|
@@ -1,742 +0,0 @@
|
|
|
-package com.skyversation.poiaddr.util;
|
|
|
-
|
|
|
-import org.opengis.referencing.operation.Projection;
|
|
|
-import org.osgeo.proj4j.*;
|
|
|
-
|
|
|
-import java.lang.reflect.InvocationTargetException;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-public class CoordTransform {
|
|
|
-
|
|
|
- private final double x_PI = (Math.PI * 3000.0) / 180.0;
|
|
|
- private final double ee = 0.00669342162296594323;
|
|
|
- private final double a = 6378245.0;
|
|
|
-
|
|
|
-
|
|
|
- private final double BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0;
|
|
|
- private final double PI = Math.PI;
|
|
|
- private final double RADIUS = 6378245.0;
|
|
|
- private final double EE = 0.00669342162296594323;
|
|
|
-
|
|
|
-
|
|
|
- // 定义常量
|
|
|
- private final double A = 6378245.0;
|
|
|
-
|
|
|
- public enum Projs {
|
|
|
- WGS84, GCJ02, BD09, UTM4, SHCJ, METER, DEGREE
|
|
|
- }
|
|
|
-
|
|
|
- public enum EPSG {
|
|
|
- WGS84("+proj=longlat +datum=WGS84 +no_defs"),
|
|
|
- MERCATOR("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"),
|
|
|
- GAUSS_KRUGER("+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
|
|
|
-
|
|
|
- private final String projString;
|
|
|
-
|
|
|
- EPSG(String projString) {
|
|
|
- this.projString = projString;
|
|
|
- }
|
|
|
-
|
|
|
- public String getProjString() {
|
|
|
- return projString;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static boolean outOfSh(double lng, double lat){
|
|
|
- lat += lat;
|
|
|
- lng +=lng;
|
|
|
- return !(lng > 115.487 && lng < 123.696 && lat > 28.260 && lat < 33.521);
|
|
|
- }
|
|
|
-
|
|
|
- private static CoordTransform instance = new CoordTransform();
|
|
|
- CoordTransform(){}
|
|
|
- public static CoordTransform getInstance(){
|
|
|
- if(instance == null) {
|
|
|
- instance = new CoordTransform();
|
|
|
- }
|
|
|
- return instance;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 定义投影字典
|
|
|
- private static final List<Projection> projs = new ArrayList<>();
|
|
|
-
|
|
|
- // 定义坐标转换方法
|
|
|
- public double[] wgs84ToShcj(double x, double y) {
|
|
|
- if (outOfChina(x, y)) {
|
|
|
- return new double[]{x, y};
|
|
|
- } else {
|
|
|
- double[] dlatLng = transformLatLng(x - 105.0, y - 35.0);
|
|
|
- double radLat = (y / 180.0) * PI;
|
|
|
- double magic = Math.sin(radLat);
|
|
|
- magic = 1 - ee * magic * magic;
|
|
|
- double sqrtMagic = Math.sqrt(magic);
|
|
|
- dlatLng[0] = (dlatLng[0] * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
|
|
|
- dlatLng[1] = (dlatLng[1] * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
|
|
|
- double mglat = y + dlatLng[0];
|
|
|
- double mglng = x + dlatLng[1];
|
|
|
- return new double[]{mglng, mglat};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 定义坐标转换方法
|
|
|
- public double[] gcj02ToWgs84(double x, double y) {
|
|
|
- if (outOfChina(x, y)) {
|
|
|
- return new double[]{x, y};
|
|
|
- } else {
|
|
|
- double[] dlatLng = transformLatLng(x - 105.0, y - 35.0);
|
|
|
- double radLat = (y / 180.0) * PI;
|
|
|
- double magic = Math.sin(radLat);
|
|
|
- magic = 1 - ee * magic * magic;
|
|
|
- double sqrtMagic = Math.sqrt(magic);
|
|
|
- dlatLng[0] = (dlatLng[0] * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
|
|
|
- dlatLng[1] = (dlatLng[1] * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
|
|
|
- double mglat = y + dlatLng[0];
|
|
|
- double mglng = x + dlatLng[1];
|
|
|
- return new double[]{x * 2 - mglng, y * 2 - mglat};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 定义判断是否在中国境内的方法
|
|
|
- public boolean outOfChina(double x, double y) {
|
|
|
- // 纬度 3.86~53.55,经度 73.66~135.05
|
|
|
- return!(x > 73.66 && x < 135.05 && y > 3.86 && y < 53.55);
|
|
|
- }
|
|
|
-
|
|
|
- // 定义坐标转换方法
|
|
|
- public double[] transformLatLng(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 new double[]{ret, ret};
|
|
|
- }
|
|
|
-
|
|
|
- // 定义经纬度转米的方法
|
|
|
- public double[] degreeToMeter(double x, double y) {
|
|
|
- double lon = (x * 20037508.34) / 180;
|
|
|
- double lat = Math.log(Math.tan(((90 + y) * PI) / 360)) / (PI / 180);
|
|
|
- lat = (lat * 20037508.34) / 180;
|
|
|
- return new double[]{lon, lat};
|
|
|
- }
|
|
|
-
|
|
|
- // 定义米转经纬度的方法
|
|
|
- public double[] meterToDegree(double x, double y) {
|
|
|
- double lon = (x / 20037508.34) * 180;
|
|
|
- double lat = (y / 20037508.34) * 180;
|
|
|
- lat = (180 / PI) * (2 * Math.atan(Math.exp((lat * PI) / 180)) - PI / 2);
|
|
|
- return new double[]{lon, lat};
|
|
|
- }
|
|
|
-
|
|
|
- // 定义 WGS84 坐标转上海城建的方法
|
|
|
- public double[] wgs84ToShcj2(double x, double y) {
|
|
|
- double[] xy = shcjGetUTMFromWGS(x, y);
|
|
|
- return utmToShcj4(xy[0], xy[1]);
|
|
|
- }
|
|
|
-
|
|
|
- // 定义 UTM 转上海城建的方法
|
|
|
- public double[] utmToShcj4(double x, double y) {
|
|
|
- double DX = -500199.29965;
|
|
|
- double DY = -3457078.805985;
|
|
|
- double T = 0.0000001755;
|
|
|
- double K = 1.0004000106;
|
|
|
- return covertByFourParm(x, y, DX, DY, T, K);
|
|
|
- }
|
|
|
-
|
|
|
- // 定义上海城建坐标转 UTM 的方法
|
|
|
- public double[] shcjGetUTMFromWGS(double lon, double lat) {
|
|
|
- double a = 6378137;
|
|
|
- double b = 6356752.3142451;
|
|
|
- double f = (a - b) / a;
|
|
|
-
|
|
|
- double eSquare = 2 * f - f * f;
|
|
|
- double k0 = 0.9996;
|
|
|
- double lonOrigin = 121.46714714;
|
|
|
- double FN = 0;
|
|
|
- // # 确保 longtitude 位于-180.00----179.9 之间
|
|
|
- double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
|
|
|
- double latRad = (lat * PI) / 180;
|
|
|
- double lonRad = (lonTemp * PI) / 180;
|
|
|
- double lonOriginRad = (lonOrigin * PI) / 180;
|
|
|
- double e2Square = eSquare / (1 - eSquare);
|
|
|
-
|
|
|
- double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
|
|
|
- double T = Math.pow(Math.tan(latRad), 2);
|
|
|
- double C = e2Square * Math.pow(Math.cos(latRad), 2);
|
|
|
- double A = Math.cos(latRad) * (lonRad - lonOriginRad);
|
|
|
- double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad - ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(2 * latRad) + ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(4 * latRad) - ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
|
|
|
-
|
|
|
- // # x
|
|
|
- double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 + ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
|
|
|
- // # y
|
|
|
- double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 + ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 + ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
|
|
|
- //# 南半球纬度起点为 10000000.0m
|
|
|
- UTMNorthing += FN;
|
|
|
- double[] xy = new double[2];
|
|
|
- xy[0] = UTMEasting;
|
|
|
- xy[1] = UTMNorthing;
|
|
|
- return xy;
|
|
|
- }
|
|
|
-
|
|
|
- // 定义上海城建坐标转 WGS84 的方法
|
|
|
- public double[] shcjToWgs84(double x, double y) {
|
|
|
- double[] xy = shcjToUtm4(x, y);
|
|
|
- return shcjGetWGSFromUTM(xy[0], xy[1]);
|
|
|
- }
|
|
|
-
|
|
|
- // 定义上海城建坐标转 UTM 的方法
|
|
|
- public double[] shcjToUtm4(double x, double y) {
|
|
|
- double DX = 499999.90104;
|
|
|
- double DY = 3455696.403019;
|
|
|
- double T = -0.0000001755;
|
|
|
- double K = 0.999600149344;
|
|
|
- return covertByFourParm(x, y, DX, DY, T, K);
|
|
|
- }
|
|
|
-
|
|
|
- // 定义四参数公式
|
|
|
- public double[] covertByFourParm(double x, double y, double dx, double dy, double a, double k) {
|
|
|
- double px = 0;
|
|
|
- double py = 0;
|
|
|
- px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
|
|
|
- py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
|
|
|
- double[] xy = new double[2];
|
|
|
- xy[0] = px;
|
|
|
- xy[1] = py;
|
|
|
- return xy;
|
|
|
- }
|
|
|
-
|
|
|
- // 定义上海城建坐标转 WGS84 的方法
|
|
|
- public double[] shcjGetWGSFromUTM(double x, double y) {
|
|
|
- // WGS84
|
|
|
- double a = 6378137; // 椭球体长半轴
|
|
|
- double b = 6356752.3142451; // 椭球体短半轴
|
|
|
- x = 500000 - x;
|
|
|
- double k0 = 0.9996;
|
|
|
- double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
|
|
|
- // # calculate the meridional arc
|
|
|
- double M = y / k0;
|
|
|
- //# calculate footprint latitude
|
|
|
- double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
|
|
|
- double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
|
|
|
- double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
|
|
|
- double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
|
|
|
- double J3 = (151 * Math.pow(e1, 3)) / 96;
|
|
|
- double J4 = (1097 * Math.pow(e1, 4)) / 512;
|
|
|
- double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
|
|
|
- // # Calculate Latitude and Longitude
|
|
|
- double e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2));
|
|
|
- double C1 = e2 * Math.pow(Math.cos(fp), 2);
|
|
|
- double T1 = Math.pow(Math.tan(fp), 2);
|
|
|
- double R1 = (a * (1 - Math.pow(e, 2))) / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2);
|
|
|
- //# This is the same as rho in the forward conversion formulas above, but calculated for fp instead of lat.
|
|
|
- double N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2);
|
|
|
- //# This is the same as nu in the forward conversion formulas above, but calculated for fp instead of lat.
|
|
|
- double D = x / (N1 * k0);
|
|
|
- double Q1 = (N1 * Math.tan(fp)) / R1;
|
|
|
- double Q2 = Math.pow(D, 2) / 2;
|
|
|
- double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
|
|
|
- double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
|
|
|
- double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
|
|
|
- // System.out.println("lat===="+Math.toRadians(fp - Q1*(Q2 - Q3 + Q4)));
|
|
|
- double Q5 = D;
|
|
|
- double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
|
|
|
- double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
|
|
|
- double lonMid = 121.46714714;
|
|
|
- double lon = lonMid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
|
|
|
- double[] xy = new double[2];
|
|
|
- xy[0] = lon;
|
|
|
- xy[1] = lat;
|
|
|
- return xy;
|
|
|
- }
|
|
|
-
|
|
|
- /***
|
|
|
- * 计算两个经纬度之间的距离,返回单位米
|
|
|
- * @param lat1
|
|
|
- * @param lon1
|
|
|
- * @param lat2
|
|
|
- * @param lon2
|
|
|
- * @return
|
|
|
- */
|
|
|
- public double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
|
|
|
- // 将经纬度转换为弧度
|
|
|
- double lat1Rad = Math.toRadians(lat1);
|
|
|
- double lon1Rad = Math.toRadians(lon1);
|
|
|
- double lat2Rad = Math.toRadians(lat2);
|
|
|
- double lon2Rad = Math.toRadians(lon2);
|
|
|
-
|
|
|
-// // 地球半径(单位:千米)
|
|
|
-// double earthRadius = 6371.0;
|
|
|
-
|
|
|
- // Haversine公式计算两点之间的距离
|
|
|
- double dLat = lat2Rad - lat1Rad;
|
|
|
- double dLon = lon2Rad - lon1Rad;
|
|
|
- double a = Math.pow(Math.sin(dLat / 2), 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.pow(Math.sin(dLon / 2), 2);
|
|
|
- double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
- double distance = 6378245.0 * c;
|
|
|
-
|
|
|
- return distance;
|
|
|
- }
|
|
|
-
|
|
|
- public boolean checkLatlon(double lat, double lon){
|
|
|
- if(lat >85 || lat < -85|| lon >180 || lon < -180){
|
|
|
- return false;
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] bd09_to_gcj02(double bd_lon, double bd_lat) {
|
|
|
- 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);
|
|
|
- return new double[]{gg_lng, gg_lat};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] gcj02_to_bd09(double lng, double lat) {
|
|
|
- double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
|
|
|
- double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
|
|
|
- double bd_lng = z * Math.cos(theta) + 0.0065;
|
|
|
- double bd_lat = z * Math.sin(theta) + 0.006;
|
|
|
- return new double[]{bd_lng, bd_lat};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] wgs84_to_gcj02(double lng, double lat) {
|
|
|
- if (out_of_china(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[]{mglng, mglat};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-// public double[] gcj02_to_wgs84(double lng, double lat) {
|
|
|
-// if (out_of_china(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};
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-// public boolean out_of_china(double lng, double lat) {
|
|
|
-// return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
|
|
|
-// }
|
|
|
-
|
|
|
-// public double transformlat(double lng, double lat) {
|
|
|
-// 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;
|
|
|
-// }
|
|
|
-//
|
|
|
-// public double transformlng(double lng, double lat) {
|
|
|
-// 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;
|
|
|
-// }
|
|
|
-
|
|
|
- public double[] degree_to_meter(double lng, double lat) {
|
|
|
- double x = (lng * 20037508.34) / 180;
|
|
|
- double y = Math.log(Math.tan(((90 + lat) * PI) / 360)) / (PI / 180);
|
|
|
- y = (y * 20037508.34) / 180;
|
|
|
- return new double[]{x, y};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] meter_to_degree(double x, double y) {
|
|
|
- double lon = (x / 20037508.34) * 180;
|
|
|
- double lat = (y / 20037508.34) * 180;
|
|
|
- lat = (180 / PI) * (2 * Math.atan(Math.exp((lat * PI) / 180)) - PI / 2);
|
|
|
- return new double[]{lon, lat};
|
|
|
- }
|
|
|
-
|
|
|
-// public double[] wgs84_to_shcj(double x, double y) {
|
|
|
-// double[] xy = new double[2];
|
|
|
-// xy = shcj_get_UTM_from_WGS(x, y);
|
|
|
-// return utm_to_shcj4(xy[0], xy[1]);
|
|
|
-// }
|
|
|
-
|
|
|
- public double[] utm_to_shcj4(double x, double y) {
|
|
|
- double DX = -500199.29965;
|
|
|
- double DY = -3457078.805985;
|
|
|
- double T = 0.0000001755;
|
|
|
- double K = 1.0004000106;
|
|
|
- return covert_by_four_parm(x, y, DX, DY, T, K);
|
|
|
- }
|
|
|
-
|
|
|
- public double[] shcj_get_UTM_from_WGS(double lon, double lat) {
|
|
|
- double a = 6378137;
|
|
|
- double b = 6356752.3142451;
|
|
|
- double f = (a - b) / a;
|
|
|
- double eSquare = 2 * f - f * f;
|
|
|
- double k0 = 0.9996;
|
|
|
- double lonOrigin = 121.46714714;
|
|
|
- double FN = 0;
|
|
|
- double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
|
|
|
- double latRad = (lat * PI) / 180;
|
|
|
- double lonRad = (lonTemp * PI) / 180;
|
|
|
- double lonOriginRad = (lonOrigin * PI) / 180;
|
|
|
- double e2Square = eSquare / (1 - eSquare);
|
|
|
- double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
|
|
|
- double T = Math.pow(Math.tan(latRad), 2);
|
|
|
- double C = e2Square * Math.pow(Math.cos(latRad), 2);
|
|
|
- double A = Math.cos(latRad) * (lonRad - lonOriginRad);
|
|
|
- double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad -
|
|
|
- ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) *
|
|
|
- Math.sin(2 * latRad) +
|
|
|
- ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) *
|
|
|
- Math.sin(4 * latRad) -
|
|
|
- ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
|
|
|
- double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 +
|
|
|
- ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
|
|
|
- double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 +
|
|
|
- ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 +
|
|
|
- ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
|
|
|
- UTMNorthing += FN;
|
|
|
- return new double[]{UTMEasting, UTMNorthing};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] shcj_to_wgs84(double x, double y) {
|
|
|
- double[] xy = new double[2];
|
|
|
- xy = shcj_to_utm4(x, y);
|
|
|
- return shcj_get_WGS_from_UTM(xy[0], xy[1]);
|
|
|
- }
|
|
|
-
|
|
|
- public double[] shcj_to_utm4(double x, double y) {
|
|
|
- double DX = 499999.90104;
|
|
|
- double DY = 3455696.403019;
|
|
|
- double T = -0.0000001755;
|
|
|
- double K = 0.999600149344;
|
|
|
- return covert_by_four_parm(x, y, DX, DY, T, K);
|
|
|
- }
|
|
|
-
|
|
|
- public double[] covert_by_four_parm(double x, double y, double dx, double dy, double a, double k) {
|
|
|
- double px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
|
|
|
- double py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
|
|
|
- return new double[]{px, py};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] shcj_get_WGS_from_UTM(double x, double y) {
|
|
|
- double a = 6378137;
|
|
|
- double b = 6356752.3142451;
|
|
|
- x = 500000 - x;
|
|
|
- double k0 = 0.9996;
|
|
|
- double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
|
|
|
- double M = y / k0;
|
|
|
- double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
|
|
|
- double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
|
|
|
- double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
|
|
|
- double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
|
|
|
- double J3 = (151 * Math.pow(e1, 3)) / 96;
|
|
|
- double J4 = (1097 * Math.pow(e1, 4)) / 512;
|
|
|
- double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
|
|
|
- double e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2));
|
|
|
- double C1 = e2 * Math.pow(Math.cos(fp), 2);
|
|
|
- double T1 = Math.pow(Math.tan(fp), 2);
|
|
|
- double R1 = (a * (1 - Math.pow(e, 2))) / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2);
|
|
|
- double N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2);
|
|
|
- double D = x / (N1 * k0);
|
|
|
- double Q1 = (N1 * Math.tan(fp)) / R1;
|
|
|
- double Q2 = Math.pow(D, 2) / 2;
|
|
|
- double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
|
|
|
- double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
|
|
|
- double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
|
|
|
- double Q5 = D;
|
|
|
- double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
|
|
|
- double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
|
|
|
- double lonmid = 121.46714714;
|
|
|
- double lon = lonmid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
|
|
|
- return new double[]{lon, lat};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] wgs84_to_bd09(double x, double y) {
|
|
|
- double[] ll = wgs84_to_gcj02(x, y);
|
|
|
- ll = gcj02_to_bd09(ll[0], ll[1]);
|
|
|
- return ll;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] bd09_to_wgs84(double x, double y) {
|
|
|
- double[] ll = bd09_to_gcj02(x, y);
|
|
|
- ll = gcj02_to_wgs84(ll[0], ll[1]);
|
|
|
- return ll;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] gcj02_to_shcj(double x, double y) {
|
|
|
- double[] ll = gcj02_to_wgs84(x, y);
|
|
|
- ll = wgs84_to_shcj(ll[0], ll[1]);
|
|
|
- return ll;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] shcj_to_gcj02(double x, double y) {
|
|
|
- double[] ll = shcj_to_wgs84(x, y);
|
|
|
- ll = wgs84_to_gcj02(ll[0], ll[1]);
|
|
|
- return ll;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] convert_proj_from_to(Projs from, Projs to, double[] xy) {
|
|
|
- if (from == to) {
|
|
|
- return xy;
|
|
|
- } else {
|
|
|
- String fromProj = from.toString().toLowerCase();
|
|
|
- String toProj = to.toString().toLowerCase();
|
|
|
- String targetMethod = fromProj + "_to_" + toProj;
|
|
|
- try {
|
|
|
- return (double[]) this.getClass().getMethod(targetMethod, double.class, double.class).invoke(this, xy[0], xy[1]);
|
|
|
- } catch (IllegalAccessException e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- } catch (InvocationTargetException e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- } catch (NoSuchMethodException e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public double[] WGS84ToSH2000(double lng, double lat) {
|
|
|
- if (out_of_sh(lng, lat)) {
|
|
|
- return new double[]{lng, lat};
|
|
|
- } else {
|
|
|
- double[] templatlng = wgs84_to_shcj(lng, lat);
|
|
|
- templatlng = meter_to_degree(templatlng[0], templatlng[1]);
|
|
|
- return new double[]{templatlng[0], templatlng[1]};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public double[] SH2000ToWGS84(double x, double y) {
|
|
|
- double[] templatlng = meter_to_degree(x, y);
|
|
|
- if (out_of_sh2000(templatlng[0], templatlng[1])) {
|
|
|
- return new double[]{x, y};
|
|
|
- } else {
|
|
|
- templatlng = shcj_to_wgs84(x, y);
|
|
|
- return templatlng;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public double[] SH2000lnglatToWGS84(double lng, double lat) {
|
|
|
- if (out_of_sh2000(lng, lat)) {
|
|
|
- return new double[]{lng, lat};
|
|
|
- } else {
|
|
|
- double[] templatlng = degree_to_meter(lng, lat);
|
|
|
- templatlng = shcj_to_wgs84(templatlng[0], templatlng[1]);
|
|
|
- return templatlng;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private boolean out_of_sh(double lng, double lat) {
|
|
|
- // 实现out_of_sh方法
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- private boolean out_of_sh2000(double lng, double lat) {
|
|
|
- // 实现out_of_sh2000方法
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] wgs84_to_shcj(double x, double y) {
|
|
|
- double[] xy = new double[2];
|
|
|
- xy = shcj_get_UTM_from_WGS(x, y);
|
|
|
- return utm_to_shcj4(xy[0], xy[1]);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public double[] BD09ToGCJ02(double lng, double lat) {
|
|
|
- double x = lng - 0.0065;
|
|
|
- double y = lat - 0.006;
|
|
|
- double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR);
|
|
|
- double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR);
|
|
|
- double gg_lng = z * Math.cos(theta);
|
|
|
- double gg_lat = z * Math.sin(theta);
|
|
|
- return new double[]{gg_lng, gg_lat};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] GCJ02ToBD09(double lng, double lat) {
|
|
|
- lat = +lat;
|
|
|
- lng = +lng;
|
|
|
- double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR);
|
|
|
- double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR);
|
|
|
- double bd_lng = z * Math.cos(theta) + 0.0065;
|
|
|
- double bd_lat = z * Math.sin(theta) + 0.006;
|
|
|
- return new double[]{bd_lng, bd_lat};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] WGS84ToBD09(double lng, double lat) {
|
|
|
- double[] GCJ02latlng = WGS84ToGCJ02(lng, lat);
|
|
|
- double[] BD09latlng = GCJ02ToBD09(GCJ02latlng[0], GCJ02latlng[1]);
|
|
|
- return BD09latlng;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] BD09ToWGS84(double lng, double lat) {
|
|
|
- double[] GCJ02latlng = BD09ToGCJ02(lng, lat);
|
|
|
- double[] wgslatlng = GCJ02ToWGS84(GCJ02latlng[0], GCJ02latlng[1]);
|
|
|
- return wgslatlng;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] WGS84ToGCJ02(double lng, double lat) {
|
|
|
- lat = +lat;
|
|
|
- lng = +lng;
|
|
|
- if (out_of_china(lng, lat)) {
|
|
|
- return new double[]{lng, lat};
|
|
|
- } else {
|
|
|
- double[] d = delta(lng, lat);
|
|
|
- return new double[]{lng + d[0], lat + d[1]};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public double[] GCJ02ToWGS84(double lng, double lat) {
|
|
|
- lat = +lat;
|
|
|
- lng = +lng;
|
|
|
- if (out_of_china(lng, lat)) {
|
|
|
- return new double[]{lng, lat};
|
|
|
- } else {
|
|
|
- double[] d = delta(lng, lat);
|
|
|
- double mgLng = lng + d[0];
|
|
|
- double mgLat = lat + d[1];
|
|
|
- return new double[]{lng * 2 - mgLng, lat * 2 - mgLat};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private double[] delta(double lng, double lat) {
|
|
|
- double dLng = transformLng(lng - 105, lat - 35);
|
|
|
- double dLat = transformLat(lng - 105, lat - 35);
|
|
|
- double radLat = (lat / 180) * PI;
|
|
|
- double magic = Math.sin(radLat);
|
|
|
- magic = 1 - EE * magic * magic;
|
|
|
- double sqrtMagic = Math.sqrt(magic);
|
|
|
- dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI);
|
|
|
- dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI);
|
|
|
- return new double[]{dLng, dLat};
|
|
|
- }
|
|
|
-
|
|
|
- private 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;
|
|
|
- }
|
|
|
-
|
|
|
- private 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;
|
|
|
- }
|
|
|
-
|
|
|
- private boolean out_of_china(double lng, double lat) {
|
|
|
- lat = +lat;
|
|
|
- lng = +lng;
|
|
|
- return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
|
|
|
- }
|
|
|
-
|
|
|
- private CRSFactory crsFactory = new CRSFactory();
|
|
|
-
|
|
|
- // 定义84坐标系
|
|
|
- private String wgs84Str = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
|
|
|
- // private CoordinateReferenceSystem wgs84 = crsFactory.createFromParameters(
|
|
|
-// "WGS84", wgs84Str);
|
|
|
- private CoordinateReferenceSystem wgs84 =
|
|
|
- crsFactory.createFromName("EPSG:4326");
|
|
|
-
|
|
|
- // 定义CGCS2000坐标系
|
|
|
- private String cgcs2000Str = "+proj=utm +zone=50 +ellps=GRS80 +units=m +no_defs";
|
|
|
- // private CoordinateReferenceSystem cgcs2000 = crsFactory.createFromParameters(
|
|
|
-// "CGCS2000", cgcs2000Str);
|
|
|
- private CoordinateReferenceSystem cgcs2000 =
|
|
|
- crsFactory.createFromName("EPSG:4490");
|
|
|
-
|
|
|
- public double[] gcj02_to_wgs84(double lng, double lat) {
|
|
|
- if (out_of_china(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) * 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);
|
|
|
- dlng = (dlng * 180.0) / ((A / sqrtmagic) * Math.cos(radlat) * Math.PI);
|
|
|
- double mglat = lat + dlat;
|
|
|
- double mglng = lng + dlng;
|
|
|
- return new double[]{lng * 2 - mglng, lat * 2 - mglat};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public double transformlng(double lng, double lat) {
|
|
|
- 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 * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
|
|
|
- ret += ((20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin((lng / 3.0) * Math.PI)) * 2.0) / 3.0;
|
|
|
- ret += ((150.0 * Math.sin((lng / 12.0) * Math.PI) + 300.0 * Math.sin((lng / 30.0) * Math.PI)) * 2.0) / 3.0;
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- public double transformlat(double lng, double lat) {
|
|
|
- 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 * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
|
|
|
- ret += ((20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin((lat / 3.0) * Math.PI)) * 2.0) / 3.0;
|
|
|
- ret += ((160.0 * Math.sin((lat / 12.0) * Math.PI) + 320 * Math.sin((lat * Math.PI) / 30.0)) * 2.0) / 3.0;
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- public double[] wgs84ToCGCS2000(double lng, double lat) {
|
|
|
-
|
|
|
- // 定义WGS84坐标点
|
|
|
- ProjCoordinate wgs84Point = new ProjCoordinate(lng, lat);
|
|
|
-
|
|
|
- // 将WGS84坐标点转换为CGCS2000坐标点
|
|
|
- ProjCoordinate cgcs2000Point = new ProjCoordinate();
|
|
|
-
|
|
|
- // 创建坐标转换器
|
|
|
- CoordinateTransformFactory ctf = new CoordinateTransformFactory();
|
|
|
- CoordinateTransform transform = ctf.createTransform(wgs84, cgcs2000);
|
|
|
-
|
|
|
- transform.transform(wgs84Point, cgcs2000Point);
|
|
|
- System.out.println(cgcs2000Point.x + "," + cgcs2000Point.y);
|
|
|
- return new double[]{cgcs2000Point.x, cgcs2000Point.y};
|
|
|
- }
|
|
|
-
|
|
|
- public double[] cgcs2000ToWGS84(double lng, double lat) {
|
|
|
- // 定义CGCS2000坐标点
|
|
|
- ProjCoordinate cgcs2000Point = new ProjCoordinate(lng, lat);
|
|
|
-
|
|
|
- // 将CGCS2000坐标点转换为WGS84坐标点
|
|
|
- ProjCoordinate wgs84Point = new ProjCoordinate();
|
|
|
-
|
|
|
- // 创建坐标转换器
|
|
|
- CoordinateTransformFactory ctf = new CoordinateTransformFactory();
|
|
|
- CoordinateTransform transform = ctf.createTransform(cgcs2000, wgs84);
|
|
|
-
|
|
|
- transform.transform(cgcs2000Point, wgs84Point);
|
|
|
- System.out.println(wgs84Point.x + "," + wgs84Point.y);
|
|
|
- return new double[]{wgs84Point.x, wgs84Point.y};
|
|
|
- }
|
|
|
-
|
|
|
-}
|