原理解析吧,参照网上的一个回答http://q.cnblogs.com/q/41339/
众所周知地球是一个不规则椭圆体,GIS中的坐标系定义由基准面和地图投影两组参数确定,而基准面的定义则由特定椭球体及其对应的转换参数确定。 基准面是利用特定椭球体对特定地区地球表面的逼近,因此每个国家或地区均有各自的基准面。基准面是在椭球体基础上建立的,椭球体可以对应多个基准面,而基准面只能对应一个椭球体。
意思就是无论是谷歌地图、搜搜地图还是高德地图、百度地图区别只是针对不同的大地地理坐标系标准制作的经纬度,不存在准不准的问题,大家都是准的只是参照物或者说是标准不一样。
谷歌地图采用的是WGS84地理坐标系(中国范围除外),谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系,百度采用的是BD09坐标系,而设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,为什么不统一用WGS84地理坐标系这就是国家地理测绘总局对于出版地图的要求,出版地图必须符合GCJ02坐标系标准了,也就是国家规定不能直接使用WGS84地理坐标系。所以定位大家感觉不准确很多又叫出版地图为火星地图其实只是坐标系不一样而已。
这就是为什么设备采集的经纬度在地图上显示的时候经常有很大的偏差,远远超出民用GPS 10米偏移量的技术规范,于是我们就有了谷歌地图纠偏 腾讯搜搜纠偏 混合地图纠偏 百度谷歌互转存在的价值。
那如何对谷歌地图纠偏、搜搜soso地图纠偏或者对百度地图纠偏呢,如果用算法目前没有太好的算法直接转换,所以大家采用的都是比对的方法吧地球划分成若干个小块找到地图的偏差量记录下来,然后根据任意经纬度找寻最接近的偏差量加上偏差量就可以实现不同地图之间的经纬度转换。现在有0.01度纠偏经纬度信息,可以提供任意格式,可以直接把经纬度偏移量调整回来。
百度地图纠偏信息包含中国海域一共29,699,997条纠偏数据,谷歌地图只包含中国陆地一共12,597,551条纠偏数据。
下面又是我在网上找到别人写的两个纠偏的算法。
第一个:
package correctPosition; public class MapPoint { private double latitude; private double longitude; private double x; private double y; public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } }
package correctPosition; /** * 经纬度纠偏工具类 * [一句话功能简述]<p> * [功能详细描述]<p> * @author PeiYu * @version 1.0, 2012-8-24 * @see * @since gframe-v100 */ public class MapFix { private double casm_f = 0.0; private double casm_rr = 0.0; private double casm_t1 = 0.0; private double casm_t2 = 0.0; private double casm_x1 = 0.0; private double casm_x2 = 0.0; private double casm_y1 = 0.0; private double casm_y2 = 0.0; private MapFix() { casm_rr = 0.0; casm_t1 = 0.0; casm_t2 = 0.0; casm_x1 = 0.0; casm_y1 = 0.0; casm_x2 = 0.0; casm_y2 = 0.0; casm_f = 0.0; } private static MapFix instance; public static MapFix getInstance() { if (instance == null) { instance = new MapFix(); } return instance; } /** * 纠偏 * @param x 经度 * @param y 纬度 * @return [0]纠偏后经度 [1]纠偏后纬度 */ public double[] fix(double x , double y) { double[] res = new double[2]; try { double num = x * 3686400.0; double num2 = y * 3686400.0; double num3 = 0.0; double num4 = 0.0; double num5 = 0.0; MapPoint point = wgtochina_lb(1, (int) num, (int) num2, (int) num5, (int) num3, (int) num4); double num6 = point.getX(); double num7 = point.getY(); num6 /= 3686400.0; num7 /= 3686400.0; res[0] = num6; res[1] = num7; } catch (Exception ex) { System.out.println(ex); } return res; } private void IniCasm(double w_time , double w_lng , double w_lat) { casm_t1 = w_time; casm_t2 = w_time; double num = (int) (w_time / 0.357); casm_rr = w_time - (num * 0.357); if (w_time == 0.0) { casm_rr = 0.3; } casm_x1 = w_lng; casm_y1 = w_lat; casm_x2 = w_lng; casm_y2 = w_lat; casm_f = 3.0; } private double random_yj() { double num = 314159269.0; double num2 = 453806245.0; casm_rr = (num * casm_rr) + num2; double num3 = (int) (casm_rr / 2.0); casm_rr -= num3 * 2.0; casm_rr /= 2.0; return casm_rr; } private double Transform_jy5(double x , double xx) { double num = 6378245.0; double num2 = 0.00669342; double num3 = Math.sqrt(1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433))); return ((xx * 180.0) / (((num / num3) * Math.cos(x * 0.0174532925199433)) * 3.1415926)); } private double Transform_jyj5(double x , double yy) { double num = 6378245.0; double num2 = 0.00669342; double d = 1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433)); double num4 = (num * (1.0 - num2)) / (d * Math.sqrt(d)); return ((yy * 180.0) / (num4 * 3.1415926)); } private double Transform_yj5(double x , double y) { double num = ((((300.0 + (1.0 * x)) + (2.0 * y)) + ((0.1 * x) * x)) + ((0.1 * x) * y)) + (0.1 * Math.sqrt(Math.sqrt(x * x))); num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588 * x))) * 0.6667; num += ((20.0 * yj_sin2(3.141592653589794 * x)) + (40.0 * yj_sin2(1.0471975511965981 * x))) * 0.6667; return (num + (((150.0 * yj_sin2(0.26179938779914952 * x)) + (300.0 * yj_sin2(0.10471975511965979 * x))) * 0.6667)); } private double Transform_yjy5(double x , double y) { double num = ((((-100.0 + (2.0 * x)) + (3.0 * y)) + ((0.2 * y) * y)) + ((0.1 * x) * y)) + (0.2 * Math.sqrt(Math.sqrt(x * x))); num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588 * x))) * 0.6667; num += ((20.0 * yj_sin2(3.141592653589794 * y)) + (40.0 * yj_sin2(1.0471975511965981 * y))) * 0.6667; return (num + (((160.0 * yj_sin2(0.26179938779914952 * y)) + (320.0 * yj_sin2(0.10471975511965979 * y))) * 0.6667)); } private MapPoint wgtochina_lb(int wg_flag , int wg_lng , int wg_lat , int wg_heit , int wg_week , int wg_time) { MapPoint point = null; if (wg_heit <= 0x1388) { double num = wg_lng; num /= 3686400.0; double x = wg_lat; x /= 3686400.0; if (num < 72.004) { return point; } if (num > 137.8347) { return point; } if (x < 0.8293) { return point; } if (x > 55.8271) { return point; } if (wg_flag == 0) { IniCasm((double) wg_time, (double) wg_lng, (double) wg_lat); point = new MapPoint(); point.setLatitude((double) wg_lng); point.setLongitude((double) wg_lat); return point; } casm_t2 = wg_time; double num3 = (casm_t2 - casm_t1) / 1000.0; if (num3 <= 0.0) { casm_t1 = casm_t2; casm_f++; casm_x1 = casm_x2; casm_f++; casm_y1 = casm_y2; casm_f++; } else if (num3 > 120.0) { if (casm_f == 3.0) { casm_f = 0.0; casm_x2 = wg_lng; casm_y2 = wg_lat; double num4 = casm_x2 - casm_x1; double num5 = casm_y2 - casm_y1; double num6 = Math.sqrt((num4 * num4) + (num5 * num5)) / num3; if (num6 > 3185.0) { return point; } } casm_t1 = casm_t2; casm_f++; casm_x1 = casm_x2; casm_f++; casm_y1 = casm_y2; casm_f++; } double xx = Transform_yj5(num - 105.0, x - 35.0); double yy = Transform_yjy5(num - 105.0, x - 35.0); double num9 = wg_heit; xx = ((xx + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj(); yy = ((yy + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj(); point = new MapPoint(); point.setX((num + Transform_jy5(x, xx)) * 3686400.0); point.setY((x + Transform_jyj5(x, yy)) * 3686400.0); } return point; } private double yj_sin2(double x) { double num = 0.0; if (x < 0.0) { x = -x; num = 1.0; } int num2 = (int) (x / 6.28318530717959); double num3 = x - (num2 * 6.28318530717959); if (num3 > 3.1415926535897931) { num3 -= 3.1415926535897931; if (num == 1.0) { num = 0.0; } else if (num == 0.0) { num = 1.0; } } x = num3; double num4 = x; double num5 = x; num3 *= num3; num5 *= num3; num4 -= num5 * 0.166666666666667; num5 *= num3; num4 += num5 * 0.00833333333333333; num5 *= num3; num4 -= num5 * 0.000198412698412698; num5 *= num3; num4 += num5 * 2.75573192239859E-06; num5 *= num3; num4 -= num5 * 2.50521083854417E-08; if (num == 1.0) { num4 = -num4; } return num4; } }
package correctPosition; public class Test { /** * @param args */ public static void main(String[] args) { // 纠偏前的经度 //double lon = 103.9804764; // 纠偏前的纬度 // double lat = 30.605864; double lon = 103.98707398732; double lat = 30.611553862277; double point[] = MapFix.getInstance().fix(lon, lat); // 纠偏后的经度 double correctLon = point[0]; // 纠偏后的纬度 double correctLat = point[1]; System.out.println("纠偏前经度:" + lon + ",纬度:" + lat); System.out.println("纠偏后经度:" + correctLon + ",纬度:" + correctLat); } }
第二个:
package cn.bdx.util; import java.util.HashMap; import java.util.Map; /** * gps纠偏算法,适用于google,高德体系的地图 * * @author Administrator */ public class GpsCorrect { final static double pi = 3.14159265358979324; final static double a = 6378245.0; final static double ee = 0.00669342162296594323; public static void main(String[] args) { System.out.println(transform(103.98707398732,30.611553862277)); } public static Map<String,Double> transform(double wgLat, double wgLon) { // if (outOfChina(wgLat, wgLon)) { // latlng[0] = wgLat; // latlng[1] = wgLon; // return null; // } double dLat = transformLat(wgLon - 105.0, wgLat - 35.0); double dLon = transformLon(wgLon - 105.0, wgLat - 35.0); double radLat = wgLat / 180.0 * pi; double magic = Math.sin(radLat); magic = 1 - ee * magic * magic; double sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); // lat = wgLat + dLat; // lng = wgLon + dLon; Map<String,Double> lnglatList = new HashMap<String,Double>(); lnglatList.put("lng", wgLon+dLon); lnglatList.put("lat", wgLat + dLat); //LatLng CHENGDU = new LatLng(wgLat + dLat, wgLon + dLon); return lnglatList; } /* private static boolean outOfChina(double lat, double lon) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; } */ private static double transformLat(double x, double y) { double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; return ret; } private static double transformLon(double x, double y) { double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0; return ret; } }
这两种算法在高德地图与百度地图上面都进行了测试,测试结果第一种算法的定位精度要比第二种算法要精确一点。
相关推荐
在IT行业中,尤其是在地理信息系统(GIS)和导航领域,GPS纠偏是一项至关重要的技术。本文将深入探讨“百度地图GPS纠偏数据库”及其在解决地图偏移和经纬度偏移问题上的作用。 首先,我们需要理解GPS(全球定位系统...
在IT行业中,GPS纠偏是一项重要的技术,尤其在地理信息系统(GIS)和导航应用中扮演着关键角色。本文将深入探讨“百度地图GPS纠偏数据库”及其相关知识点。 首先,我们要理解什么是GPS纠偏。GPS(全球定位系统)在...
在IT行业中,GPS纠偏是一项关键技术,特别是在地理信息系统(GIS)和导航系统中。百度地图作为中国领先的在线地图服务提供商,提供了丰富的API和工具供开发者使用,其中包括GPS纠偏数据库的免费开发包。这个开发包...
### GPS纠偏算法详解 GPS纠偏算法是用于纠正GPS定位数据偏差的一种技术,主要针对的是在中国区域内的地图服务,如Google地图、高德地图等。由于地理坐标系统的差异以及政策原因,中国的地图数据需要进行一定的偏移...
在本主题中,我们将深入探讨“google地图GPS纠偏数据”以及如何解决GPS纠偏问题。 GPS(全球定位系统)依赖于一组分布在地球轨道上的卫星来确定设备的位置。然而,由于多种因素,如信号反射、多路径效应、大气折射...
在IT行业中,GPS纠偏是一项重要的技术,尤其在地理信息系统(GIS)和导航应用中扮演着关键角色。本文将深入探讨“百度地图的纠偏技术”以及如何解决GPS纠偏问题,这对于理解百度地图的精准定位功能至关重要。 首先...
GPS纠偏是为了提高定位精度,确保地理位置信息的准确性和可靠性。下面我们将详细讨论标题和描述中提及的知识点。 1. **数据库纠偏**: 数据库纠偏是指通过数据库中的预设信息来修正由GPS或其他定位系统获取的坐标...
googlemap谷歌地图gps纠偏数据库免费下载 纠偏数据库(google地图) 精度为0.01:经纬度每变化0.01,取一次偏移值,共980万条,access文件约600mb,误差5~10米。 精度为0.001:经纬度每变化0.001,取一次偏移值,共9...
纠偏数据库 精度为0.01:经纬度每变化0.01,取一次偏移值,共980万条,access文件约600mb,误差5~10米。 精度为0.001:经纬度每变化0.001,取一次偏移值,共9亿条,csv文件共20gb,误差约2米。 经纬度中文地址解析...
本主题聚焦于“最新全国百度、高德、谷歌等各类地图经纬度偏移,经纬度纠偏,GPS偏移,GPS纠偏数据库”,这些概念涉及到地图数据处理的核心技术,对确保精确地理位置信息至关重要。 首先,我们要理解经纬度偏移的...
这是一个access类型的gps纠偏数据库,共有9万多条记录,大小5M,我导入到sqlite3数据库,大小4M多。适用于要求精度不是太高的google map应用。所有经过纠偏的gps点,基本上能够显示到道路上。如果需要sqlite的可以...
google baidu 980万条纠偏记录,精度为:0.01,每条记录8个字节
在全球定位系统的应用过程中,GPS纠偏工具扮演着至关重要的角色。尤其是在中国,由于国家安全和地理信息规范的原因,国内使用了不同于全球标准的GCJ-02(即“火星坐标”)和百度的BD-09坐标系统,这些特定的坐标体系...
国际标准gps转中国标准gps源码实例,简单易用
GoogleMap 谷歌地图 GPS纠偏数据下载器 0.1精度 所谓0.1精度,就是每隔0.1度提供一个修正值,详情请参见我的博客: http://blog.csdn.net/hushoubo/article/details/7708804
对GSP经纬度数据进行纠偏计算,过滤掉偏移无效的数据。画出规整的轨迹。
谷歌地图专用纠偏数据库 精度为0.01:经纬度每变化0.01,取一次偏移值,共980万条,access文件约600mb,误差5~10米。 精度为0.001:经纬度每变化0.001,取一次偏移值,共9亿条,csv文件共20gb,误差约2米 百度...
在国家保密插件和纠偏数据库的基础上,我们还可以提供更多的解决方案,例如 GPS偏移算法、经纬度转换算法等。这些解决方案可以满足不同的应用需求,帮助开发者更好地解决GPS开发和互联网项目开发中的经纬度偏移问题...
本资源——“baidu地图全国gps经纬度纠偏数据库”正是这样一个工具,它包含了全国范围内的纠偏数据,可供用户免费下载使用。 首先,我们要了解什么是GPS偏移。GPS偏移主要由三部分构成:卫星钟误差、接收机钟误差和...
百度地图作为中国市场的主要地图服务提供商之一,其纠偏数据(GPS专用)的研发便是在这一背景下诞生。 百度地图纠偏数据项目的目的,是通过一系列的算法和技术手段对GPS信号进行校正。由于原始GPS信号存在偏差,...