| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- package com.onemap.sanya.utils;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.onemap.common.core.annotation.Excel;
- import com.onemap.sanya.domain.spatial.CustomXY;
- import java.io.IOException;
- import java.lang.reflect.Field;
- import java.text.ParseException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.stream.Collectors;
- import com.onemap.sanya.domain.spatial.FldInfo;
- import com.onemap.sanya.domain.spatial.SuperMapFreature;
- import com.onemap.sanya.domain.spatial.SuperMapGeo;
- import org.geotools.geojson.GeoJSON;
- import org.geotools.geometry.jts.JTS;
- import org.geotools.util.factory.Hints;
- import org.locationtech.jts.geom.*;
- import org.locationtech.jts.geom.Polygon;
- import org.locationtech.jts.geom.GeometryFactory;
- import org.locationtech.jts.io.WKTReader;
- import org.locationtech.jts.io.WKTWriter;
- import org.geotools.referencing.CRS;
- import org.opengis.referencing.crs.CRSAuthorityFactory;
- import org.opengis.referencing.crs.CRSFactory;
- import org.opengis.referencing.crs.CoordinateReferenceSystem;
- import org.opengis.referencing.operation.MathTransform;
- public class SpatialOperate {
- static Hints hints = new Hints();
- // static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(hints);
- static PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING);
- // 定义一个坐标参考系统,这里使用EPSG:4326,即WGS84
- static final int srid = 4490;
- // WGS84 坐标系(EPSG:4326)
- private static final String WGS84 = "EPSG:4490";
- // 根据你的地理位置选择合适的 UTM Zone
- private static final String UTM_ZONE = "EPSG:32650"; //
- static String srid4326 = "GEOGCS[\"WGS 84\",\n" +
- " DATUM[\"WGS_1984\",\n" +
- " SPHEROID[\"WGS 84\",6378137,298.257223563,\n" +
- " AUTHORITY[\"EPSG\",\"7030\"]],\n" +
- " AUTHORITY[\"EPSG\",\"6326\"]],\n" +
- " PRIMEM[\"Greenwich\",0,\n" +
- " AUTHORITY[\"EPSG\",\"8901\"]],\n" +
- " UNIT[\"degree\",0.0174532925199433,\n" +
- " AUTHORITY[\"EPSG\",\"9122\"]],\n" +
- " AUTHORITY[\"EPSG\",\"4326\"]]";
- static String srid3857 = "PROJCS[\"WGS 84 / Pseudo-Mercator\",\n" +
- " GEOGCS[\"WGS 84\",\n" +
- " DATUM[\"WGS_1984\",\n" +
- " SPHEROID[\"WGS 84\",6378137,298.257223563,\n" +
- " AUTHORITY[\"EPSG\",\"7030\"]],\n" +
- " AUTHORITY[\"EPSG\",\"6326\"]],\n" +
- " PRIMEM[\"Greenwich\",0,\n" +
- " AUTHORITY[\"EPSG\",\"8901\"]],\n" +
- " UNIT[\"degree\",0.0174532925199433,\n" +
- " AUTHORITY[\"EPSG\",\"9122\"]],\n" +
- " AUTHORITY[\"EPSG\",\"4326\"]],\n" +
- " PROJECTION[\"Mercator_1SP\"],\n" +
- " PARAMETER[\"central_meridian\",0],\n" +
- " PARAMETER[\"scale_factor\",1],\n" +
- " PARAMETER[\"false_easting\",0],\n" +
- " PARAMETER[\"false_northing\",0],\n" +
- " UNIT[\"metre\",1,\n" +
- " AUTHORITY[\"EPSG\",\"9001\"]],\n" +
- " AXIS[\"Easting\",EAST],\n" +
- " AXIS[\"Northing\",NORTH],\n" +
- " EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs\"],\n" +
- " AUTHORITY[\"EPSG\",\"3857\"]]";
- static String srid4490 = "GEOGCS[\"China Geodetic Coordinate System 2000\",\n" +
- " DATUM[\"China_2000\",\n" +
- " SPHEROID[\"CGCS2000\",6378137,298.257222101,\n" +
- " AUTHORITY[\"EPSG\",\"1024\"]],\n" +
- " AUTHORITY[\"EPSG\",\"1043\"]],\n" +
- " PRIMEM[\"Greenwich\",0,\n" +
- " AUTHORITY[\"EPSG\",\"8901\"]],\n" +
- " UNIT[\"degree\",0.0174532925199433,\n" +
- " AUTHORITY[\"EPSG\",\"9122\"]],\n" +
- " AUTHORITY[\"EPSG\",\"4490\"]]";
- static String srid4546 = "PROJCS[\"CGCS2000 / 3-degree Gauss-Kruger CM 111E\",\n" +
- " GEOGCS[\"China Geodetic Coordinate System 2000\",\n" +
- " DATUM[\"China_2000\",\n" +
- " SPHEROID[\"CGCS2000\",6378137,298.257222101,\n" +
- " AUTHORITY[\"EPSG\",\"1024\"]],\n" +
- " AUTHORITY[\"EPSG\",\"1043\"]],\n" +
- " PRIMEM[\"Greenwich\",0,\n" +
- " AUTHORITY[\"EPSG\",\"8901\"]],\n" +
- " UNIT[\"degree\",0.0174532925199433,\n" +
- " AUTHORITY[\"EPSG\",\"9122\"]],\n" +
- " AUTHORITY[\"EPSG\",\"4490\"]],\n" +
- " PROJECTION[\"Transverse_Mercator\"],\n" +
- " PARAMETER[\"latitude_of_origin\",0],\n" +
- " PARAMETER[\"central_meridian\",111],\n" +
- " PARAMETER[\"scale_factor\",1],\n" +
- " PARAMETER[\"false_easting\",500000],\n" +
- " PARAMETER[\"false_northing\",0],\n" +
- " UNIT[\"metre\",1,\n" +
- " AUTHORITY[\"EPSG\",\"9001\"]],\n" +
- " AUTHORITY[\"EPSG\",\"4546\"]]";
- // 创建GeometryFactory
- static GeometryFactory geometryFactory = new GeometryFactory(precisionModel, srid);
- public static Polygon createPolygonByXYArray(List<CustomXY> coors) {
- Polygon pPolygon = null;
- if (coors == null || coors.size() == 0)
- return pPolygon;
- Coordinate[] coordinates = new Coordinate[]{new Coordinate(1, 2), new Coordinate(1, 2), new Coordinate(1, 2)};
- pPolygon = geometryFactory.createPolygon();
- return pPolygon;
- }
- public static String geometry2Wkt(Geometry geometry) {
- String wkt = "SRID=" + srid + ";";
- WKTWriter wktWriter = new WKTWriter();
- wkt += wktWriter.write(geometry);
- return wkt;
- }
- public static String geometry2GeoJson(Geometry geometry) throws IOException {
- String wkt = "";
- GeoJSON.write(geometry, wkt);
- return wkt;
- }
- public static Point createPoint(Double x, Double y) {
- Point point = null;
- if(x == null && y == null) {
- return point;
- }
- point=geometryFactory.createPoint(new Coordinate(x, y));
- point.setSRID(srid);
- return point;
- }
- /**
- * 根据坐标点创建
- *
- * @param points
- * @return
- */
- public static Polygon createPolygon(List<Coordinate> points) {
- Polygon polygon = null;
- if (points == null)
- return polygon;
- Coordinate[] coordinates = points.toArray(new Coordinate[points.size()]);
- LinearRing ring = geometryFactory.createLinearRing(coordinates);
- polygon = geometryFactory.createPolygon(ring);
- polygon.setSRID(srid);
- return polygon;
- }
- /**
- * 为输入的 Geometry 计算 24 米缓冲区,并保持原始坐标系
- * @param inputGeometry 输入的几何图形(支持点、线、面等)
- * @param bufferMeters 缓冲(米)
- * @return
- * @throws Exception
- */
- public static Geometry bufferByMeters(Geometry inputGeometry,Double bufferMeters) throws Exception {
- CoordinateReferenceSystem sourceCRS = CRS.parseWKT(srid4490);
- // 投影转换
- CoordinateReferenceSystem utmCRS = CRS.parseWKT(srid4546);
- // 转换到 UTM 坐标系进行缓冲区计算
- MathTransform toUTM = CRS.findMathTransform(sourceCRS, utmCRS, true);
- Geometry geometryInUTM = JTS.transform(inputGeometry, toUTM);
- // 计算 缓冲区
- Geometry bufferedGeometryUTM = geometryInUTM.buffer(bufferMeters);
- // 转回原始坐标系
- MathTransform toSource = CRS.findMathTransform(utmCRS, sourceCRS, true);
- return JTS.transform(bufferedGeometryUTM, toSource);
- }
- /**
- * 经纬度转墨卡托 便于面积转换
- *
- * @param geom
- * @return
- */
- // public static Geometry lonlat2WebMactor(Geometry geom) {
- // try {
- // //这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影
- // CRSAuthorityFactory factory=CRS.getAuthorityFactory(true);
- // Integer wkid=geom.getSRID();
- // CoordinateReferenceSystem sourceTarget = factory.createCoordinateReferenceSystem("EPSG:"+4490);
- //
- //// MathTransform transform1 = CRS.findMathTransform(DefaultGeographicCRS.WGS84, sourceTarget);
- //// Geometry geometry1= JTS.transform(geom, transform1);
- // // 投影转换
- // CoordinateReferenceSystem crsTarget=factory.createCoordinateReferenceSystem("EPSG:"+4546);
- //// CoordinateReferenceSystem crsTarget = CRS.parseWKT(srid4546);
- //
- // MathTransform transform2 = CRS.findMathTransform(sourceTarget, crsTarget, false);
- // return JTS.transform(geom, transform2);
- // } catch (Exception e) {
- // e.printStackTrace();
- // return null;
- // }
- // }
- /**
- * 经纬度转墨卡托 便于面积转换
- *
- * @param geom
- * @return
- */
- public static Geometry lonlat2WebMactor(Geometry geom) {
- try {
- //这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影
- CoordinateReferenceSystem sourceTarget = CRS.parseWKT(srid4490);
- // MathTransform transform1 = CRS.findMathTransform(DefaultGeographicCRS.WGS84, sourceTarget);
- // Geometry geometry1= JTS.transform(geom, transform1);
- // 投影转换
- CoordinateReferenceSystem crsTarget = CRS.parseWKT(srid4546);
- MathTransform transform2 = CRS.findMathTransform(sourceTarget, crsTarget, false);
- return JTS.transform(geom, transform2);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- /**
- * 获取面积(平方米)
- *
- * @param geometry
- * @return
- */
- public static Double getGeometryArea(Geometry geometry) {
- if (geometry == null)
- return 0.00;
- Geometry geometry1 = lonlat2WebMactor(geometry);
- if (geometry1 == null)
- return 0.00;
- return geometry1.getArea();
- }
- /**
- * 根据wkt 生成多边形
- *
- * @param wkt
- * @return
- * @throws ParseException
- */
- public static Geometry createPolygonByWkt(String wkt) throws ParseException, org.locationtech.jts.io.ParseException {
- Geometry geometry=null;
- WKTReader reader = new WKTReader();
- Integer index = wkt.indexOf(";");
- if (index > -1)
- wkt = wkt.substring(index + 1);
- geometry=reader.read(wkt);
- return geometry;
- }
- /**
- * 根据wkt 生成多边形
- *
- * @param wkt
- * @return
- * @throws ParseException
- */
- public static Geometry createGeometryByWkt(String wkt) throws ParseException, org.locationtech.jts.io.ParseException {
- WKTReader reader = new WKTReader();
- Integer index = wkt.indexOf(";");
- if (index > -1)
- wkt = wkt.substring(index + 1);
- Geometry geometry = reader.read(wkt);
- geometry.setSRID(srid);
- return geometry;
- }
- public static Double getIntersectsArea(Geometry polygon1, Geometry other) {
- Double result=0.0;
- Geometry intersetGeom =null;
- Boolean isInster= polygon1.intersects(other);
- if(isInster)
- {
- try {
- intersetGeom = polygon1.intersection(other);
- }
- catch (Exception er){
- result=0.0;
- }
- }
- if (intersetGeom == null) {
- result=0.0;
- }
- else {
- Geometry pPolgon = lonlat2WebMactor(intersetGeom);
- if (pPolgon != null)
- result = pPolgon.getArea() / 666.66;
- }
- return result;
- }
- /**
- * 计算多个面交集
- *
- * @param polygons
- * @return
- */
- public static Double getIntersectByGeometrys(List<Geometry> polygons) {
- Geometry intersetGeom = null;
- if (polygons.size() >= 2) {
- for (int i = 1; i < polygons.size(); i++) {
- // 第一次用前两个比较
- if (i == 1) {
- intersetGeom = polygons.get(0).intersection(polygons.get(i));
- }
- // 后续用上次的结果比较
- else if (i == polygons.size() - 1) {
- intersetGeom = intersetGeom.intersection(polygons.get(i));
- }
- // 检查交集是否为空,如果为空则提前结束循环
- if (intersetGeom.isEmpty()) {
- return 0.00;
- }
- }
- }
- if (!intersetGeom.isEmpty()) {
- return lonlat2WebMactor(intersetGeom).getArea()/666.66;
- } else {
- return 0.00;
- }
- }
- public static SuperMapFreature Feature2Supermap(Object obj, Geometry geom ) throws org.locationtech.jts.io.ParseException, IllegalAccessException {
- SuperMapFreature res = new SuperMapFreature();
- Geometry geometry = geom;
- WKTReader reader = new WKTReader();
- Field[] fields = obj.getClass().getDeclaredFields();
- String[] fieldNames = new String[fields.length];
- String[] fieldValues = new String[fields.length];
- Integer smId = 0;
- for (int i = 0; i < fields.length; i++) {
- String fldName = fields[i].getName().toUpperCase();
- // if(fldName.equals("SMGEOMETRY"))
- // continue;
- fields[i].setAccessible(true);
- fieldNames[i] = fldName;
- String s = "null";
- if ("SMGEOMETRY".equals(fldName)) {
- fieldValues[i] = "";
- } else {
- fieldValues[i] = fields[i].get(obj) == null ? s : fields[i].get(obj).toString();
- }
- if (fields[i].getName().toUpperCase().equals("SMID"))
- smId = Integer.parseInt(fields[i].get(obj).toString());
- }
- int innerCout = 0;
- LinearRing outRing = null;
- Integer[] parts = new Integer[1];
- Integer[] partTop = new Integer[1];
- Integer partIndex = 0;
- List<Coordinate> allPoints = new ArrayList<>();
- int outPointCount = 0;
- LinearRing curInnerRing = null;
- Polygon polygon = null;
- if (geom.getGeometryType() == Geometry.TYPENAME_MULTIPOLYGON)
- polygon = (Polygon) geom.getGeometryN(0);
- else if (geom.getGeometryType() == Geometry.TYPENAME_POLYGON) {
- polygon = (Polygon) geom;
- }
- innerCout = polygon.getNumInteriorRing();
- outRing = polygon.getExteriorRing();
- parts = new Integer[innerCout + 1];
- partTop = new Integer[innerCout+1];
- outPointCount = outRing.getNumPoints();
- parts[0] = outPointCount - 1;
- partTop[0] = 1;
- partIndex = outPointCount - 1;
- for (Integer i = 1; i < innerCout; i++) {
- curInnerRing = polygon.getInteriorRingN(i - 1);
- partIndex += curInnerRing.getNumPoints();
- parts[i] = partIndex;
- partTop[i] = -1;
- Coordinate[] ddd= curInnerRing.getCoordinates();
- List<Coordinate> dddfs= Arrays.stream(ddd).collect(Collectors.toList());
- allPoints.addAll(dddfs);
- }
- allPoints.addAll(Arrays.stream(outRing.getCoordinates()).collect(Collectors.toList()));
- SuperMapGeo superMapGeo = new SuperMapGeo();
- superMapGeo.setCenter(new Coordinate(geom.getCentroid().getX(), geom.getCentroid().getY()));
- superMapGeo.setId(smId);
- superMapGeo.setParts(parts);
- superMapGeo.setPoints(allPoints);
- superMapGeo.setType("REGION");
- superMapGeo.setPartTopo(partTop);
- res.setFieldNames(fieldNames);
- res.setFieldValues(fieldValues);
- res.setGeometry(superMapGeo);
- res.setID(smId);
- return res;
- }
- /**
- * 根据类生成字段列表
- *
- * @param object
- * @return
- */
- public static List<FldInfo> getFieldAnnotation(Object object) {
- Field[] fields = object.getClass().getDeclaredFields();
- List<FldInfo> fldInfos = new ArrayList<>();
- for (Field field : fields) {
- // 是否引用ApiModelProperty注解
- String name = field.getName();
- String typeName = field.getType().getName();
- boolean bool = field.isAnnotationPresent(Excel.class);
- String cnName = "";
- if (bool) {
- cnName = field.getAnnotation(Excel.class).name();
- // fldInfos.add(new FldInfo(value);
- System.out.print(cnName);
- }
- if (cnName == null || cnName.isEmpty())
- cnName = name;
- fldInfos.add(new FldInfo(name.toUpperCase(), cnName.toUpperCase(), typeName.toUpperCase()));
- }
- return fldInfos;
- }
- /**
- * 根据类生成字段列表
- *
- * @param object
- * @return
- */
- public static List<FldInfo> getFieldAnnotationJZDJ(Object object) {
- Field[] fields = object.getClass().getDeclaredFields();
- List<FldInfo> fldInfos = new ArrayList<>();
- for (Field field : fields) {
- // 是否引用ApiModelProperty注解
- String name = field.getName();
- String typeName = field.getType().getName();
- boolean bool = field.isAnnotationPresent(Excel.class);
- String cnName = "";
- if (bool) {
- cnName = field.getAnnotation(Excel.class).name();
- // fldInfos.add(new FldInfo(value);
- System.out.print(cnName);
- }
- if (cnName == null || cnName.isEmpty())
- cnName = name;
- fldInfos.add(new FldInfo(name, cnName, typeName));
- }
- return fldInfos;
- }
- //
- // private GeometryFactory geometryFactory = new GeometryFactory();
- // /**
- // * 根据wkt生成点
- // *
- // * @param wkt
- // * @return
- // * @throws ParseException
- // */
- // public Point creatPoint(String wkt) throws ParseException {
- // WKTReader wktReader = new WKTReader();
- // Point point = null;
- // if (wkt != null)
- // point = (Point) wktReader.read(wkt);
- // return point;
- // }
- //
- // /**
- // * 根据wkt生成线
- // *
- // * @param wkt
- // * @return
- // * @throws ParseException
- // */
- // public LineString creatPolyline(String wkt) throws ParseException {
- // WKTReader wktReader = new WKTReader();
- // LineString polyline = null;
- // if (wkt != null)
- // polyline = (LineString) wktReader.read(wkt);
- // return polyline;
- // }
- //
- // /**
- // * wkt生产面
- // *
- // * @param wkt
- // * @return
- // * @throws ParseException
- // */
- // public Polygon creatPolygon(String wkt) throws ParseException {
- // WKTReader wktReader = new WKTReader();
- // Polygon polygon = null;
- // if (wkt != null)
- // polygon = (Polygon) wktReader.read(wkt);
- // return polygon;
- // }
- //
- // /**
- // * 获取面积
- // * @param wkt
- // * @return
- // * @throws ParseException
- // */
- // public Double getArea(String wkt) throws ParseException {
- // WKTReader wktReader = new WKTReader();
- // Polygon polygon = null;
- // if (wkt != null)
- // polygon = (Polygon) wktReader.read(wkt);
- // return polygon.getArea();
- // }
- //
- //
- // /**
- // * 根据坐标创建点
- // * @param x
- // * @param y
- // * @return
- // */
- // public Geometry createPointXY(Double x,Double y)
- // {
- // Geometry geometry=null;
- // Coordinate coord = new Coordinate(x,y);
- // Point point = geometryFactory.createPoint( coord );
- // return point;
- // }
- //
- // /**
- // * 获取2个实体的的相交面积
- // * @param one
- // * @param other
- // * @return
- // */
- // public Double getInsertion(Geometry one,Geometry other)
- // {
- // if(one==null||other==null)
- // return 0.00;
- // Geometry geometry= one.intersection(other);
- // if(geometry==null)
- // return 0.00;
- // return geometry.getArea();
- // }
- }
|