常见GIS坐标系的坐标转换

几种常见的 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 = 6378245.0;
    private static final double EE = 0.00669342162296594323;

    /**
     * 经纬度偏移转换-经度
     *
     * @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(6378245.0)
ee = 0.00669342162296594323

# 经纬度偏移转换
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]]
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: GIS坐标转换为经纬度的在线小程序是一种能够帮助用户实现坐标转换的工具。通过该小程序,用户可以输入不同的GIS坐标(如高斯投影坐标、UTM坐标等),并将其转换为经纬度坐标。具体实现方法如下所述: 首先,用户需要在小程序的输入框中输入待转换的GIS坐标。小程序可以支持多种常用的GIS坐标格式,例如输入格式可以是(X,Y)或者X,Y形式的坐标。 接下来,小程序将根据用户输入的GIS坐标类型,使用相应的算法进行坐标转换。例如,如果用户输入的是高斯投影坐标,小程序将使用高斯投影反算公式进行计算,将其转换为经纬度坐标。 在计算完成后,小程序将会在界面上显示转换后的经纬度坐标。用户可以随时调整输入的GIS坐标,实时查看对应的经纬度坐标。 此外,小程序还可以提供一些额外的功能,例如批量转换、坐标定位等。用户可以通过这些功能进行一次性转换多个坐标,或者在地图上标注坐标点。 综上所述,GIS坐标转换为经纬度的在线小程序可以方便用户在移动设备上进行坐标转换操作。帮助用户快速获取需要的经纬度坐标信息,适用于需要频繁进行GIS坐标转换的场景。同时,小程序的便携性也使得用户可以随时随地进行坐标转换,提高工作效率。 ### 回答2: GIS坐标转换为经纬度在线小程序通常可以通过以下步骤完成: 1. 首先,需要获取用户输入的GIS坐标,包括坐标系类型以及坐标数值。可以通过输入框或地图选择的方式来实现用户输入。 2. 然后,根据用户选择的GIS坐标系类型,进行相应的转换算法。常见GIS坐标系包括UTM坐标系、高斯-克吕格投影等。针对不同的坐标系,可以编写不同的转换代码。 3. 在转换算法中,需要考虑坐标系的原点、投影参数、椭球体参数等。这些参数通常根据用户选择的坐标系类型进行设置。 4. 转换完成后,将经纬度数值显示给用户。可以以文本形式或地图标注的形式展示。 5. 同时,还可以添加一些附加功能,比如点击地图获取GIS坐标、批量转换多个坐标等。 6. 最后,为了提升用户体验,可以设计一些可选项,如选择常用的GIS坐标系、保存历史转换记录等。 需要注意的是,GIS坐标转换为经纬度涉及到复杂的数学计算和坐标系知识,因此在编写小程序时需要进行充分的测试和验证,确保转换结果准确可靠。同时,还需要确保小程序的界面友好、功能简洁,以便用户能够方便地进行坐标转换操作。 ### 回答3: GIS坐标转换为经纬度的在线小程序是一个方便用户将不同坐标系下的坐标转换为经纬度的工具。用户可以通过输入GIS坐标,选择当前坐标系,然后点击转换按钮进行转换操作。 这个在线小程序的实现需要用到一些基本的数学公式和算法,例如投影算法、反三角函数等。通过这些算法,可以将用户输入的GIS坐标转换为经纬度值。 在实现过程中,先要确定用户当前使用的坐标系,根据不同的坐标系选择不同的转换算法。然后,根据用户输入的GIS坐标,应用相应的算法进行计算,得出经纬度值。 在小程序界面上,可以设置一个输入框用于用户输入GIS坐标,提供一个下拉菜单来选择当前的坐标系。还可以添加一个转换按钮,点击按钮后触发转换操作,并在界面上显示转换后的经纬度结果。 总之,一个GIS坐标转换为经纬度的在线小程序可以帮助用户方便地进行坐标转换操作,无需手动计算和查表。用户只需输入GIS坐标,并选择当前坐标系,点击转换即可得到对应的经纬度值。这个小程序的实现需要用到一些基本的算法和数学知识,但用户可以通过简单的操作就能完成坐标转换

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值