地图--WGS84 高德坐标 百度坐标的相互转换(好用推荐)

在地图学中,一般将坐标分为投影坐标和地理坐标。地理坐标和投影坐标的联系和区别对于一般的地图使用者而言可能并不需要掌握的非常清楚。通俗一点来说,地理坐标是一个球体的坐标,而投影坐标是一个平面的坐标。常用的GPS、百度地图、高德地图等都是采用的地理坐标。
确定了地理坐标之后,常见的地图应用分别采用的都是什么坐标系呢?一般来说,国外的一些地图,都是采用WGS84坐标系,比如谷歌地图、OMS地图、Bing地图(非中国区域)等。而国内的地图,处于保密需求,大多采用火星坐标系,在WGS84的基础上作了一些偏移,如高德地图、腾讯地图等。而百度又在火星坐标系的基础上又作了一定偏移,生成了自己的百度坐标系。

作者:家琦的三亩地
链接:https://www.jianshu.com/p/ee7dcac935cf
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

WGS84:谷歌地图 OMS
火星坐标系:高德地图 腾讯地图
百度坐标系:百度地图

这些加密算法,一般是无法准确还原的,但是在小范围内的数据,可以通过一定的变换相互转化。具体的C#代码如下

    调用示例如下
    //GPSPoint point = new GPSPoint();
    //point.lat = (double) decimal_lat;
    //point.lng = (double) decimal_lon;
    //point = GPSTransformer.transform(point, "84转百度");



    /// </summary>
    public struct GPSPoint
    {
        public double lng;
        public double lat;
    }

    /// <summary>
    ///坐标系转换帮助类
    /// </summary>
    /// WGS84:谷歌地图 OMS
    /// 火星坐标系:高德地图 腾讯地图
    /// 百度坐标系:百度地图
    /// 7
    /// 在地图学中,一般将坐标分为投影坐标和地理坐标。地理坐标和投影坐标的联系和区别对于一般的地图使用者而言可能并不需要掌握的非常清楚。通俗一点来说,地理坐标是一个球体的坐标,而投影坐标是一个平面的坐标。常用的GPS、百度地图、高德地图等都是采用的地理坐标。
    //确定了地理坐标之后,常见的地图应用分别采用的都是什么坐标系呢?一般来说,国外的一些地图,都是采用WGS84坐标系,比如谷歌地图、OMS地图、Bing地图(非中国区域)等。而国内的地图,处于保密需求,大多采用火星坐标系,在WGS84的基础上作了一些偏移,如高德地图、腾讯地图等。而百度又在火星坐标系的基础上又作了一定偏移,生成了自己的百度坐标系。
    //这些加密算法,一般是无法准确还原的,但是在小范围内的数据,可以通过一定的变换相互转化。具体的C#代码如下
    //作者:家琦的三亩地
    //链接:https://www.jianshu.com/p/ee7dcac935cf

    public class GPSTransformer
    {
        const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        const double pi = 3.1415926535897932384626; // π
        const double a = 6378245.0;// 长半轴
        const double ee = 0.00669342162296594323; // 扁率

        //火星转百度
        public static GPSPoint gcj02tobd09(GPSPoint HxCor)
        {
            double z = Math.Sqrt(HxCor.lng * HxCor.lng + HxCor.lat * HxCor.lat) + 0.00002 * Math.Sin(HxCor.lat * x_pi);
            double theta = Math.Atan2(HxCor.lat, HxCor.lng) + 0.000003 * Math.Cos(HxCor.lng * x_pi);
            GPSPoint BaiduCor;
            BaiduCor.lng = z * Math.Cos(theta) + 0.0065;
            BaiduCor.lat = z * Math.Sin(theta) + 0.006;
            return BaiduCor;
        }

        //百度转火星
        public static GPSPoint bd09togcj02(GPSPoint Bd)
        {
            double x = Bd.lng - 0.0065;
            double y = Bd.lat - 0.006;
            double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi);
            double theta = Math.Atan2(y, x) - .000003 * Math.Cos(x * x_pi);
            GPSPoint hx;
            hx.lng = z * Math.Cos(theta);
            hx.lat = z * Math.Sin(theta);
            return hx;
        }

        //WGS84转火星
        public static GPSPoint wgs84togcj02(GPSPoint wgs84)
        {
            if (OutOfChina(wgs84))
            {
                return wgs84;
            }
            double dlat = transformlat(wgs84.lng - 105.0, wgs84.lat - 35.0);
            double dlng = transformlng(wgs84.lng - 105.0, wgs84.lat - 35.0);
            double radlat = wgs84.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);
            dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * pi);
            GPSPoint hx;
            hx.lat = wgs84.lat + dlat;
            hx.lng = wgs84.lng + dlng;
            return hx;
        }


        //火星转84
        public static GPSPoint gcj02towgs84(GPSPoint hx)
        {
            if (OutOfChina(hx))
            {
                return hx;
            }
            double dlat = transformlat(hx.lng - 105.0, hx.lat - 35.0);
            double dlng = transformlng(hx.lng - 105.0, hx.lat - 35.0);
            double radlat = hx.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);
            dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * pi);
            GPSPoint wgs84;
            double mglat = hx.lat + dlat;
            double mglng = hx.lng + dlng;
            wgs84.lat = hx.lat * 2 - mglat;
            wgs84.lng = hx.lng * 2 - mglng;
            return wgs84;
        }

        //百度转84
        public static GPSPoint bd09towgs84(GPSPoint bd)
        {
            GPSPoint hx = bd09togcj02(bd);
            GPSPoint wgs84 = gcj02towgs84(hx);
            return wgs84;
        }

        //84转百度
        public static GPSPoint wgs84tobd09(GPSPoint wgs84)
        {
            GPSPoint hx = wgs84togcj02(wgs84);
            GPSPoint bd = gcj02tobd09(hx);
            return bd;
        }
        /*辅助函数*/
        //判断是否在国内
        private static Boolean OutOfChina(GPSPoint wgs84)
        {
            if (wgs84.lng < 72.004 || wgs84.lng > 137.8347)
            {
                return true;
            }
            if (wgs84.lat < 0.8293 || wgs84.lat > 55.8271)
            {
                return true;
            }
            return false;
        }

        /*辅助函数*/
        //转换lat
        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;
        }

        /*辅助函数*/
        //转换lng
        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;
        }

        // 按类计算
        public static GPSPoint transform(GPSPoint corOld, string transType)
        {
            switch (transType)
            {
                case "百度转火星":
                    return GPSTransformer.bd09togcj02(corOld);
                case "百度转84":
                    return GPSTransformer.bd09towgs84(corOld);
                case "火星转84":
                    return GPSTransformer.gcj02towgs84(corOld);
                case "84转火星":
                    return GPSTransformer.wgs84togcj02(corOld);
                case "火星转百度":
                    return GPSTransformer.gcj02tobd09(corOld);
                case "84转百度":
                    return GPSTransformer.wgs84tobd09(corOld);
                default:
                    return corOld;
            }
        }
    }

    //public class GPSPoint
    //{
    //    private double lat;// 纬度
    //    private double lng;// 经度

    //    public GPSPoint()
    //    {
    //    }

    //    public GPSPoint(double lng, double lat)
    //    {
    //        this.lng = lng;
    //        this.lat = lat;
    //    }

    //    public double GetLat()
    //    {
    //        return lat;
    //    }
    //    public void SetLat(double lat)
    //    {
    //        this.lat = lat;
    //    }
    //    public double GetLng()
    //    {
    //        return lng;
    //    }
    //    public void SetLng(double lng)
    //    {
    //        this.lng = lng;
    //    }
    //}
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值