https://wenku.baidu.com/view/4e528439b4360b4c2e3f5727a5e9856a5612269c.html 或https://blog.csdn.net/qq_29384789/article/details/113247108 也不知那个是原创 借鉴借鉴
以下的方法可以实现CGCS2000大地坐标系XY值转化为对应经纬度信息,
注意输入的XY值与给定的值相反,则参数X为已知的Y,参数Y为已知的X。
得出的结果为 [纬度,经度],不要应用错误。
L0参数为中央子午线的经线值,应用方法前需要确定L0的值,否则得出的值会有很大的偏差
/**
* y x 转换成经纬度
* @param X y 这里的X是坐标的y
* @param Y x
* @param L0 浙江 120 中央子午线
* @return
*/
public static double [] xytolatlon(double X, double Y ,double L0) {
double lat ,lon;
Y-=500000;
double [] result = new double[2];
double iPI = 0.0174532925199433;//pi/180
double a = 6378137.0; //长半轴 m
double b = 6356752.31414; //短半轴 m
double f = 1/298.257222101;//扁率 a-b/a
double e = 0.0818191910428; //第一偏心率 Math.sqrt(5)
double ee = Math.sqrt(a*a-b*b)/b; //第二偏心率
double bf = 0; //底点纬度
double a0 = 1+(3*e*e/4) + (45*e*e*e*e/64) + (175*e*e*e*e*e*e/256) + (11025*e*e*e*e*e*e*e*e/16384) + (43659*e*e*e*e*e*e*e*e*e*e/65536);
double b0 = X/(a*(1-e*e)*a0);
double c1 = 3*e*e/8 +3*e*e*e*e/16 + 213*e*e*e*e*e*e/2048 + 255*e*e*e*e*e*e*e*e/4096;
double c2 = 21*e*e*e*e/256 + 21*e*e*e*e*e*e/256 + 533*e*e*e*e*e*e*e*e/8192;
double c3 = 151*e*e*e*e*e*e*e*e/6144 + 151*e*e*e*e*e*e*e*e/4096;
double c4 = 1097*e*e*e*e*e*e*e*e/131072;
bf = b0 + c1*Math.sin(2*b0) + c2*Math.sin(4*b0) +c3*Math.sin(6*b0) + c4*Math.sin(8*b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...
double tf = Math.tan(bf);
double n2 = ee*ee*Math.cos(bf)*Math.cos(bf); //第二偏心率平方成bf余弦平方
double c = a*a/b;
double v=Math.sqrt(1+ ee*ee*Math.cos(bf)*Math.cos(bf));
double mf = c/(v*v*v); //子午圈半径
double nf = c/v;//卯酉圈半径
//纬度计算
lat=bf-(tf/(2*mf)*Y)*(Y/nf) * (1-1/12*(5+3*tf*tf+n2-9*n2*tf*tf)*(Y*Y/(nf*nf))+1/360*(61+90*tf*tf+45*tf*tf*tf*tf)*(Y*Y*Y*Y/(nf*nf*nf*nf)));
//经度偏差
lon=1/(nf*Math.cos(bf))*Y -(1/(6*nf*nf*nf*Math.cos(bf)))*(1+2*tf*tf +n2)*Y*Y*Y + (1/(120*nf*nf*nf*nf*nf*Math.cos(bf)))*(5+28*tf*tf+24*tf*tf*tf*tf)*Y*Y*Y*Y*Y;
result[0] =retain6((lat/iPI));
result[1] =retain6(L0+lon/iPI);
//System.out.println(result[1]+","+result[0]);
return result;
}
private static double retain6(double num) {
String result = String.format("%.6f", num);
return Double.valueOf(result);
}
上面的这个实验成功 下面的米勒投影的转换 转换我不太清楚是那种坐标下 同样的xy出来的经纬度 和上面的那种不一样
/**
* 经纬转 y x
* 米勒投影
*/
public static String MillierConvertion(double lat, double lon) {
double L = 6381372 * Math.PI * 2;//地球周长
double W = L;// 平面展开后,x轴等于周长
double H = L / 2;// y轴约等于周长一半
double mill = 2.3;// 米勒投影中的一个常数,范围大约在正负2.3之间
double x = lon * Math.PI / 180;// 将经度从度数转换为弧度
double y = lat * Math.PI / 180;// 将纬度从度数转换为弧度
y = 1.25 * Math.log(Math.tan(0.25 * Math.PI + 0.4 * y));// 米勒投影的转换
// 弧度转为实际距离
x = (W / 2) + (W / (2 * Math.PI)) * x;
y = (H / 2) - (H / (2 * mill)) * y;
double[] result = new double[2];
result[0] = x;
result[1] = y;
return "X:" + result[0] + " Y:" + result[1];
}
/**
* y x 转换成经纬度
* @param x
* @param y
* @return
*/
public static double[] MillierConvertion1(double x, double y) {
double L = 6381372 * Math.PI * 2;//地球周长
double W = L;// 平面展开后,x轴等于周长
double H = L / 2;// y轴约等于周长一半
double mill = 2.3;// 米勒投影中的一个常数,范围大约在正负2.3之间
double lat;
lat = ((H / 2 - y) * 2 * mill) / (1.25 * H);
lat = ((Math.atan(Math.exp(lat)) - 0.25 * Math.PI) * 180) / (0.4 * Math.PI);
double lon;
lon = (x - W / 2) * 360 / W;
double[] result = new double[2];
result[0] = lon;
result[1] = lat;
// return "lon:" + result[0] + " lat:" + result[1];
return result;
}
WGS84坐标系是1984世界大地坐标系(World Geodetic System)的简称。它是美国国防制图局于1984年建立的,是GPS卫星星历的参考基准,也是协议地球参考系的一种
地心坐标系(geocentric coordinate system )以地球质心为原点建立的空间直角坐标系,或以球心与地球质心重合的地球椭球面为基准面所建立的大地坐标系
/**
* WGS84转地心坐标系
**/
public static double[] WGS84toECEF(double latitude, double longitude, double height) {
double X;
double Y;
double Z;
double a = 6378137.0;
double b = 6356752.31424518;
double E = (a * a - b * b) / (a * a);
double COSLAT = Math.cos(latitude * Math.PI / 180);
double SINLAT = Math.sin(latitude * Math.PI / 180);
double COSLONG = Math.cos(longitude * Math.PI / 180);
double SINLONG = Math.sin(longitude * Math.PI / 180);
double N = a / (Math.sqrt(1 - E * SINLAT * SINLAT));
double NH = N + height;
X = NH * COSLAT * COSLONG;
Y = NH * COSLAT * SINLONG;
Z = (b * b * N / (a * a) + height) * SINLAT;
return new double[]{X, Y, Z};
}
/**
* 地心坐标系转WGS84
*/
public static String ECEFtoWGS84(double x, double y, double z) {
double a, b, c, d;
double Longitude;// 经度
double Latitude;// 纬度
double Altitude;// 海拔高度
double p, q;
double N;
a = 6378137.0;
b = 6356752.31424518;
c = Math.sqrt(((a * a) - (b * b)) / (a * a));
d = Math.sqrt(((a * a) - (b * b)) / (b * b));
p = Math.sqrt((x * x) + (y * y));
q = Math.atan2((z * a), (p * b));
Longitude = Math.atan2(y, x);
Latitude = Math.atan2((z + (d * d) * b * Math.pow(Math.sin(q), 3)),
(p - (c * c) * a * Math.pow(Math.cos(q), 3)));
N = a / Math.sqrt(1 - ((c * c) * Math.pow(Math.sin(Latitude), 2)));
Altitude = (p / Math.cos(Latitude)) - N;
Longitude = Longitude * 180.0 / Math.PI;
Latitude = Latitude * 180.0 / Math.PI;
return Longitude + "," + Latitude + "," + Altitude;
}
各个坐标的直接的转换
/**
* 描述:经纬度转换
* Created by cxb on 2018/5/24.
*/
public class LatLngTools {
public static final double a = 6378245.0;
public static final double ee = 0.00669342162296594323;
public static final double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
/**
* 手机GPS坐标转火星坐标
*
* @param wgLoc
* @return
*/
public static Lation transformFromWGSToGCJ(Lation wgLoc) {
//如果在国外,则默认不进行转换
if (outOfChina(wgLoc.lat, wgLoc.lon)) {
return new Lation(wgLoc.lat, wgLoc.lon);
}
double dLat = transformLat(wgLoc.lon - 105.0,
wgLoc.lat - 35.0);
double dLon = transformLon(wgLoc.lon - 105.0,
wgLoc.lat - 35.0);
double radLat = wgLoc.lat / 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 Lation(wgLoc.lat + dLat, wgLoc.lon + dLon);
}
//是否超出中国
public 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;
}
private 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 * 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;
}
private 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 * 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;
}
/**
* 地球坐标转换为火星坐标
* World Geodetic System ==> Mars Geodetic System
*
* @param wgLat 地球坐标
* @param wgLon
*/
public static Lation transform2Mars(double wgLat, double wgLon) {
Lation lation = new Lation();
if (outOfChina(wgLat, wgLon)) {
lation.lat = wgLat;
lation.lon = wgLon;
return lation;
}
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 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);
lation.lat = wgLat + dLat;
lation.lon = wgLon + dLon;
return lation;
}
/**
* 火星坐标转换为百度坐标
*
* @param gg_lat
* @param gg_lon
*/
public static Lation bd_encrypt(double gg_lat, double gg_lon) {
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);
Lation lation = new Lation();
lation.lon = z * Math.cos(theta) + 0.0065;
lation.lat = z * Math.sin(theta) + 0.006;
return lation;
}
/**
* 百度转火星
*
* @param bd_lat
* @param bd_lon
*/
public static Lation bd_decrypt(double bd_lat, double bd_lon) {
double x = bd_lon - 0.0065, 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);
Lation lation = new Lation();
lation.lon = z * Math.cos(theta);
lation.lat = z * Math.sin(theta);
return lation;
}
}
public class Lation {
double lat;
double lon;
//构造 set get
}