各地图坐标系转换(WGS84坐标系,GCJ02坐标系,BD09坐标系)

各地图坐标系转换(WGS84坐标系,GCJ02坐标系,BD09坐标系)
  1. package position;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. /** 
  6.  * 各地图API坐标系统比较与转换; 
  7.  *  
  8.  * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,谷歌地图采用的是WGS84地理坐标系(中国范围除外); 
  9.  *  
  10.  * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系; 
  11.  *  
  12.  * BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系; 
  13.  *  
  14.  * 搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。 
  15.  *  
  16.  * @author chenhua 
  17.  *  
  18.  */  
  19. public class PositionUtil  
  20. {  
  21.     private static double pi = 3.1415926535897932384626;  
  22.     private static double a = 6378245.0;  
  23.     private static double ee = 0.00669342162296594323;  
  24.   
  25.     @Test  
  26.     public void t1()  
  27.     {  
  28.         // 北斗芯片获取的经纬度为WGS84地理坐标 31.426896,119.496145  
  29.   
  30.         Gps gps = new Gps(31.426896119.496145);  
  31.         System.out.println("gps :" + gps);  
  32.   
  33.         Gps gcj = gps84_To_Gcj02(gps.getWgLat(), gps.getWgLon());  
  34.         System.out.println("gcj :" + gcj);  
  35.   
  36.         Gps star = gcj_To_Gps84(gcj.getWgLat(), gcj.getWgLon());  
  37.         System.out.println("star:" + star);  
  38.   
  39.         Gps bd = gcj02_To_Bd09(gcj.getWgLat(), gcj.getWgLon());  
  40.         System.out.println("bd  :" + bd);  
  41.   
  42.         Gps gcj2 = bd09_To_Gcj02(bd.getWgLat(), bd.getWgLon());  
  43.         System.out.println("gcj :" + gcj2);  
  44.   
  45.     }  
  46.   
  47.     /** 
  48.      * 84 to 火星坐标系 (GCJ-02) 
  49.      *  
  50.      * World Geodetic System ==> Mars Geodetic System 
  51.      *  
  52.      * @param lat 
  53.      * @param lon 
  54.      * @return 
  55.      */  
  56.     public static Gps gps84_To_Gcj02(double lat, double lon)  
  57.     {  
  58.         if (outOfChina(lat, lon))  
  59.         {  
  60.             return null;  
  61.         }  
  62.         double dLat = transformLat(lon - 105.0, lat - 35.0);  
  63.         double dLon = transformLon(lon - 105.0, lat - 35.0);  
  64.         double radLat = lat / 180.0 * pi;  
  65.         double magic = Math.sin(radLat);  
  66.         magic = 1 - ee * magic * magic;  
  67.         double sqrtMagic = Math.sqrt(magic);  
  68.         dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);  
  69.         dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);  
  70.         double mgLat = lat + dLat;  
  71.         double mgLon = lon + dLon;  
  72.   
  73.         return new Gps(mgLat, mgLon);  
  74.     }  
  75.   
  76.     /** 
  77.      * 火星坐标系 (GCJ-02) to 84 
  78.      *  
  79.      * @param lon 
  80.      * @param lat 
  81.      * @return 
  82.      */  
  83.     public Gps gcj_To_Gps84(double lat, double lon)  
  84.     {  
  85.         Gps gps = transform(lat, lon);  
  86.         double lontitude = lon * 2 - gps.getWgLon();  
  87.         double latitude = lat * 2 - gps.getWgLat();  
  88.   
  89.         return new Gps(latitude, lontitude);  
  90.   
  91.     }  
  92.   
  93.     /** 
  94.      * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 
  95.      *  
  96.      * 将 GCJ-02 坐标转换成 BD-09 坐标 
  97.      *  
  98.      * @param gg_lat 
  99.      * @param gg_lon 
  100.      */  
  101.     public static Gps gcj02_To_Bd09(double gg_lat, double gg_lon)  
  102.     {  
  103.         double x = gg_lon, y = gg_lat;  
  104.   
  105.         double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);  
  106.   
  107.         double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);  
  108.   
  109.         double bd_lon = z * Math.cos(theta) + 0.0065;  
  110.   
  111.         double bd_lat = z * Math.sin(theta) + 0.006;  
  112.   
  113.         return new Gps(bd_lat, bd_lon);  
  114.     }  
  115.   
  116.     /** 
  117.      * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 
  118.      *  
  119.      * 将 BD-09 坐标转换成GCJ-02 坐标 
  120.      *  
  121.      * @param bd_lat 
  122.      * @param bd_lon 
  123.      * @return 
  124.      */  
  125.     public static Gps bd09_To_Gcj02(double bd_lat, double bd_lon)  
  126.     {  
  127.         double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
  128.   
  129.         double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);  
  130.   
  131.         double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);  
  132.   
  133.         double gg_lon = z * Math.cos(theta);  
  134.   
  135.         double gg_lat = z * Math.sin(theta);  
  136.   
  137.         return new Gps(gg_lat, gg_lon);  
  138.     }  
  139.   
  140.     private static boolean outOfChina(double lat, double lon)  
  141.     {  
  142.         if (lon < 72.004 || lon > 137.8347)  
  143.             return true;  
  144.         if (lat < 0.8293 || lat > 55.8271)  
  145.             return true;  
  146.         return false;  
  147.     }  
  148.   
  149.     private Gps transform(double lat, double lon)  
  150.     {  
  151.         if (outOfChina(lat, lon))  
  152.         {  
  153.             return new Gps(lat, lon);  
  154.         }  
  155.         double dLat = transformLat(lon - 105.0, lat - 35.0);  
  156.         double dLon = transformLon(lon - 105.0, lat - 35.0);  
  157.         double radLat = lat / 180.0 * pi;  
  158.         double magic = Math.sin(radLat);  
  159.         magic = 1 - ee * magic * magic;  
  160.         double sqrtMagic = Math.sqrt(magic);  
  161.         dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);  
  162.         dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);  
  163.         double mgLat = lat + dLat;  
  164.         double mgLon = lon + dLon;  
  165.   
  166.         return new Gps(mgLat, mgLon);  
  167.     }  
  168.   
  169.     private static double transformLat(double x, double y)  
  170.     {  
  171.         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));  
  172.         ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;  
  173.         ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;  
  174.         ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;  
  175.         return ret;  
  176.     }  
  177.   
  178.     private static double transformLon(double x, double y)  
  179.     {  
  180.         double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));  
  181.         ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;  
  182.         ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;  
  183.         ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;  
  184.         return ret;  
  185.     }  
  186.   
  187. }  
[java]  view plain copy 在CODE上查看代码片
  1. package position;  
  2.   
  3. public class Gps  
  4. {  
  5.   
  6.     private double wgLat;  
  7.     private double wgLon;  
  8.   
  9.     public Gps(double wgLat, double wgLon)  
  10.     {  
  11.         setWgLat(wgLat);  
  12.         setWgLon(wgLon);  
  13.     }  
  14.   
  15.     public double getWgLat()  
  16.     {  
  17.         return wgLat;  
  18.     }  
  19.   
  20.     public void setWgLat(double wgLat)  
  21.     {  
  22.         this.wgLat = wgLat;  
  23.     }  
  24.   
  25.     public double getWgLon()  
  26.     {  
  27.         return wgLon;  
  28.     }  
  29.   
  30.     public void setWgLon(double wgLon)  
  31.     {  
  32.         this.wgLon = wgLon;  
  33.     }  
  34.   
  35.     @Override  
  36.     public String toString()  
  37.     {  
  38.         return wgLat + "," + wgLon;  
  39.     }  
  40.   
  41. }  

你可能感兴趣的:(各地图坐标系转换(WGS84坐标系,GCJ02坐标系,BD09坐标系))