火星坐标系 (GCJ 02) 与百度坐标系 (BD 09) 的互转 以及其他经纬度相关方法 - s9797456/MyCommonCodeSnippets GitHub Wiki
package com.xinle.car.admin.common.util;
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.util.Arrays; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject;
/**
-
火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的互转 以及其他经纬度相关方法
-
http://blog.csdn.net/a13570320979/article/details/51366355 */ public class GPSUtil { public static final double pi = 3.1415926535897932384626;
public static final double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
public static final double a = 6378245.0;
public static final double ee = 0.00669342162296594323; public static final double DICTINCE_COV = 0.01745329251994329D;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};
}/**
- 坐标点经纬度是否在国外(国外坐标点经纬度不需要转换)
- @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;
}
/**
- 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[]{mgLon, mgLat};
}
/**
- 火星坐标系 (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;
}
/**
- 将bd09转为 gps84
- @param lat
- @param lon
- @return
*/
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;
}
/**
- 计算两个经纬度之间的距离
- lat 小 log 大 */ public static double GetDistance(double lng1, double lat1, double lng2, double lat2) { double var4 = lng1 * DICTINCE_COV; double var6 = lat1 * DICTINCE_COV; double var8 = lng2 * DICTINCE_COV; double var10 = lat2 * DICTINCE_COV; double var12 = Math.sin(var4); double var14 = Math.sin(var6); double var16 = Math.cos(var4); double var18 = Math.cos(var6); double var20 = Math.sin(var8); double var22 = Math.sin(var10); double var24 = Math.cos(var8); double var26 = Math.cos(var10); double[] var28 = new double[3]; double[] var29 = new double[3]; var28[0] = var18 * var16; var28[1] = var18 * var12; var28[2] = var14; var29[0] = var26 * var24; var29[1] = var26 * var20; var29[2] = var22; double var30 = Math.sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])); return (float)(Math.asin(var30 / 2.0D) * 1.27420015798544E7D); }
/**
- 根据经纬度获取地名
- lat 小 log 大 */ public static String getAdd(String log, String lat) { // lat 小 log 大 // 参数解释: 纬度,经度 type 001 (100代表道路,010代表POI,001代表门址,111可以同时显示前三项) String urlString = "http://gc.ditu.aliyun.com/regeocoding?l=" + lat + "," + log + "&type=010"; StringBuffer res = new StringBuffer(); try { URL url = new URL(urlString); java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { res.append(line); } in.close(); } catch (Exception e) { System.out.println("error in wapaction,and e is " + e.getMessage()); } return res.toString(); }
@SuppressWarnings("rawtypes") public static String getAddName(String lng, String lat) { String addName = ""; String add = ""; try { add = getAdd(lng, lat);
Map map = (Map) JSON.parse(add); // 先转换成Object JSONArray nameMap = (JSONArray) map.get("addrList"); JSONObject j_2 = nameMap.getJSONObject(0); String allAdd = j_2.getString("admName"); String arr[] = allAdd.split(","); if(arr.length == 3) { addName = arr[2] + j_2.getString("addr") + j_2.getString("name"); }else { addName = j_2.getString("addr") + j_2.getString("name"); } }catch(Exception e) { } if(StringUtils.isBlank(addName)) { addName = "地址名称转换失败"; } return addName;
}
/**
- 保留小数点后六位
- @param num
- @return
*/
private static double retain6(double num){
String result = String .format("%.6f", num);
return Double.valueOf(result);
}
public static void main(String[] args) { // [114.04291, 22.527493] [113.87546, 22.568424] [114.04066, 22.715206] [114.11545, 22.545536] // [113.96032, 22.566998] [114.11932, 22.54414] [114.06837, 22.531603] [113.674095, 22.869143] double lat1 = 114.04291, lon1 = 22.527493; Double[] real = gps84_To_Gcj02(lon1, lat1); System.out.println("==============>"); System.out.println(Arrays.toString(real)); // 22.5247138900,114.0479726400
double lat2 = 113.87546, lon2 = 22.568424; Double[] real2 = gps84_To_Gcj02(lon2, lat2); System.out.println("==============>"); System.out.println(Arrays.toString(real2)); // 22.5653925300,113.8803630500 double lat3 = 114.04066, lon3 = 22.715206; Double[] real3 = gps84_To_Gcj02(lon3, lat3); System.out.println("==============>"); System.out.println(Arrays.toString(real3)); // 22.7124798600,114.0457578400 double lat4 = 114.11545, lon4 = 22.545536; Double[] real4 = gps84_To_Gcj02(lon4, lat4); System.out.println("==============>"); System.out.println(Arrays.toString(real4)); // 22.5428395000,114.1205429800 String addName = getAddName("114.041084", "22.616901"); System.out.println(addName); //获取两点之间距离 //海事局--中医院 double dist = GetDistance(114.092406,22.534082, 114.085346,22.537016); System.out.println(dist);
} }