`

java实例 - gps经纬度坐标转百度地图坐标

阅读更多

天朝地图坐标和gps坐标不在一个次元中.

具体原因可以参见这篇文章:  gps纠偏及大陆地图偏移原因

 

地图纠偏的主要手段有以下几种:

 

(一)利用已有的api接口

(1)百度api: 

地址:   http://api.map.baidu.com/ag/coord/convert?x=121.583140&y=31.341174&from=0&to=2&mode=1

结果:[{"error":0,"x":"MTIxLjU4NzM2NDA5NTA1","y":"MzEuMzM5MDI3NTA2NTE="}]

说明:

请求参数中x为gps经度, y为gps纬度. from to是标识类型转换的方式.具体可以去查百度的api.

返回结果中error为0表示没有错误,返回的x和y是base64算法后的结果(可以自行Google加解密base64),解密后就是:121.58736409505和31.33902750651,这个就是百度坐标。

(2)其他人已经实现好了的api

如: http://map.yanue.net/gpsApi.php?lat=22.502412986242&lng=113.93832783228 等.大家看一下就明白,不具体描述了.

 

优点: 方便, 可靠, 免费

缺点: 受限于网络速度与api查询次数

 

(二)利用数据库纠偏

原理和实现方式,参见: gps纠偏数据库及gps纠偏算法PHP

 

有点: 可靠.适合于大型项目

缺点: 需要数据库支持.免费的纠偏数据库精度低,基本不更新.高精度的库需要额外付费,成本大.

 

(三)利用代码实现小范围地区的纠偏

原理和c的实现,参见:  一种根据纠偏数据对火星坐标进行完美拟合的方法

简单说, 在一个极有限的范围内, 我们可以将gps和百度坐标之间的变化视作是一种与参考点相关的线性的变化.

参见上面的博客, 我的java代码实现如下:

package test;

public class Tester {

	// 定义4个坐标参考点 gps (百度坐标值)
	// 福州东北参考点(福州市晋安区东山村)gps 26.105833333333333, 119.36166666666666
	// (26.1087320550,119.3731015851)
	// System.out.println(degress(26, 06, 21) + ", " + degress(119, 21, 42));
	// 福州西北参考点(绿洲寨公园)gps 26.105833333333333, 119.21166666666667
	// (26.1083582702,119.2230388300)
	// System.out.println(degress(26, 06, 21) + ", " + degress(119, 12, 42));
	// 福州西南参考点(福州市闽侯县南屿镇)gps 25.974999999999998, 119.21166666666667
	// (25.9776145157,119.2230386554)
	// System.out.println(degress(25, 58, 30) + ", " + degress(119, 12, 42));
	// 福州东南参考点(城门镇)gps 25.974999999999998, 119.36166666666666
	// (25.9779880657,119.3731014562)
	// System.out.println(degress(25, 58, 30) + ", " + degress(119, 21, 42));

	static MapSubject x0y0 = new MapSubject(25.974999999999998, 119.21166666666667,
			25.9776145157, 119.2230386554);
	static MapSubject x1y0 = new MapSubject(26.105833333333333, 119.21166666666667,
			26.1083582702, 119.2230388300);
	static MapSubject x1y1 = new MapSubject(26.105833333333333, 119.36166666666666,
			26.1087320550, 119.3731015851);
	static MapSubject x0y1 = new MapSubject(25.974999999999998, 119.36166666666666,
			25.9779880657, 119.3731014562);

	/**
	 * gps经纬度转小数 
	 * @param v1      度
	 * @param v2      分
	 * @param v3      秒
	 * @return
	 */
	public static double degree(double v1, double v2, double v3) {
		return v1 / 1.0 + v2 / 60.0 + v3 / 3600.0;
	}
	
	/**
	 * 小数转经纬度
	 * @param degree
	 * @return
	 */
	public static String reverDegree(double degree){
		StringBuilder sb = new StringBuilder();
		int du = (int)(degree / 1);
		sb.append(String.valueOf(du) + "度");
		degree = degree % 1 * 60;
		int fen = (int)( degree / 1);
		sb.append(String.valueOf(fen) + "分");
		degree = degree % 1 * 60;
		double miao = degree;
		sb.append(String.valueOf(miao) + "秒");		
		return sb.toString();
	}
	
	public static MapSubject gpsToBaidu(double tGpsLat, double tGpsLng){
		return gpsToBaidu(tGpsLat, tGpsLng, "");
	}

        /**
	 * 
	 * @param tGpsLat 目标gps纬度
	 * @param tGpsLng 目标gps经度
	 * @param realBaidu 从百度api获取的坐标
	 * @return
	 */
	public static MapSubject gpsToBaidu(double tGpsLat, double tGpsLng, String realBaidu) {
		
		/*// 参考点的纠偏数据
		System.out.println(x0y0.getOffsetLat() + ", " + x0y0.getOffsetLng());
		System.out.println(x1y0.getOffsetLat() + ", " + x1y0.getOffsetLng());
		System.out.println(x1y1.getOffsetLat() + ", " + x1y1.getOffsetLng());
		System.out.println(x0y1.getOffsetLat() + ", " + x0y1.getOffsetLng());*/

		System.out.println("targetGps: " + tGpsLat + "," + tGpsLng);
		System.out.println("Real targetBaidu: " + realBaidu);

		// 计算纠偏影响系数
		double param0 = (tGpsLat - x0y0.getBdLat())	* (tGpsLng - x0y0.getBdLng());
		double param1 = (x0y1.getBdLat() - tGpsLat)	* (tGpsLng - x0y1.getBdLng());
		double param2 = (x1y1.getBdLat() - tGpsLat)	* (x1y1.getBdLng() - tGpsLng);
		double param3 = (tGpsLat - x1y0.getBdLat())	* (x1y0.getBdLng() - tGpsLng);

		double tOffsetLat = x0y0.getOffsetLat() * param0 + x0y1.getOffsetLat() * param1 
				+ x1y1.getOffsetLat() * param2 + x1y0.getOffsetLat() * param3;
		double tOffsetLng = x0y0.getOffsetLng() * param0 + x0y1.getOffsetLng() * param1 
				+ x1y1.getOffsetLng() * param2 + x1y0.getOffsetLng() * param3;

		double tBdLat = tGpsLat + tOffsetLat + 0.003; //0.003 修正值.为多次测试比较后得到的一个近似的常量值
		double tBdLng = tGpsLng + tOffsetLng + 0.011; //同上

		System.out.println("Calc targetBaidu: " + tBdLat + "," + tBdLng);
		System.out.println("---------------------------");
		
		return new MapSubject(tGpsLat, tGpsLng, tBdLat, tBdLng);

	}

	public static void main(String[] args) {
		
		gpsToBaidu(26.1100000000, 119.2700000000, "26.1131933362,119.2811939364");
		
		gpsToBaidu(26.0697361026, 119.3022537231, "26.0725808678,119.3136200409");
		
		gpsToBaidu(26.0481851155, 119.2573320865, "26.0513207295,119.2685508427");
		
		gpsToBaidu(26.0135952280, 119.2724275589, "26.0168640068,119.2836105099");
		
		gpsToBaidu(26.0163287437, 119.3032836914, "26.0192058631,119.3146067513");
		
		gpsToBaidu(26.0888307969, 119.3262434006, "26.0914428213,119.3376982627");
		
		gpsToBaidu(25.974999999999998, 119.21166666666667, "25.9776145157,119.2230386554");		
	}

	public static class MapSubject {
		double gpsLng;	//gps经度
		double gpsLat;	//gps纬度
		double bdLng;	//百度经度
		double bdLat;	//百度纬度
		double offsetLng; //经度纠偏值 = 百度经度 - gps经度
		double offsetLat; //纬度纠偏值 = 百度纬度 - gps纬度

		public MapSubject() {
		}

		public MapSubject(double gpsLat, double gpsLng, double bdLat, double bdLng) {
			this.gpsLat = gpsLat;
			this.gpsLng = gpsLng;
			this.bdLat = bdLat;
			this.bdLng = bdLng;
			this.offsetLat = bdLat - gpsLat;
			this.offsetLng = bdLng - gpsLng;
		}

		public double getGpsLng() {
			return gpsLng;
		}

		public void setGpsLng(double gpsLng) {
			this.gpsLng = gpsLng;
		}

		public double getGpsLat() {
			return gpsLat;
		}

		public void setGpsLat(double gpsLat) {
			this.gpsLat = gpsLat;
		}

		public double getBdLng() {
			return bdLng;
		}

		public void setBdLng(double bdLng) {
			this.bdLng = bdLng;
		}

		public double getBdLat() {
			return bdLat;
		}

		public void setBdLat(double bdLat) {
			this.bdLat = bdLat;
		}

		public double getOffsetLng() {
			return offsetLng;
		}

		public void setOffsetLng(double offsetLng) {
			this.offsetLng = offsetLng;
		}

		public double getOffsetLat() {
			return offsetLat;
		}

		public void setOffsetLat(double offsetLat) {
			this.offsetLat = offsetLat;
		}
	}

}

 使用http://www.gpsspg.com/maps.htm验证,使用代码计算在预设范围内的点,gps转百度坐标的结果与实际值的误差在0.0001-0.001,  对于手边的这个项目来说,已经可堪使用了. 

如果设置更多更密集的参考点,误差值将进一步减小.

 

优点: 方便.

缺点: 计算值与实际值偏差大, 不适合高精度的定位.

分享到:
评论

相关推荐

    Android定位功能开发-获取经纬度坐标的例子

    本文将深入探讨如何在Android应用中实现这一功能,并提供一个获取经纬度坐标的实例。 首先,Android提供了多种定位技术,包括GPS(全球定位系统)、网络定位(Wi-Fi和移动网络)以及传感器辅助定位等。开发者可以...

    java-业务需求需要根据经纬度计算面积,整理了一下根据经纬度计算面积,根据openlayers借鉴改写,亲测可用

    java-业务需求需要根据经纬度计算面积,整理了一下根据经纬度计算面积,根据openlayers借鉴改写,亲测可用!

    火星百度坐标转WGS84坐标小工具

    总的来说,"火星百度坐标转WGS84坐标小工具"是GIS技术在中国本土化应用的一个实例,它有效地解决了因坐标系统差异带来的问题,提高了数据处理的效率和准确性。对于需要处理中国地理数据的人来说,这是一个非常实用的...

    gps.zip_GPS_GPS java_JAVA GPS_gps经纬度

    6. **经纬度坐标**: 位置对象(Location)包含了`getLatitude()`和`getLongitude()`方法,分别返回当前的纬度和经度值,通常以十进制形式表示。 7. **精度与海拔**: `getAccuracy()`方法返回位置的精度(半径),...

    百度地图API数据库经纬度(GPS数据)在地图中显示为路径

    总结起来,将数据库中的GPS经纬度数据在百度地图上以路径形式展示,涉及数据处理、地图API的使用以及Web开发技巧。通过以上步骤,你可以创建一个直观的可视化工具,帮助分析和理解地理轨迹数据。记得在实际操作中...

    GPS经纬度转换

    1. **GPS经纬度基础**: GPS使用经度、纬度和海拔高度来定位地球上任何一点。经度是沿地球的赤道线测量的,范围从0°到180°E和180°W,而纬度是从赤道开始,向北到90°N(北极)和向南到90°S(南极)。每个度被...

    根据IP或经纬度查询城市-离线版.zip

    而经纬度定位则是基于GPS或其他卫星定位系统,直接获取设备的精确地理坐标,然后通过逆地理编码找到对应的行政区域信息。 在这个压缩包中,关键文件“address_api”可能是一个Java API库,用于处理这两种定位方式。...

    j2me-gps.rar_JAVA GPS_gps j2me_gps 平台_j2me g_j2me gps

    - 开发者首先需要实例化LocationProvider类,选择合适的定位提供者,例如基于网络的位置信息(CellID)或者卫星信号(GPS)。 - 然后注册PositionListener,监听位置更新事件,当设备位置发生变化时,会触发回调...

    android 百度地图api 经纬度

    本文将详细讲解如何利用百度地图API在Android应用中获取经纬度坐标,以及解决GPS定位为null的问题。 首先,我们需要在项目中集成百度地图SDK。在AndroidManifest.xml文件中添加必要的权限,比如访问网络、读写外部...

    GPS轨迹纠偏算法,java代码,包含异常点检测、滤波平滑,

    3. **LocationConvert.java**:此文件可能包含将原始GPS坐标转换为其他坐标系(如WGS84、GCJ-02、BD-09等)的函数。在中国,由于地理信息安全考虑,通常需要进行坐标加密,因此转换代码是必要的。 4. **轨迹纠偏...

    J2ME-GPS定位JAVA源码

    **J2ME-GPS定位JAVA源码** J2ME(Java Micro Edition)是Java平台的一个子集,主要用于移动设备和嵌入式系统。在移动领域,J2ME为开发手机应用提供了广泛的框架,包括游戏、应用程序和服务。GPS(全球定位系统)...

    Android获取当前地理位置经纬度坐标

    在Android应用开发中,获取设备的当前地理位置经纬度坐标是一项常见的功能,这通常涉及到位置服务、GPS、网络定位等技术。下面将详细讲解如何在Android Studio项目中实现这一功能。 首先,我们需要添加必要的权限到...

    iphone通过gps获取经纬度的

    本示例将深入探讨如何通过GPS获取iPhone的经纬度坐标,以及相关的知识点。 首先,我们需要导入Core Location框架,它是苹果提供的用于地理位置服务的核心框架。在Swift中,我们可以在代码顶部添加以下代码来引入: ...

    Android百度手机地图-实例集合.zip

    4. **地理编码与反地理编码**:地理编码是将地址转换为经纬度坐标的过程,反地理编码则是将经纬度坐标转换为地址,这对于搜索地点或根据坐标显示地址信息非常有用。 5. **覆盖物服务**:百度地图API支持动态加载和...

    GPS百度和谷歌坐标互转示例和代码(新)

    本文将深入探讨“GPS百度和谷歌坐标互转”的技术实现,基于给定的Java代码示例,为开发者提供详细的转换方法和步骤。 首先,我们需要了解两种坐标系的基础知识。百度地图使用的是自定义的“bd09ll”坐标系,而谷歌...

    android GPS获取经纬度

    在Android平台上,获取GPS经纬度是一项基础且重要的功能,它涉及到地理位置服务,广泛应用于地图导航、定位服务、社交应用等领域。下面将详细讲解如何在Android中实现这一功能,以及涉及的相关知识点。 首先,我们...

    J2ME获取GPS经纬度

    它允许开发者获取设备的经纬度坐标、速度、方向等地理信息。JSR179的引入极大地简化了开发过程,使得开发者无需关心底层硬件的具体实现,只需通过API调用来获取数据。 要获取GPS经纬度,首先在J2ME项目中,我们需要...

    android gps定位获取经纬度

    本篇将详细介绍如何在Android中获取经纬度坐标。 一、Android权限设置 在AndroidManifest.xml文件中,必须声明使用GPS的权限,这是获取位置信息的前提。添加以下代码: ```xml <uses-permission android:name=...

    GPS坐标转换集合

    本压缩包文件"GPS坐标转换集合"包含了一系列用于经纬度到大地坐标的转换工具和资源,适用于不同的编程语言和应用场景。 首先,我们有"大地坐标转经纬度.cs",这是一个C#代码文件。C#是微软开发的面向对象的编程语言...

    JavaME开发实例

    开发者需要理解经纬度坐标系统,以及如何加载和解析地图数据,如瓦片地图或者离线地图包。可能还会用到地理编码(Geocoding)将地址转化为坐标,以及反向地理编码(Reverse Geocoding)将坐标转化为地址。 4. **GPS...

Global site tag (gtag.js) - Google Analytics