资讯专栏INFORMATION COLUMN

百度,高德,Google地图定位偏移以及坐标系转换

nidaye / 2686人阅读

摘要:高德和在国内都是使用坐标系或在此基础上面加密为直接的坐标系,可以说,是国内最广泛使用的坐标系百度坐标系,百度坐标系是在坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图。

概述

一:在进行地图开发过程中,我们一般能接触到以下三种类型的地图坐标系:

1.WGS-84原始坐标系,一般用国际GPS纪录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的;但是在国内是不允许直接用WGS84坐标系标注的,必须经过加密后才能使用;

2.GCJ-02坐标系,又名“火星坐标系”,是我国国测局独创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系或在此基础上面加密为直接的坐标系,可以说,GCJ-02是国内最广泛使用的坐标系;

3.百度坐标系:bd-09,百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图。(目前百度API提供了从其它坐标系转换为百度坐标系的API,但却没有从百度坐标系转为其他坐标系的API)

二:为什么会发生偏移?

1.由于坐标系之间不兼容,如在百度地图上定位的经纬度拿到高德地图上直接描点就肯定会发生偏移;只考虑国内的情况,高德地图和Google地图是可以不经过转换也能够准确显示的(在国内用的都是GCJ-02坐标系);下面是收录了网上的WGS-84,GCJ-02,百度坐标系(bd-09)之间的相互转换的方法,经测试,是转换后相对准确可用的:

测试

工具类:

package com.topinfo.gps;

/**
 * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的互转
 * 
 */
public class GPSUtil {

    public static double pi   = 3.1415926535897932384626;
    public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    public static double a    = 6378245.0;
    public static double ee   = 0.00669342162296594323;

    public 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;
    }

    public 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;
    }

    public static double[] transform(double lat,double lon){
        if (outOfChina (lat, lon)) { return new double[] { lat, lon }; }
        double dLat = transformLat (lon - 105.0, lat - 35.0);
        double dLon = transformLon (lon - 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) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos (radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new double[] { mgLat, mgLon };
    }

    public 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;
    }

    /**
     * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System
     *
     * @param lat
     * @param lon
     * @return
     */
    public static double[] gps84_To_Gcj02(double lat,double lon){
        if (outOfChina (lat, lon)) { return new double[] { lat, lon }; }
        double dLat = transformLat (lon - 105.0, lat - 35.0);
        double dLon = transformLon (lon - 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) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos (radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new double[] { mgLat, mgLon };
    }

    /**
     * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
     * */
    public static double[] gcj02_To_Gps84(double lat,double lon){
        double[] gps = transform (lat, lon);
        double lontitude = lon * 2 - gps[1];
        double latitude = lat * 2 - gps[0];
        return new double[] { latitude, lontitude };
    }

    /**
     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
     *
     * @param lat
     * @param lon
     */
    public static double[] gcj02_To_Bd09(double lat,double lon){
        double x = lon, y = lat;
        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 tempLon = z * Math.cos (theta) + 0.0065;
        double tempLat = z * Math.sin (theta) + 0.006;
        double[] gps = { tempLat, tempLon };
        return gps;
    }

    /**
     * * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
     * bd_lat * @param bd_lon * @return
     */
    public static double[] bd09_To_Gcj02(double lat,double lon){
        double x = lon - 0.0065, 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 tempLon = z * Math.cos (theta);
        double tempLat = z * Math.sin (theta);
        double[] gps = { tempLat, tempLon };
        return gps;
    }

    /**将gps84转为bd09
     * @param lat
     * @param lon
     * @return
     */
    public static double[] gps84_To_bd09(double lat,double lon){
        double[] gcj02 = gps84_To_Gcj02 (lat, lon);
        double[] bd09 = gcj02_To_Bd09 (gcj02[0], gcj02[1]);
        return bd09;
    }

    public static double[] bd09_To_gps84(double lat,double lon){
        double[] gcj02 = bd09_To_Gcj02 (lat, lon);
        double[] gps84 = gcj02_To_Gps84 (gcj02[0], gcj02[1]);
        // 保留小数点后六位
        gps84[0] = retain6 (gps84[0]);
        gps84[1] = retain6 (gps84[1]);
        return gps84;
    }

    /**保留小数点后六位
     * @param num
     * @return
     */
    private static double retain6(double num){
        String result = String.format ("%.6f", num);
        return Double.valueOf (result);
    }

}

测试类:

package com.topinfo.gps;

public class Test2 {

    /**
    
    //GPS坐标
    116.32715863448607
    39.990912172420714
    
    //百度
    116.33993794567915
    39.99790821949972
     
    */
    
    public static void main(String[] args){
        
        double[] gps =  GPSUtil.gps84_To_bd09 (39.990912172420714, 116.32715863448607);
        
        System.out.println (gps[0]);
        System.out.println (gps[1]);
         
       
        
    }
    
}

输出:
39.997903976430734
116.33993249456921

经过比对:
39.997903976430734
39.99790821949972

116.33993249456921
116.33993794567915

然后在百度官网API测试;也几乎是重叠的,如果:

工具类我是在 https://blog.csdn.net/a135703... 找到的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74369.html

相关文章

  • 前端小知识--地图坐标转换

    摘要:实际中我们可能会用到不同的地图,那么就对应到不同坐标系的转换,比如说,你有一份的数据服务,你要展现在百度或者高德地图上,这时候你就需要转换了。 地图坐标转换 LBS,基于位置的服务(Location Based Service),近年来已经无处不在,尤其是我们前端,相信或多或少都有接触一些地图API服务,比如高德、百度啊、谷歌啊~但是用的时候可能看到下面这些字眼:比如BD09、火星坐标...

    liangdas 评论0 收藏0
  • gcoord: 转换WGS84、GCJ02、BD09坐标,解决百度地图高德地图标系不统一的问题

    摘要:做过地图相关开发的同学肯定会遇到这样一个问题同样的经纬度坐标,在百度地图和高德地图上位置不一样。解决方案百度地图以及高德地图都提供了一些方法来转换不同坐标系下的坐标,但是它们都需要进行网络请求,性能很差。 做过地图相关开发的同学肯定会遇到这样一个问题:同样的经纬度坐标,在百度地图和高德地图上位置不一样。showImg(https://segmentfault.com/img/remot...

    yimo 评论0 收藏0
  • 如何用Python完成百度高德地图转换

      众所周知,Python的一个使用场景还是比较多的,在工作当中,也会涉及到多方面的一些事情。那么,今天小编写这篇文章的一个主要目的,给大家来介绍关于如何用Python完成百度与搞得地图转换,下面就给大家详细介绍下。  一、地理编码与逆编码  地理编码与逆编码表示的是地名地址与地理坐标(经纬度)互相转换的过程。其中,将地址信息映射为地理坐标的过程称之为地理编码;将地理坐标转换为地址信息的过程称之为...

    89542767 评论0 收藏0
  • GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)

    摘要:转换的结果和百度提供的接口精确到小数点后位请放心使用卫星椭球坐标投影到平面地图坐标系的投影因子。 WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块) GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用 BD-09:百度坐标偏移标准,Baidu Map使用 WGS-84 to GCJ-02 GPS.gcj_encrypt(); GC...

    Baaaan 评论0 收藏0
  • GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)

    摘要:转换的结果和百度提供的接口精确到小数点后位请放心使用卫星椭球坐标投影到平面地图坐标系的投影因子。 WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块) GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用 BD-09:百度坐标偏移标准,Baidu Map使用 WGS-84 to GCJ-02 GPS.gcj_encrypt(); GC...

    Paul_King 评论0 收藏0

发表评论

0条评论

nidaye

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<