常用 bd09、wgs84、gcj02 以及广州2000 坐标系互转
/**
* 坐标转换
*
* @author maofs
* @version 1.0
* @date 2021 -04-26 11:45:13
*/
public interface ICoordTransformService {
/**
* The constant x_PI.
*/
Double XPI = 3.14159265358979324 * 3000.0 / 180.0;
/**
* The constant PI.
*/
Double PI = 3.1415926535897932384626;
/**
* The constant a.
*/
Double A = 6378245.0;
/**
* The constant ee.
*/
Double EE = 0.00669342162296594323;
/**
* The constant T2345_TO_GZ2000_X.
*/
Double T2345_TO_GZ2000_X = -374151.464765618;
/**
* The constant T2345_TO_GZ2000_Y.
*/
Double T2345_TO_GZ2000_Y = -2331890.52174604;
/**
* The constant T2345_TO_GZ2000_M.
*/
Double T2345_TO_GZ2000_M = -3.59216301315524E-06;
/**
* The constant T2345_TO_GZ2000_R.
*/
Double T2345_TO_GZ2000_R = 0.00484909724486718;
/**
* The constant GZ2000_TO_2435_X.
*/
Double GZ2000_TO_2435_X = 385455.970368639;
/**
* The constant GZ2000_TO_2435_Y.
*/
Double GZ2000_TO_2435_Y = 2330057.18710631;
/**
* The constant GZ2000_TO_2435_M.
*/
Double GZ2000_TO_2435_M = 3.58872253802822E-06;
/**
* The constant GZ2000_TO_2435_R.
*/
Double GZ2000_TO_2435_R = -0.00484909724489578;
/**
* Bd 09 to gcj 02 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] bd09ToGcj02(Double lng, Double lat);
/**
* Bd 09 to wgs 84 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] bd09ToWgs84(Double lng, Double lat);
/**
* Bd 09 to gz 2000 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] bd09ToGz2000(Double lng, Double lat);
/**
* Gcj 02 to bd 09 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gcj02ToBd09(Double lng, Double lat);
/**
* Gcj 02 to wgs 84 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gcj02ToWgs84(Double lng, Double lat);
/**
* Gcj 02 to gz 2000 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gcj02ToGz2000(Double lng, Double lat);
/**
* Wgs 84 to gcj 02 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] wgs84ToGcj02(Double lng, Double lat);
/**
* Wgs 84 to bd 09 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] wgs84ToBd09(Double lng, Double lat);
/**
* Wgs 84 to gz 2000 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] wgs84ToGz2000(Double lng, Double lat);
/**
* Gz 2000 to wgs 84 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gz2000ToWgs84(Double lng, Double lat);
/**
* Gz 2000 to bd 09 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gz2000ToBd09(Double lng, Double lat);
/**
* Gz 2000 to gcj 02 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
Double[] gz2000ToGcj02(Double lng, Double lat);
/**
* Transform lat double.
*
* @param lng the lng
* @param lat the lat
* @return the double
*/
default Double transformLat(Double lng, Double lat) {
lat = +lat;
lng = +lng;
double ret =
-100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret;
}
/**
* Transform lng double.
*
* @param lng the lng
* @param lat the lat
* @return the double
*/
default Double transformLng(Double lng, Double lat) {
lat = +lat;
lng = +lng;
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret;
}
/**
* 判断是否在国内,不在国内则不做偏移
*
* @param lng the lng
* @param lat the lat
* @return the boolean
*/
default boolean outOfChina(Double lng, Double lat) {
lat = +lat;
lng = +lng;
// 纬度 3.86~53.55, 经度 73.66~135.05
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
}
/**
* Wgs 84 to 2435 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
default Double[] wgs84To2435(Double lng, Double lat) {
CRSFactory crsFactory = new CRSFactory();
//源坐标系统
String sourceCrs = "wgs84";
String sourceCrsParams = "+proj=longlat +datum=WGS84 +no_defs ";
CoordinateReferenceSystem source = crsFactory.createFromParameters(sourceCrs, sourceCrsParams);
//目标坐标系统
String targetCrs = "2435";
String targetCrsParams = "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +towgs84=15.8,-154.4,-82.3 +ellps=krass +units=m +no_defs ";
CoordinateReferenceSystem target = crsFactory.createFromParameters(targetCrs, targetCrsParams);
//定义转换类WGS84转2436
CoordinateTransformFactory ctf = new CoordinateTransformFactory();
CoordinateTransform transform = ctf.createTransform(source, target);
//WGS84坐标系转换
ProjCoordinate projCoordinate = new ProjCoordinate(lng, lat);
transform.transform(projCoordinate, projCoordinate);
double x1 = projCoordinate.x;
double y1 = projCoordinate.y;
return new Double[]{x1, y1};
}
/**
* Gz 2000 to 2345 double [ ].
*
* @param lng the lng
* @param lat the lat
* @return the double [ ]
*/
default Double[] t2435ToWgs84(Double lng, Double lat) {
CRSFactory crsFactory = new CRSFactory();
//目标坐标系统
String targetCrs = "wgs84";
String targetCrsParams = "+proj=longlat +datum=WGS84 +no_defs ";
CoordinateReferenceSystem target = crsFactory.createFromParameters(targetCrs, targetCrsParams);
//源坐标系统
String sourceCrs = "2435";
String sourceCrsParams = "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +towgs84=15.8,-154.4,-82.3 +ellps=krass +units=m +no_defs ";
CoordinateReferenceSystem source = crsFactory.createFromParameters(sourceCrs, sourceCrsParams);
//定义转换类2436转WGS84
CoordinateTransformFactory ctf = new CoordinateTransformFactory();
CoordinateTransform transform = ctf.createTransform(source, target);
//WGS84坐标系转换
ProjCoordinate projCoordinate = new ProjCoordinate(lng, lat);
transform.transform(projCoordinate, projCoordinate);
double x1 = projCoordinate.x;
double y1 = projCoordinate.y;
return new Double[]{x1, y1};
}
}
/**
* 坐标转换
*
* @author maofs
* @version 1.0
* @date 2021 -04-26 11:45:13
*/
public class CoordTransformServiceImpl implements ICoordTransformService {
/**
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02) 的转换 即 百度 转 谷歌、高德
*
* @param bdLng 经度
* @param bdLat 纬度
* @return the double [ ]
*/
@Override
public Double[] bd09ToGcj02(Double bdLng, Double bdLat) {
bdLng = +bdLng;
bdLat = +bdLat;
Double x = bdLng - 0.0065;
Double y = bdLat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * XPI);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * XPI);
double gcLng = z * Math.cos(theta);
double gcLat = z * Math.sin(theta);
return new Double[]{gcLng, gcLat};
}
/**
* 百度坐标系 (BD-09) 与 WGS-84的转换
*
* @param bdLng 经度
* @param bdLat 纬度
* @return the double [ ]
*/
@Override
public Double[] bd09ToWgs84(Double bdLng, Double bdLat) {
Double[] gcDoubles = bd09ToGcj02(bdLng, bdLat);
return gcj02ToWgs84(gcDoubles[0], gcDoubles[1]);
}
/**
* 百度坐标系 (BD-09) 与 GZ2000的转换
*
* @param bdLng 经度
* @param bdLat 纬度
* @return the double [ ]
*/
@Override
public Double[] bd09ToGz2000(Double bdLng, Double bdLat) {
Double[] doubles = bd09ToWgs84(bdLng, bdLat);
return wgs84ToGz2000(doubles[0], doubles[1]);
}
/**
* WGS-84 转 BD09
*
* @param wgLng 经度
* @param wgLat 纬度
* @return the double [ ]
*/
@Override
public Double[] wgs84ToBd09(Double wgLng, Double wgLat) {
Double[] doubles = wgs84ToGcj02(wgLng, wgLat);
return gcj02ToBd09(doubles[0], doubles[1]);
}
/**
* WGS-84 转 GZ2000
*
* @param wgLng 经度
* @param wgLat 纬度
* @return the double [ ]
*/
@Override
public Double[] wgs84ToGz2000(Double wgLng, Double wgLat) {
Double[] doubles = wgs84To2435(wgLng, wgLat);
Double lng = doubles[0];
Double lat = doubles[1];
double x = T2345_TO_GZ2000_X + (1 + T2345_TO_GZ2000_M) * (Math.cos(T2345_TO_GZ2000_R) * lng - Math.sin(T2345_TO_GZ2000_R) * lat);
double y = T2345_TO_GZ2000_Y + (1 + T2345_TO_GZ2000_M) * (Math.sin(T2345_TO_GZ2000_R) * lng + Math.cos(T2345_TO_GZ2000_R) * lat);
return new Double[]{x, y};
/* CoordDTO coordDTO = null;
try {
coordDTO = gz2000ApiService.wsg84ToGz2000(wgLng, wgLat, tokens);
} catch (Exception e) {
e.printStackTrace();
Assert.isTrue(false, e.getMessage());
}
return new Double[] {coordDTO.getX(), coordDTO.getY()};*/
}
/**
* WGS-84 转 GCJ-02
*
* @param wgLng 经度
* @param wgLat 纬度
* @return the double [ ]
*/
@Override
public Double[] wgs84ToGcj02(Double wgLng, Double wgLat) {
double lat = +wgLat;
double lng = +wgLng;
if (outOfChina(lng, lat)) {
return new Double[]{lng, lat};
} else {
double dlat = transformLat(lng - 105.0, lat - 35.0);
double dlng = transformLng(lng - 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);
dlng = (dlng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI);
double gcLat = lat + dlat;
double gcLng = lng + dlng;
return new Double[]{gcLng, gcLat};
}
}
/**
* 火星坐标系 (GCJ-02) 与 BD09 的转换
*
* @param gcLng 经度
* @param gcLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gcj02ToBd09(Double gcLng, Double gcLat) {
double lat = +gcLat;
double lng = +gcLng;
double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * XPI);
double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * XPI);
double bdLng = z * Math.cos(theta) + 0.0065;
double bdLat = z * Math.sin(theta) + 0.006;
return new Double[]{bdLng, bdLat};
}
/**
* GCJ-02 转换为 WGS-84
*
* @param gcLng 经度
* @param gcLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gcj02ToWgs84(Double gcLng, Double gcLat) {
double lat = +gcLat;
double lng = +gcLng;
if (outOfChina(lng, lat)) {
return new Double[]{lng, lat};
} else {
double dlat = transformLat(lng - 105.0, lat - 35.0);
double dlng = transformLng(lng - 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);
dlng = (dlng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI);
double mgLat = lat + dlat;
double mgLng = lng + dlng;
return new Double[]{lng * 2 - mgLng, lat * 2 - mgLat};
}
}
/**
* GCJ-02 转换为 gz2000
*
* @param gcLng 经度
* @param gcLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gcj02ToGz2000(Double gcLng, Double gcLat) {
Double[] doubles = gcj02ToWgs84(gcLng, gcLat);
return wgs84ToGz2000(doubles[0], doubles[1]);
}
/**
* Gz2000 to Wgs84
*
* @param gzLng 经度
* @param gzLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gz2000ToWgs84(Double gzLng, Double gzLat) {
double x = GZ2000_TO_2435_X + (1 + GZ2000_TO_2435_M) * (Math.cos(GZ2000_TO_2435_R) * gzLng - Math.sin(GZ2000_TO_2435_R) * gzLat);
double y = GZ2000_TO_2435_Y + (1 + GZ2000_TO_2435_M) * (Math.sin(GZ2000_TO_2435_R) * gzLng + Math.cos(GZ2000_TO_2435_R) * gzLat);
return t2435ToWgs84(x, y);
/* CoordDTO coordDTO = gz2000ApiService.gz2000ToWsg84(gzLng, gzLat, tokens);
return new Double[]{coordDTO.getX(), coordDTO.getY()};*/
}
/**
* Gz2000 to Wgs84
*
* @param gzLng 经度
* @param gzLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gz2000ToBd09(Double gzLng, Double gzLat) {
Double[] doubles = gz2000ToWgs84(gzLng, gzLat);
return wgs84ToBd09(doubles[0], doubles[1]);
}
/**
* Gz2000 to Gcj02
*
* @param gzLng 经度
* @param gzLat 纬度
* @return the double [ ]
*/
@Override
public Double[] gz2000ToGcj02(Double gzLng, Double gzLat) {
Double[] doubles = gz2000ToWgs84(gzLng, gzLat);
return wgs84ToGcj02(doubles[0], doubles[1]);
}
}
版权声明:本文为weixin_43931248原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。