将GPS坐标转换为火星坐标

在谈到地图坐标转换前,有必要了解一下关于地图坐标的相关知识:

一、分类:

地图坐标大致分为几种:

1、GPS、WGS84,也就是原始坐标体系,这是国际公认的世界标准坐标体系;

2、GCJ-02,又称为“火星坐标”,国家测绘局在02年发布的坐标体系,在国内,至少得使用此坐标体系,比如:google、高德、腾讯地图等;

3、其他特殊坐标体系,一般都是由火星坐标通过偏移算法计算得出的,比如百度使用的是BD-09坐标,搜狗使用的是自己的搜狗坐标。

二、坐标转换:

由于国内目前的已知的地图所使用的坐标体系不同,这就造成有时候服务端给的坐标,在不同的地图上显示会存在很大的偏移差。因此需要进行坐标转换。

下面介绍一下不同地图的坐标转换方法:

[mw_shl_code=java,true]static double a = 6378245.0;
        static double ee = 0.00669342162296594323;

        public static LatLng transformFromWGSToGCJ(LatLng wgLoc) {

                //如果在国外,则默认不进行转换
                if (outOfChina(wgLoc.latitude, wgLoc.longitude)) {
                        return new LatLng(wgLoc.latitude, wgLoc.longitude);
                }
                double dLat = transformLat(wgLoc.longitude - 105.0,
                                wgLoc.latitude - 35.0);
                double dLon = transformLon(wgLoc.longitude - 105.0,
                                wgLoc.latitude - 35.0);
                double radLat = wgLoc.latitude / 180.0 * Math.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) * Math.PI);
                dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);

                return new LatLng(wgLoc.latitude + dLat, wgLoc.longitude + dLon);
        }

        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(x > 0 ? x : -x);
                ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
                                * Math.PI)) * 2.0 / 3.0;
                ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0
                                * Math.PI)) * 2.0 / 3.0;
                ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y
                                * Math.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(x > 0 ? x : -x);
                ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
                                * Math.PI)) * 2.0 / 3.0;
                ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0
                                * Math.PI)) * 2.0 / 3.0;
                ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x
                                / 30.0 * Math.PI)) * 2.0 / 3.0;
                return ret;
        }

        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;
        }[/mw_shl_code]

—–上面的方法就是将WGS84坐标转换为高德地图能够识别的GCJ-02坐标。此方法经过本人的测试,发现误差很小。大家也可以尝试下。

这里要提到的一点就是:通常一般来说,腾讯、高德提供的坐标都是经度在前,纬度在后的,例如:(116.388171,39.935961),但是服务端提供的wgs84坐标有可能其经纬度是反方向的,即纬度在前,经度在后,需要留意下。

使用方法:
在获取到经纬度之后组装成:LatLng lat = new LatLng(纬度, 经度),调用 transformFromWGSToGCJ(lat )即可:

注:
1)、这个坐标转换方法是本人参照github上面一个c语言的坐标转换方式改写成java的,附上原Github地址:
https://github.com/JackZhouCn/JZLocationConverter,这个里面还有各个坐标体系之间的互转:如“WGS-84 -> BD-09、GCJ-02 -> WGS-84、BD-09 -> WGS-84、GCJ-02 -> BD-09、BD-09 -> GCJ-02,当然误差是难免的,不过一般情况下都是可以用的。

2)、当然里面涉及到转换为百度的BD-09坐标的话,还是按照百度提供的隐藏api来调用把,因此这里提供的的转换方法会有微小的误差,官方提供的才是正统,
百度的坐标转换类是:CoordinateConvert,这个转换类提供了两种转换方法:一种是fromGcjToBaidu、另一种就是fromWgs84ToBaidu,我们在需要转换的时候可以根据特定的坐标选择相应的转换方法。

你可能感兴趣的:(技术总结)