各坐标系简介与转换,包括WGS84(地球坐标系)、GCJ02(火星坐标系)和BD09(百度坐标系)

一、各坐标系简介与转换

背景:从GPS和北斗卫星定位得到的定位数据采用的都是WGS84坐标系,即地球坐标系,但是国内不管是高德地图、百度地图采用的并不是WGS84坐标系,所以需要经过转换后才能使用,前端用百度API提供的方法转换速度较慢。通过网上搜索收集资料,然后自己编写代码测试,总结了一下有关坐标系简介与转换的知识,分享给大家!

1.各坐标系简介

  • WGS84坐标系 即地球坐标系,国际上通用的坐标系。 设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系。谷歌地图采用的是WGS84地理坐标系(中国范围除外,谷歌中国地图采用的是GCJ02地理坐标系。)

  • GCJ02坐标系 即火星坐标系,WGS84坐标系经加密后的坐标系。 出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标。

  • BD09坐标系 即百度坐标系,GCJ02坐标系经加密后的坐标系。搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。

  • 各主流地图API采用的坐标系 高德MapABC地图API 火星坐标 腾讯搜搜地图API 火星坐标 阿里云地图API 火星坐标 灵图51ditu地图API 火星坐标

    百度地图API 百度坐标 搜狐搜狗地图API 搜狗坐标 图吧MapBar地图API 图吧坐标

  • 这里介绍几个常用的在线坐标工具 高德开放平台 百度拾取坐标系统 在线坐标转换工具

2.各坐标系转换JAVA代码实现

2.1坐标点实体类

package com.cennavi.audi_data_collect.bean;import java.io.Serializable;/*** Description: 坐标点* * @author JourWon* @date Created on 2018年6月19日*/
public class Point implements Serializable {private static final long serialVersionUID = 3584864663880053897L;/*** 经度*/private double lng;/*** 纬度*/private double lat;public Point(double lng, double lat ) {  setLat(lat);  setLng(lng);  }  public double getLng() {return lng;}public void setLng(double lng) {this.lng = lng;}public double getLat() {return lat;}public void setLat(double lat) {this.lat = lat;}public static long getSerialversionuid() {return serialVersionUID;}
}

2.2各坐标系转换工具类

package com.jourwon.util;import com.jourwon.pojo.Point;/*** Description: 各坐标系之间的转换工具类* * @author JourWon* @date Created on 2018年6月19日*/
public class CoordinateTransformUtils {// 圆周率πprivate static final double PI = 3.1415926535897932384626D;// 火星坐标系与百度坐标系转换的中间量private static final double X_PI = 3.14159265358979324 * 3000.0 / 180.0D;// Krasovsky 1940// 长半轴a = 6378245.0, 1/f = 298.3// b = a * (1 - f)// 扁率ee = (a^2 - b^2) / a^2;// 长半轴private static final double SEMI_MAJOR = 6378245.0D;// 扁率private static final double FLATTENING = 0.00669342162296594323D;// WGS84=>GCJ02 地球坐标系=>火星坐标系public static Point wgs84ToGcj02(double lng, double lat) {if (outOfChina(lng, lat)) {return new Point(lng, lat);}double[] offset = offset(lng, lat);double mglng = lng + offset[0];double mglat = lat + offset[1];return new Point(mglng, mglat);}// GCJ02=>WGS84 火星坐标系=>地球坐标系(粗略)public static Point gcj02ToWgs84(double lng, double lat) {if (outOfChina(lng, lat)) {return new Point(lng, lat);}double[] offset = offset(lng, lat);double mglng = lng - offset[0];double mglat = lat - offset[1];return new Point(mglng, mglat);}// GCJ02=>WGS84 火星坐标系=>地球坐标系(精确)public static Point gcj02ToWgs84Exactly(double lng, double lat) {if (outOfChina(lng, lat)) {return new Point(lng, lat);}double initDelta = 0.01;double threshold = 0.000000001;double dLat = initDelta, dLon = initDelta;double mLat = lat - dLat, mLon = lng - dLon;double pLat = lat + dLat, pLon = lng + dLon;double wgsLat, wgsLng, i = 0;while (true) {wgsLat = (mLat + pLat) / 2;wgsLng = (mLon + pLon) / 2;Point point = wgs84ToGcj02(wgsLng, wgsLat);dLon = point.getLng() - lng;dLat = point.getLat() - lat;if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))break;if (dLat > 0)pLat = wgsLat;elsemLat = wgsLat;if (dLon > 0)pLon = wgsLng;elsemLon = wgsLng;if (++i > 10000)break;}return new Point(wgsLng, wgsLat);}// GCJ-02=>BD09 火星坐标系=>百度坐标系public static Point gcj02ToBd09(double lng, double lat) {double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * X_PI);double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * X_PI);double bd_lng = z * Math.cos(theta) + 0.0065;double bd_lat = z * Math.sin(theta) + 0.006;return new Point(bd_lng, bd_lat);}// BD09=>GCJ-02 百度坐标系=>火星坐标系public static Point bd09ToGcj02(double lng, double lat) {double x = lng - 0.0065;double y = lat - 0.006;double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);double gcj_lng = z * Math.cos(theta);double gcj_lat = z * Math.sin(theta);return new Point(gcj_lng, gcj_lat);}// WGS84=>BD09 地球坐标系=>百度坐标系public static Point wgs84ToBd09(double lng, double lat) {Point point = wgs84ToGcj02(lng, lat);return gcj02ToBd09(point.getLng(), point.getLat());}// BD09=>WGS84 百度坐标系=>地球坐标系public static Point bd09ToWgs84(double lng, double lat) {Point point = bd09ToGcj02(lng, lat);return gcj02ToWgs84(point.getLng(), point.getLat());}/*** Description: 中国境外返回true,境内返回false* @param lng    经度* @param lat 纬度* @return*/public static boolean outOfChina(double lng, double lat) {if (lng < 72.004 || lng > 137.8347)return true;if (lat < 0.8293 || lat > 55.8271)return true;return false;}// 经度偏移量private static double transformLng(double lng, double lat) {double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;return ret;}// 纬度偏移量private static double transformLat(double lng, double lat) {double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat+ 0.2 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;return ret;}// 偏移量public static double[] offset(double lng, double lat) {double[] lngLat = new double[2];double dlng = transformLng(lng - 105.0, lat - 35.0);double dlat = transformLat(lng - 105.0, lat - 35.0);double radlat = lat / 180.0 * PI;double magic = Math.sin(radlat);magic = 1 - FLATTENING * magic * magic;double sqrtmagic = Math.sqrt(magic);dlng = (dlng * 180.0) / (SEMI_MAJOR / sqrtmagic * Math.cos(radlat) * PI);dlat = (dlat * 180.0) / ((SEMI_MAJOR * (1 - FLATTENING)) / (magic * sqrtmagic) * PI);lngLat[0] = dlng;lngLat[1] = dlat;return lngLat;}}

3.测试

/*** Description: 坐标系转换工具测试类* * @author JourWon* @date Created on 2018年6月19日*/
public class CoordinateTransformUtilsTest {/*** Description: 地球坐标系 =>火星坐标系、百度坐标系*/@Testpublic void test01() {// 广州市中大地铁站Point point = new Point(113.28749670783887D, 23.094783676708065D);System.out.println("地球坐标系 : " + point);Point wgs84ToGcj02 = CoordinateTransformUtils.wgs84ToGcj02(point.getLng(), point.getLat());System.out.println("火星坐标系 : " + wgs84ToGcj02);Point wgs84ToBd09 = CoordinateTransformUtils.wgs84ToBd09(point.getLng(), point.getLat());System.out.println("百度坐标系 : " + wgs84ToBd09);}/*** Description: 火星坐标系=>地球坐标系、百度坐标系*/@Testpublic void test02() {// 广州市珠江新城地铁站Point point = new Point(113.321171D, 23.119285D);System.out.println("火星坐标系 : " + point);Point wgs84ToGcj02 = CoordinateTransformUtils.gcj02ToWgs84(point.getLng(), point.getLat());System.out.println("地球坐标系 : " + wgs84ToGcj02);Point wgs84ToBd09 = CoordinateTransformUtils.gcj02ToBd09(point.getLng(), point.getLat());System.out.println("百度坐标系 : " + wgs84ToBd09);}/*** Description: 百度坐标系=>地球坐标系、火星坐标系*/@Testpublic void test03() {// 广州市体育西路地铁站Point point = new Point(113.328035D, 23.136929D);System.out.println("百度坐标系 : " + point);Point wgs84ToGcj02 = CoordinateTransformUtils.bd09ToWgs84(point.getLng(), point.getLat());System.out.println("地球坐标系 : " + wgs84ToGcj02);Point wgs84ToBd09 = CoordinateTransformUtils.bd09ToGcj02(point.getLng(), point.getLat());System.out.println("火星坐标系 : " + wgs84ToBd09);}}

二、坐标转换精度测试说明

1.互转精度值

1、09坐标转84坐标,转换后的84坐标再转回09坐标,前后两个09坐标精度相差不到1米


2、取02坐标点,转为84坐标,转换后的84坐标再转回02坐标,前后两个02坐标精度相差1米左右

2.单向转换精度:

1、02转84精度:取某路口02坐标点,转换为84坐标点,比较84地图上某路口的位置和转换的84坐标点位置,两点相差不到1米

2、09转84精度:取84坐标点,转换为09坐标,然后09坐标转换为84坐标,两个84坐标相差1.6米左右

WGS84、GCJ02、BD09坐标系互转相关推荐

  1. 【Java代码】坐标系说明+WGS84\GCJ02\BD09坐标系转换工具+Java坐标系转换及验证源代码分享(粘贴可用)

    1. 坐标系说明 开发地图应用服务时,一定会接触到各种坐标系,而保证坐标系的正确与合理是一切数据分析的前提,总的来说,坐标系可以分为两大类:地理坐标系GCS(Geographic Coordinate ...

  2. Python3 Wgs84\gcj02\bd09\mercator\bd09mc坐标系转换与投影

    最基础的一组经纬度坐标转换,在网上找到过JavaScript和java版本的,但是没有找到python版本的,把JavaScript版本的改成了python版本的,能凑合用. "" ...

  3. wgs-84,gcj-02,bd-09的相互转换,高德,世界测量,百度坐标系的相互转换,坐标系转换

    高德使用的是gcj-02坐标系,百度使用的是bd09坐标系,注意其间的相互转换 1.首先创建一个GPS对象类 public class Gps {private double wgLat;privat ...

  4. 各坐标系转换,百度、高德、wgs84、cgcs2000坐标系互转

    首先申明:转换方法都是网上找的,但是都不全,整理了一下 其中wgs84.cgcs2000互转结果有差异,也就是完全还原不了 先附上百度.高德.wgs84互转方法 js /*** Created by ...

  5. 批量将postgis进行WGS84与bd-09,gcj-02坐标系转换

    WGS84与bd-09,gcj-02坐标系,百度经纬度与百度墨卡托之间互转 FreeGIS_Coordinate_Transform( in schema_name text, in table_na ...

  6. STM32开发 -- 地球坐标系(WGS84),火星坐标系(GCJ02), 百度坐标系(BD09)坐标转换

    如需转载请注明出处:https://juyou.blog.csdn.net/article/details/99599071 STM32开发 – GPS模块开发详解 最后有提到一下: WGS84坐标系 ...

  7. WGS84地球坐标系,GCJ02火星坐标系,BD09百度坐标系简介与转换,mybatis字段映射原理

    1.各坐标系简介 2.各坐标系转换 2.1坐标点实体类 2.2各坐标系转换工具类 3.测试 1.各坐标系简介 WGS84坐标系 即地球坐标系,国际上通用的坐标系. 设备一般包含GPS芯片或者北斗芯片获 ...

  8. GCJ-02火星坐标系、BD-09百度坐标系和WGS-84坐标系转换

    WGS-84:GPS坐标系 GCJ-02:火星坐标系,国测局02年发布的坐标体系,高德,腾讯等使用. BD-09:百度坐标系 GCJ-02火星坐标系和WGS-84坐标系转换关系 var pi = 3. ...

  9. GPS坐标系(WGS84)、火星坐标系(GCJ02)、百度坐标系(BD-09)的相互转换

    WGS-84:  GPS坐标系,国际标准,GPS模块使用. GCJ-02:   火星坐标系,国测局坐标系,谷歌.高德.腾讯等使用. BD-09:     百度坐标系,百度地图使用. GCJ-02 转W ...

最新文章

  1. 高精地图:为自动驾驶汽车提供动力的新时代地图
  2. overlapped I/O的学习笔记
  3. 图像检索:layer选择与fine-tuning性能提升验证
  4. Latex快速入门系列 -- 在TexStudio中正确插入参考文献的基本操作
  5. linux网路编程之TCP状态转换及端口复用
  6. ES6之Module的语法(1)
  7. 噪声控制简史,以及几个简单的声学概念
  8. Android实现点击两次返回键退出
  9. [转]解决微信及360浏览器无法读取本地图片问题
  10. QNX Hardware connection
  11. 从文本界面安装RHEL5操作系统详解
  12. #9 shell脚本的函数运用
  13. 计算机二级c语言考点变化,计算机二级C语言考点归纳汇总.doc
  14. 基于android的订餐系统 答辩ppt,外卖订餐系统答辩PPT
  15. 利用python解决简单数独
  16. 集成学习——BAGGING和随机森林
  17. Linux文本处理工具实践
  18. MATLAB多项式计算
  19. 基于FPGAd的FIR数字滤波器的设计和实现——刘朋全(西北工业大学)
  20. 交通流优化的一种强化学习方法

热门文章

  1. linux 命令神器,Linux 命令神器 - glances
  2. 0.96寸oled显示坏苹果(badapple)
  3. C++【求水仙花数】输出所有的水仙花数。所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如:153是一个水仙花数,因为153=1^3+5^3+3^3。
  4. Spring家族主流成员介绍与比较
  5. aarch64 poky linux,python - aarch64-poky-linux-gcc:错误::没有这样的文件或目录 - 堆栈内存溢出...
  6. 数据库-SQL Server
  7. axios实战学习——调用城市天气api接口数据实现天气查询案例
  8. 树莓派实现远程控制空调
  9. 求小蚁摄像头YHS-113 CMIIT刷机包?7-26
  10. 全球及中国空气电磁阀行业营运模式及销售渠道分析报告2021~2026年