Android 84、gc、高德、百度、墨卡托地理坐标转换

开发时我们有两个项目,一个web端,都涉及到地图,所以坐标系的统一至关重要,问题是,我们两个项目一个高德,一个百度,web端用的是天地图,在上传坐标的时候都涉及到了坐标转换的问题,那么我们常用的地图都是什么坐标系呢

参考博客:http://blog.csdn.net/jiang117/article/details/48031927

上面介绍的很清楚,我这里就简单的说,方便运用。

android 开发一般都使用高德地图或者百度地图,常见的坐标系就是gs和84,gc也就是火星坐标系,

84就是大地坐标系,LocationManager获取的就是这个坐标系

gc(国测局)就是我国使用的,又名”火星坐标系“当然也就是加密的坐标系,高德地图、搜狗地图等,就是使用了这一套坐标系

百度地图则是在gc的基础上自己加密的一个坐标系

所以在转换的时候就设计到了gc、84、百度之间的转换。

 

这个基本也就全了,方便大家使用

 

public class GCJ02ToWGS84Util {

   /**
    * 地球坐标系 (WGS-84) 相互转火星坐标系 (GCJ-02) 的转换算法
    *
    * @author jxh
    * @time 2013-5-16
    */
   private static double pi = 3.14159265358979324D;// 圆周率
   private static double a = 6378245.0D;// WGS 长轴半径
   private static double ee = 0.00669342162296594323D;// WGS 偏心率的平方
   private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;

   /**
    * 中国坐标内
    *
    * @param lat
    * @param lon
    * @return
    */
   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;
   }

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

   // 84->gcj02
   public static Map<String, Double> transform(double lon, double lat) {
      HashMap<String, Double> localHashMap = new HashMap<String, Double>();
      if (outofChina(lat, lon)) {
         localHashMap.put("lon", Double.valueOf(lon));
         localHashMap.put("lat", Double.valueOf(lat));
         return localHashMap;
      }
      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;
      localHashMap.put("lon", mgLon);
      localHashMap.put("lat", mgLat);
      return localHashMap;
   }

   // gcj02-84
   public static Map<String, Double> gcj2wgs(double lon, double lat) {
      Map<String, Double> localHashMap = new HashMap<String, Double>();
      double lontitude = lon
            - (((Double) transform(lon, lat).get("lon")).doubleValue() - lon);
      double latitude = (lat - (((Double) (transform(lon, lat)).get("lat"))
            .doubleValue() - lat));
      localHashMap.put("lon", lontitude);
      localHashMap.put("lat", latitude);
      return localHashMap;
   }

   /**
    * 火星坐标转换为百度坐标
    *
    * @param gg_lat
    * @param gg_lon
    */
   public static Map<String, Double> bd_encrypt(double gg_lat, double gg_lon) {
      Map<String, Double> bdlocalHashMap = new HashMap<String, Double>();
      double x = gg_lon, y = gg_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 bd_lon = z * Math.cos(theta) + 0.0065;
      double bd_lat = z * Math.sin(theta) + 0.006;
      bdlocalHashMap.put("lon", bd_lon);
      bdlocalHashMap.put("lat", bd_lat);
      return bdlocalHashMap;
   }

   /**
    * 84转百度
    *
    * @param latitude  纬度
    * @param longitude 经度
    * @return
    */
   public static Map<String, Double> wgs84_bd09(double latitude, double longitude) {
      //1,84转国测局gcj-02
      Map<String, Double> mapForGCJ = transform(longitude, latitude);
      Double lonGCJ = mapForGCJ.get("lon");
      Double latGCJ = mapForGCJ.get("lat");
      //2.gcj-02转百度
      Map<String, Double> mapForBD09 = bd_encrypt(latGCJ, lonGCJ);
      return mapForBD09;
   }

   /**
    * 百度转gcj02
    */
   public static Map<String, Double> bd09togcj02(double bd_lon, double bd_lat){
        Map<String, Double> bdtogcmap = new HashMap<>();
        double x = bd_lon - 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) - 0.000003 * Math.cos(x * x_pi);
        double gg_lng = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        bdtogcmap.put("lon", gg_lng);
        bdtogcmap.put("lat", gg_lat);
        return bdtogcmap;
    }

    /**
     * 百度转84
     */
    public static Map<String, Double> bd09to84(double bd_lon, double bd_lat){
        Map<String, Double> bdtogcmap = bd09togcj02(bd_lon, bd_lat);
        Double lon = bdtogcmap.get("lon");
        Double lat = bdtogcmap.get("lat");

        Map<String, Double> gcto84map = gcj2wgs(lon, lat);
        return gcto84map;
    }
}

 

添加84和墨卡托的转换(借鉴http://www.gisall.com/html/68/104468-4865.html

 

 

[cpp] view plaincopy

  1. //经纬度转Wev墨卡托  
  2. dvec3 CMathEngine::lonLat2WebMercator(dvec3  lonLat)  
  3. {  
  4.     dvec3  mercator;  
  5.     double x = lonLat.x *20037508.34/180;  
  6.     double y = log(tan((90+lonLat.y)*PI/360))/(PI/180);  
  7.     y = y *20037508.34/180;  
  8.     mercator.x = x;  
  9.     mercator.y = y;  
  10.     return mercator ;  
  11. }  
  12. //Web墨卡托转经纬度  
  13. dvec3 CMathEngine::WebMercator2lonLat( dvec3   mercator )  
  14. {  
  15.     dvec3 lonLat;  
  16.     double x = mercator.x/20037508.34*180;  
  17.     double y = mercator.y/20037508.34*180;  
  18.     y= 180/PI*(2*atan(exp(y*PI/180))-PI/2);  
  19.     lonLat.x = x;  
  20.     lonLat.y = y;  
  21.     return lonLat;  
  22. }  


经过笔者测试,与Google map dowloader软件系列的转换器相比,在14级别的某地图上测试有0.04个像素误差,基本可以无视。

 

其他级别和经纬区域有待测试

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值