常见GIS坐标系的坐标转换

常见GIS坐标系的坐标转换本文详细介绍了 GIS 中的三种常见坐标系 WGS 84 GCJ 02 和 BD 09 以及在 Java 和 Python 编程语言中实现的坐标数据转换算法 包括 WGS 84 到国测局坐标系 GCJ 02 GCJ 02 到百度坐标系 BD 09 等转换方法

几种常见的 GIS 坐标系的简单介绍及坐标数据的相互转换方法。


一、坐标系介绍

1. WGS-84:大地坐标系

  • 国际通用坐标系,也叫地球坐标系。
  • 各 GPS 设备、境外地图(包括但不限于谷歌地图、高德地图、百度地图的境外版)等使用的坐标系。

2. GCJ-02:国测局坐标系

  • 国内通用坐标系,也叫火星坐标系。
  • 各境内地图(高德地图、腾讯地图等)等使用的坐标系。

3. BD-09:百度坐标系

  • GCJ-02 基础上的二次加密。
  • 百度标准,百度 SDK,百度地图,百度 GeoCoding 等使用的坐标系。

二、坐标数据转换方法-Java 版

1. 准备工作

1.1 定义依赖的一些常量和转换方法

 private static final double PI = Math.PI; private static final double X_PI = PI * 3000.0 / 180.0; private static final double AA = .0; private static final double EE = 0.00; / * 经纬度偏移转换-经度 * * @param lng * @param lat * @return */ 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; } / * 经纬度偏移转换-维度 * * @param lng * @param lat * @return */ 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; } / * 判断坐标是否超出境内 * * @param lng * @param lat * @return */ private static boolean outOfChina(double lng, double lat) { 
    // 纬度3.86~53.55,经度73.66~135.05;非精确判断,可能误判 return !(73.66 < lng && lng < 135.05 && 3.86 < lat && lat < 53.55); } 

2. WGS-84 和 GCJ-02 的相互转换

2.1 WGS-84 转 GCJ-02

 / * WGS-84转GCJ-02 * * @param lng * @param lat * @return */ public static double[] wgs84ToGcj02(double lng, double lat) { 
    if (outOfChina(lng, lat)) { 
    return new double[]{ 
   lng, lat}; } else { 
    double dlat = transformLat(lng - 105.0, lat - 35.0); double dlng = transformLng(lng - 105.0, lat - 35.0); double radlat = lat / 180.0 * PI; double magic = Math.sin(radlat); magic = 1 - EE * magic * magic; double sqrtMagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((AA * (1 - EE)) / (magic * sqrtMagic) * PI); dlng = (dlng * 180.0) / (AA / sqrtMagic * Math.cos(radlat) * PI); double mglat = lat + dlat; double mglng = lng + dlng; return new double[]{ 
   mglng, mglat}; } } 

2.2 GCJ-02 转 WGS-84

 / * GCJ-02转WGS-84 * * @param lng * @param lat * @return */ public static double[] gcj02ToWgs84(double lng, double lat) { 
    if (outOfChina(lng, lat)) { 
    return new double[]{ 
   lng, lat}; } else { 
    double dlat = transformLat(lng - 105.0, lat - 35.0); double dlng = transformLng(lng - 105.0, lat - 35.0); double radlat = lat / 180.0 * PI; double magic = Math.sin(radlat); magic = 1 - EE * magic * magic; double sqrtMagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((AA * (1 - EE)) / (magic * sqrtMagic) * PI); dlng = (dlng * 180.0) / (AA / sqrtMagic * Math.cos(radlat) * PI); double mglat = lat + dlat; double mglng = lng + dlng; return new double[]{ 
   lng * 2 - mglng, lat * 2 - mglat}; } } 

3. GCJ-02 和 BD-09 的相互转换

3.1 GCJ-02 转 BD-09

 / * GCJ-02转BD-09 * * @param lng * @param lat * @return */ public static double[] 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 bdLng = z * Math.cos(theta) + 0.0065; double bdLat = z * Math.sin(theta) + 0.006; return new double[]{ 
   bdLng, bdLat}; } 

3.2 BD-09 转 GCJ-02

 / * BD-09转GCJ-02 * * @param lng * @param lat * @return */ public static double[] 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 gcjLng = z * Math.cos(theta); double gcjLat = z * Math.sin(theta); return new double[]{ 
   gcjLng, gcjLat}; } 

4. WGS-84 和 BD-09 的相互转换

4.1 WGS-84 转 BD-09

 / * WGS-84转BD-09 * * @param lng * @param lat * @return */ public static double[] wgs84ToBd09(double lng, double lat) { 
    double[] gcjPoint = wgs84ToGcj02(lng, lat); return gcj02ToBd09(gcjPoint[0], gcjPoint[1]); } 

4.2 BD-09 转 WGS-84

 / * BD-09转WGS-84 * * @param lng * @param lat * @return */ public static double[] bd09ToWgs84(double lng, double lat) { 
    double[] gcjPoint = bd09ToGcj02(lng, lat); return gcj02ToWgs84(gcjPoint[0], gcjPoint[1]); } 

三、坐标数据转换方法-Python 版

1. 准备工作

1.1 依赖的一些常量和转换方法

import math # 常量定义 PI = math.pi x_PI = float(PI * float(3000.0) / float(180.0)) aa = float(.0) ee = 0.00 # 经纬度偏移转换 def transform_lat(lng, lat): ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(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 def transform_lng(lng, lat): ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(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 # 判断坐标是否超出境内 def out_of_china(lng, lat): # 纬度3.86~53.55,经度73.66~135.05;非精确判断,可能误判 if 73.66 < lng < 135.05 and 3.86 < lat < 53.55: return False 

2. WGS-84 和 GCJ-02 的相互转换

2.1 WGS-84 转 GCJ-02

# WGS-84转GCJ-02 def wgs84_to_gcj02(lng, lat): if out_of_china(lng, lat): return [lng, lat] else: dlat = transform_lat(lng - 105.0, lat - 35.0) dlng = transform_lng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * PI magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((aa * (1 - ee)) / (magic * sqrtmagic) * PI) dlng = (dlng * 180.0) / (aa / sqrtmagic * math.cos(radlat) * PI) mglat = lat + dlat mglng = lng + dlng return [mglng, mglat] 

2.2 GCJ-02 转 WGS-84

# GCJ-02转WGS-84 def gcj02_to_wgs84(lng, lat): if out_of_china(lng, lat): return [lng, lat] else: dlat = transform_lat(lng - 105.0, lat - 35.0) dlng = transform_lng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * PI magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((aa * (1 - ee)) / (magic * sqrtmagic) * PI) dlng = (dlng * 180.0) / (aa / sqrtmagic * math.cos(radlat) * PI) mglat = lat + dlat mglng = lng + dlng return [lng * 2 - mglng, lat * 2 - mglat] 

3. GCJ-02 和 BD-09 的相互转换

3.1 GCJ-02 转 BD-09

# GCJ-02转BD-09 def gcj02_to_bd09(lng, lat): z = math.sqrt(lng * lng + lat * lat) + 0.00002 * math.sin(lat * x_PI) theta = math.atan2(lat, lng) + 0.000003 * math.cos(lng * x_PI) bd_lng = z * math.cos(theta) + 0.0065 bd_lat = z * math.sin(theta) + 0.006 return [bd_lng, bd_lat] 

3.2 BD-09 转 GCJ-02

# BD-09转GCJ-02 def bd09_to_gcj02(bd_lon, bd_lat): x = bd_lon - 0.0065 y = bd_lat - 0.006 z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_PI) theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_PI) gg_lng = z * math.cos(theta) gg_lat = z * math.sin(theta) return [gg_lng, gg_lat] 

4. WGS-84 和 BD-09 的相互转换

4.1 WGS-84 转 BD-09

# WGS-84转BD-09 def wgs84_to_bd09(lng, lat): gcj_point = wgs84_to_gcj02(lng, lat) bd_point = gcj02_to_bd09(gcj_point[0], gcj_point[1]) return [bd_point[0], bd_point[1]] 

4.2 BD-09 转 WGS-84

# BD-09转WGS-84 def bd09_to_wgs84(lng, lat): gcj_point = bd09_to_gcj02(lng, lat) wgs_point = gcj02_to_wgs84(gcj_point[0], gcj_point[1]) return [wgs_point[0], wgs_point[1]] 
今天的文章 常见GIS坐标系的坐标转换分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-08 11:21
下一篇 2024-12-08 11:17

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/81041.html