|
@@ -0,0 +1,163 @@
|
|
|
+package com.huashe.park.common.geo;
|
|
|
+
|
|
|
+import org.geotools.geometry.jts.JTS;
|
|
|
+import org.geotools.referencing.CRS;
|
|
|
+import org.locationtech.jts.geom.Coordinate;
|
|
|
+import org.opengis.referencing.FactoryException;
|
|
|
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|
|
+import org.opengis.referencing.operation.MathTransform;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.text.DecimalFormat;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public final class CoordinateUtil {
|
|
|
+ // 2000坐标转wgs84坐标
|
|
|
+ public static Double[] getCoordinate(Double x, Double y) {
|
|
|
+ Double[] res = new Double[2];
|
|
|
+ Coordinate tar = null;
|
|
|
+ try {
|
|
|
+ // 封装点,这个是通用的,也可以用POINT(y,x)
|
|
|
+ // private static WKTReader reader = new WKTReader( geometryFactory );
|
|
|
+ Coordinate sour = new Coordinate(y, x);
|
|
|
+ // 这里要选择转换的坐标系是可以随意更换的
|
|
|
+ CoordinateReferenceSystem source = CRS.decode("EPSG:4549");
|
|
|
+ CoordinateReferenceSystem target = CRS.decode("EPSG:4326");
|
|
|
+ // 建立转换,下面两个我屏掉的转换方式会报出需要3/7参数的异常
|
|
|
+ // MathTransform mathTransform = CRS.findMathTransform(source, target);
|
|
|
+ // MathTransform mathTransform1 = CRS.findMathTransform(source, target, false);
|
|
|
+ MathTransform transform = CRS.findMathTransform(source, target, true);
|
|
|
+ tar = new Coordinate();
|
|
|
+ // 转换
|
|
|
+ JTS.transform(sour, tar, transform);
|
|
|
+ }
|
|
|
+ catch (FactoryException | org.opengis.referencing.operation.TransformException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String[] split = (tar.toString().substring(1, tar.toString().length() - 1)).split(",");
|
|
|
+ // 经纬度精度
|
|
|
+ DecimalFormat fm = new DecimalFormat("0.0000000");
|
|
|
+ res[0] = Double.valueOf(fm.format(Double.valueOf(split[0])));
|
|
|
+ res[1] = Double.valueOf(fm.format(Double.valueOf(split[1])));
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * wgs84坐标转2000坐标
|
|
|
+ *
|
|
|
+ * @param B 纬度
|
|
|
+ * @param L 经度
|
|
|
+ * @param degree 角度,即所用的地图是几度的,列如CGCS2000_3_Degree_GK_CM_120E 表示该地 图是3度的
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map<String, Double> GetXY(double B, double L, double degree) {
|
|
|
+ Map<String, Double> map = new HashMap<>();
|
|
|
+ double[] xy = new double[] {
|
|
|
+ 0.0D, 0.0D
|
|
|
+ };
|
|
|
+ double a = 6378137.0D;
|
|
|
+ double b = 6356752.314245179D;
|
|
|
+ double e = 0.081819190842621D;
|
|
|
+ double eC = 0.0820944379496957D;
|
|
|
+ double L0 = 0.0D;
|
|
|
+ int n;
|
|
|
+ if (degree == 6.0D) {
|
|
|
+ n = (int) Math.round((L + degree / (double) 2) / degree);
|
|
|
+ L0 = degree * (double) n - degree / (double) 2;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ n = (int) Math.round(L / degree);
|
|
|
+ L0 = degree * (double) n;
|
|
|
+ }
|
|
|
+
|
|
|
+ double radB = B * 3.141592653589793D / (double) 180;
|
|
|
+ double radL = L * 3.141592653589793D / (double) 180;
|
|
|
+ double deltaL = (L - L0) * 3.141592653589793D / (double) 180;
|
|
|
+ double N = a * a / b / Math.sqrt((double) 1 + eC * eC * Math.cos(radB) * Math.cos(radB));
|
|
|
+ double C1 = 1.0D + 0.75D * e * e + 0.703125D * Math.pow(e, 4.0D) + 0.68359375D * Math.pow(e, 6.0D)
|
|
|
+ + 0.67291259765625D * Math.pow(e, 8.0D);
|
|
|
+ double C2 = 0.75D * e * e + 0.9375D * Math.pow(e, 4.0D) + 1.025390625D * Math.pow(e, 6.0D)
|
|
|
+ + 1.07666015625D * Math.pow(e, 8.0D);
|
|
|
+ double C3 = 0.234375D * Math.pow(e, 4.0D) + 0.41015625D * Math.pow(e, 6.0D)
|
|
|
+ + 0.538330078125D * Math.pow(e, 8.0D);
|
|
|
+ double C4 = 0.068359375D * Math.pow(e, 6.0D) + 0.15380859375D * Math.pow(e, 8.0D);
|
|
|
+ double C5 = 0.00240325927734375D * Math.pow(e, 8.0D);
|
|
|
+ double t = Math.tan(radB);
|
|
|
+ double eta = eC * Math.cos(radB);
|
|
|
+ double X = a * ((double) 1 - e * e)
|
|
|
+ * (C1 * radB - C2 * Math.sin((double) 2 * radB) / (double) 2 + C3 * Math.sin((double) 4 * radB) / (double) 4
|
|
|
+ - C4 * Math.sin((double) 6 * radB) / (double) 6 + C5 * Math.sin((double) 8 * radB));
|
|
|
+ xy[0] = X + N * Math.sin(radB) * Math.cos(radB) * Math.pow(deltaL, 2.0D)
|
|
|
+ * ((double) 1
|
|
|
+ + Math.pow(deltaL * Math.cos(radB), 2.0D)
|
|
|
+ * ((double) 5 - t * t + (double) 9 * eta * eta + (double) 4 * Math.pow(eta, 4.0D)) / (double) 12
|
|
|
+ + Math.pow(deltaL * Math.cos(radB), 4.0D) * ((double) 61 - (double) 58 * t * t + Math.pow(t, 4.0D))
|
|
|
+ / (double) 360)
|
|
|
+ / (double) 2;
|
|
|
+ xy[1] = N * deltaL * Math.cos(radB)
|
|
|
+ * ((double) 1 + Math.pow(deltaL * Math.cos(radB), 2.0D) * ((double) 1 - t * t + eta * eta) / (double) 6
|
|
|
+ + Math.pow(deltaL * Math.cos(radB), 4.0D) * ((double) 5 - (double) 18 * t * t + Math.pow(t, 4.0D)
|
|
|
+ - (double) 14 * eta * eta - (double) 58 * eta * eta * t * t) / (double) 120)
|
|
|
+ + (double) 500000;
|
|
|
+ // return "纬度Y:"+xy[0]+"---经度X"+xy[1];
|
|
|
+ map.put("X", xy[1]);
|
|
|
+ map.put("Y", xy[0]);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 度分秒地理位置转wgs84坐标
|
|
|
+ private String getPosition(String position) {
|
|
|
+ String[] degree = position.split("\\°");
|
|
|
+ if (degree.length == 1) {
|
|
|
+ return position;
|
|
|
+ }
|
|
|
+ String d = degree[0];
|
|
|
+ String[] one = degree[1].split("\\′");
|
|
|
+ String a = one[0];
|
|
|
+ if (!a.contains(".")) {
|
|
|
+ if (a.substring(0, 1).equals("0")) {
|
|
|
+ a = a.substring(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (a.contains(".") && a.split("\\.").length > 1) {
|
|
|
+ a = a.substring(1);
|
|
|
+ }
|
|
|
+ String[] two = one[1].split("\\″");
|
|
|
+ String b = two[0];
|
|
|
+ if (!b.contains(".")) {
|
|
|
+ if (b.substring(0, 1).equals("0")) {
|
|
|
+ b = b.substring(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (b.contains(".") && b.split("\\.").length > 1) {
|
|
|
+ if (b.substring(0, 1).equals("0")) {
|
|
|
+ b = b.substring(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ BigDecimal fen = new BigDecimal(a);
|
|
|
+ BigDecimal miao = new BigDecimal(b);
|
|
|
+ BigDecimal du = new BigDecimal(d);
|
|
|
+ // float f = Float.valueOf(a)+ Float.valueOf(Float.valueOf(b)/60);
|
|
|
+ // float du = Float.valueOf(f/60)+Float.valueOf(d);
|
|
|
+ BigDecimal add = fen.add(miao.divide(new BigDecimal("60"), 6, BigDecimal.ROUND_HALF_UP))
|
|
|
+ .divide(new BigDecimal("60"), 6, BigDecimal.ROUND_HALF_UP).add(du);
|
|
|
+ return String.valueOf(add);
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isDouble(String str1, String str2) {
|
|
|
+ try {
|
|
|
+ Double.parseDouble(str1);
|
|
|
+ Double.parseDouble(str2);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ catch (NumberFormatException ex) {
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ System.out.println(Arrays.toString(getCoordinate(2833742.70380015070,582577.02485382770)));
|
|
|
+ }
|
|
|
+}
|