|
@@ -0,0 +1,331 @@
|
|
|
+package com.flyer.util;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.geotools.geojson.geom.GeometryJSON;
|
|
|
+import org.geotools.geometry.jts.JTS;
|
|
|
+import org.geotools.referencing.CRS;
|
|
|
+import org.geotools.referencing.GeodeticCalculator;
|
|
|
+import org.geotools.referencing.crs.DefaultGeographicCRS;
|
|
|
+import org.locationtech.jts.geom.*;
|
|
|
+import org.locationtech.jts.io.ParseException;
|
|
|
+import org.locationtech.jts.io.WKTReader;
|
|
|
+import org.locationtech.jts.io.WKTWriter;
|
|
|
+import org.opengis.referencing.FactoryException;
|
|
|
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|
|
+import org.opengis.referencing.operation.MathTransform;
|
|
|
+import org.opengis.referencing.operation.TransformException;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.StringReader;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+public class GeoCastUtil {
|
|
|
+ public static GeometryJSON gjson = new GeometryJSON(20);
|
|
|
+ private static WKTWriter wKTWriter2 = new WKTWriter();
|
|
|
+ private static WKTReader wktReader2 = new WKTReader();
|
|
|
+
|
|
|
+ public static String geomToWkt(Geometry geometry){
|
|
|
+ return wKTWriter2.write(geometry);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Geometry wktToGeom(String wkt){
|
|
|
+ try {
|
|
|
+ return wktReader2.read(wkt);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建矩形wkt
|
|
|
+ * @param points
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String createPolygonWkt(List<double[]> points){
|
|
|
+ if(ObjectUtils.isEmpty(points)){
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ StringBuffer sb = new StringBuffer(points.size() * 50);
|
|
|
+ sb.append("MULTIPOLYGON(((");
|
|
|
+ for(double[] point : points){
|
|
|
+ sb.append(point[0]);
|
|
|
+ sb.append(" ");
|
|
|
+ sb.append(point[1]);
|
|
|
+ sb.append(",");
|
|
|
+ }
|
|
|
+ sb.append(points.get(0)[0]);
|
|
|
+ sb.append(" ");
|
|
|
+ sb.append(points.get(0)[1]);
|
|
|
+ sb.append(")))");
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static GeometryCollection castGeometryCollection2(GeometryJSON fjson, GeometryCollection geometryCollection) throws IOException {
|
|
|
+ if (geometryCollection.getGeometryType().equals("GeometryCollection")) {
|
|
|
+ return geometryCollection;
|
|
|
+ }
|
|
|
+ String[] geometriesJsonArray = new String[geometryCollection.getNumGeometries()];
|
|
|
+ int length = 0;
|
|
|
+ for(int i=0; i< geometryCollection.getNumGeometries(); i++){
|
|
|
+ Geometry geometry = geometryCollection.getGeometryN(i);
|
|
|
+ geometriesJsonArray[i] = fjson.toString(geometry);
|
|
|
+ length += geometriesJsonArray[i].length();
|
|
|
+ }
|
|
|
+ StringBuffer result = new StringBuffer(length + 100);
|
|
|
+ result.append("{\"type\": \"GeometryCollection\",\"geometries\": [");
|
|
|
+ result.append(geometriesJsonArray[0]);
|
|
|
+ for(int i=1;i< geometriesJsonArray.length;i++){
|
|
|
+ result.append(",").append(geometriesJsonArray[i]);
|
|
|
+ }
|
|
|
+ result.append("]}");
|
|
|
+ return fjson.readGeometryCollection(new StringReader(result.toString()));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static GeometryCollection castGeometryCollection(GeometryJSON fjson, Geometry geometry) throws IOException {
|
|
|
+ if (geometry.getGeometryType().equals("GeometryCollection")) {
|
|
|
+ return (GeometryCollection)geometry;
|
|
|
+ }
|
|
|
+ if (geometry instanceof GeometryCollection) {
|
|
|
+ return castGeometryCollection2(fjson, (GeometryCollection)geometry);
|
|
|
+ }
|
|
|
+ String geometryJson = fjson.toString(geometry);
|
|
|
+ StringBuffer result = new StringBuffer(geometryJson.length() + 100);
|
|
|
+ result.append("{\"type\": \"GeometryCollection\",\"geometries\": [");
|
|
|
+ result.append(geometryJson);
|
|
|
+ result.append("]}");
|
|
|
+ return fjson.readGeometryCollection(new StringReader(result.toString()));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Geometry readGeometry(Object input, String type, GeometryJSON gjson) throws IOException {
|
|
|
+ switch(type){
|
|
|
+ case "Point":
|
|
|
+ return gjson.readPoint(input);
|
|
|
+ case "MultiPoint":
|
|
|
+ return gjson.readMultiPoint(input);
|
|
|
+ case "LineString":
|
|
|
+ return gjson.readLine(input);
|
|
|
+ case "MultiLineString":
|
|
|
+ return gjson.readMultiLine(input);
|
|
|
+ case "Polygon":
|
|
|
+ return gjson.readPolygon(input);
|
|
|
+ case "MultiPolygon":
|
|
|
+ return gjson.readMultiPolygon(input);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static Double[] lonlatToMactor(Double[] point){
|
|
|
+ CoordinateReferenceSystem crsTarget = null;
|
|
|
+ // 投影转换
|
|
|
+ MathTransform transform = null;
|
|
|
+ try {
|
|
|
+ crsTarget = CRS.decode("EPSG:3857");
|
|
|
+ transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crsTarget);
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ Coordinate sourcePoint = new Coordinate(point[0],point[1]);
|
|
|
+ Coordinate targetPoint = new Coordinate();
|
|
|
+ try {
|
|
|
+ JTS.transform(sourcePoint, targetPoint, transform);
|
|
|
+ } catch (TransformException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return new Double[]{targetPoint.getX(), targetPoint.getY()};
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double[] mactorToLonlat(double[] point, CoordinateReferenceSystem srcTarget){
|
|
|
+ // 投影转换
|
|
|
+ MathTransform transform = null;
|
|
|
+ try {
|
|
|
+ transform = CRS.findMathTransform(srcTarget, DefaultGeographicCRS.WGS84);
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ Coordinate sourcePoint = new Coordinate(point[0],point[1]);
|
|
|
+ Coordinate targetPoint = new Coordinate();
|
|
|
+ try {
|
|
|
+ JTS.transform(sourcePoint, targetPoint, transform);
|
|
|
+ } catch (TransformException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return new double[]{targetPoint.getX(),targetPoint.getY()};
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double[] mactorToLonlat(double[] point){
|
|
|
+ CoordinateReferenceSystem srcTarget = null;
|
|
|
+ // 投影转换
|
|
|
+ MathTransform transform = null;
|
|
|
+ try {
|
|
|
+ srcTarget = CRS.decode("EPSG:3857");
|
|
|
+ transform = CRS.findMathTransform(srcTarget, DefaultGeographicCRS.WGS84);
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ Coordinate sourcePoint = new Coordinate(point[0],point[1]);
|
|
|
+ Coordinate targetPoint = new Coordinate();
|
|
|
+ try {
|
|
|
+ JTS.transform(sourcePoint, targetPoint, transform);
|
|
|
+ } catch (TransformException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return new double[]{targetPoint.getX(),targetPoint.getY()};
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据多边形类型计算出多边形面积,单位(平方米)
|
|
|
+ * @param geometry 多边形对象
|
|
|
+ * @return 面积
|
|
|
+ */
|
|
|
+ public static double getArea(Geometry geometry){
|
|
|
+ CoordinateReferenceSystem source = null;
|
|
|
+ try {
|
|
|
+ source = CRS.decode("CRS:84");
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ CoordinateReferenceSystem target = null;
|
|
|
+ try {
|
|
|
+ target = CRS.decode("EPSG:3857");
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ MathTransform transform = null;
|
|
|
+ try {
|
|
|
+ transform = CRS.findMathTransform(source, target, true);
|
|
|
+ } catch (FactoryException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ Geometry transform1 = null;
|
|
|
+ try {
|
|
|
+ transform1 = JTS.transform(geometry, transform);
|
|
|
+ } catch (TransformException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ double area = transform1.getArea();
|
|
|
+ return area;
|
|
|
+ }
|
|
|
+
|
|
|
+// public static double toFlex(double d){
|
|
|
+// BigDecimal bd = new BigDecimal(d);
|
|
|
+// String s = bd.toPlainString();
|
|
|
+// int index = s.indexOf(".");
|
|
|
+// String last = s.substring(index + 1);
|
|
|
+// if(last.length() > 4){
|
|
|
+// last = last.substring(0,4);
|
|
|
+// }
|
|
|
+// return Double.parseDouble(s.substring(0,index + 1) + last);
|
|
|
+// }
|
|
|
+
|
|
|
+ public static int dist84(Point p1,Point p2){
|
|
|
+ // 84坐标系构造GeodeticCalculator
|
|
|
+ GeodeticCalculator geodeticCalculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
|
|
|
+ // 起点经纬度
|
|
|
+ geodeticCalculator.setStartingGeographicPoint(p1.getX(),p1.getY());
|
|
|
+ // 末点经纬度
|
|
|
+ geodeticCalculator.setDestinationGeographicPoint(p2.getX(),p2.getY());
|
|
|
+ // 计算距离,单位:米
|
|
|
+ double orthodromicDistance = geodeticCalculator.getOrthodromicDistance();
|
|
|
+ return (int)orthodromicDistance;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double miToMu(double m){
|
|
|
+ double c = 666.66666666667;
|
|
|
+ return m / c;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double mToDegree(Integer m){
|
|
|
+ double degree = m / (2 * Math.PI * 6371004) * 360;
|
|
|
+ return degree;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回面积 单位亩
|
|
|
+ * @param geom
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static double getAreaOfMu(Geometry geom){
|
|
|
+ return miToMu(getArea(geom));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转为geom并合并
|
|
|
+ * @param geom
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static Geometry unionToGeom(Geometry... geom){
|
|
|
+ if(geom.length == 0){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if(geom.length == 1){
|
|
|
+ return geom[0];
|
|
|
+ }
|
|
|
+ Geometry res = geom[0];
|
|
|
+ for(int i=1;i<geom.length;i++){
|
|
|
+ res = res.union(geom[i]);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转为geom并合并
|
|
|
+ * @param wkt
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static Geometry unionToGeom(String... wkt){
|
|
|
+ if(wkt.length == 1){
|
|
|
+ return wktToGeom(wkt[0]);
|
|
|
+ }
|
|
|
+ Geometry res = wktToGeom(wkt[0]);
|
|
|
+ for(int i=1;i<wkt.length;i++){
|
|
|
+ res = res.union(wktToGeom(wkt[i]));
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double distance(Point p1, Point p2){
|
|
|
+ double distance = p1.distance(p2);
|
|
|
+ return distance;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static GeometryFactory geometryFactory = new GeometryFactory();
|
|
|
+
|
|
|
+ // 假设的参数113.746646,22.970229
|
|
|
+ private static final double REFERENCE_LATITUDE = 22.970229; // 参考点的纬度
|
|
|
+ private static final double REFERENCE_LONGITUDE = 113.746646; // 参考点的经度
|
|
|
+ private static final double M_PER_PIXEL_X = 0.00001; // 每个像素的米数(x方向)
|
|
|
+ private static final double M_PER_PIXEL_Y = 0.00001; // 每个像素的米数(y方向)
|
|
|
+
|
|
|
+ public static Coordinate pixelToLatLng(double pixelX, double pixelY, double imageWidth, double imageHeight) {
|
|
|
+ // 计算像素到米的转换
|
|
|
+ double metersX = pixelX * M_PER_PIXEL_X;
|
|
|
+ double metersY = pixelY * M_PER_PIXEL_Y;
|
|
|
+
|
|
|
+ // 将米转换为经纬度
|
|
|
+ // 假设地球是平坦的,这里只是简单的加减
|
|
|
+ double latitude = REFERENCE_LATITUDE - (metersY / 111320); // 111320米为1度纬度距离的近似值
|
|
|
+ double longitude = REFERENCE_LONGITUDE + (metersX / (111320 * Math.cos(Math.toRadians(REFERENCE_LATITUDE)))); // 1度经度距离随纬度变化
|
|
|
+
|
|
|
+ return new Coordinate(longitude, latitude);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ int pixelX = 100;
|
|
|
+ int pixelY = 100;
|
|
|
+ int imageWidth = 1000;
|
|
|
+ int imageHeight = 1000;
|
|
|
+
|
|
|
+ Coordinate latLng = pixelToLatLng(pixelX, pixelY, imageWidth, imageHeight);
|
|
|
+ System.out.println("Latitude: " + latLng.y + ", Longitude: " + latLng.x);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|