|
@@ -0,0 +1,214 @@
|
|
|
+package com.persagy.adm.diagram.core.util;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.map.CaseInsensitiveMap;
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
+import com.persagy.adm.diagram.core.model.base.XY;
|
|
|
+import org.locationtech.jts.geom.*;
|
|
|
+import org.locationtech.jts.io.ParseException;
|
|
|
+import org.locationtech.jts.io.WKTReader;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public class GeomUtil {
|
|
|
+
|
|
|
+ private static GeometryFactory geometryFactory = new GeometryFactory();
|
|
|
+
|
|
|
+ public static Polygon getPolygon(XY location, XY size) {
|
|
|
+ Coordinate[] cs = new Coordinate[5];
|
|
|
+ cs[0] = new Coordinate(location.x, location.y);
|
|
|
+ cs[1] = new Coordinate(location.x + size.x, location.y);
|
|
|
+ cs[2] = new Coordinate(location.x + size.x, location.y + size.y);
|
|
|
+ cs[3] = new Coordinate(location.x, location.y + size.y);
|
|
|
+ cs[4] = cs[0];
|
|
|
+ return geometryFactory.createPolygon(cs);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static LineString getLine(XY[] points) {
|
|
|
+ Coordinate[] cs = new Coordinate[points.length];
|
|
|
+ for (int i = 0; i < cs.length; i++) {
|
|
|
+ cs[i] = new Coordinate(points[i].x, points[i].y);
|
|
|
+ }
|
|
|
+ return geometryFactory.createLineString(cs);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Point getPoint(XY xy){
|
|
|
+ return geometryFactory.createPoint(new Coordinate(xy.x, xy.y));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Polygon[] getPolygon(ArrayNode arrayNode){
|
|
|
+ Polygon[] ps = new Polygon[arrayNode.size()];
|
|
|
+ for (int i = 0; i < ps.length; i++) {
|
|
|
+ ArrayNode arr = (ArrayNode) arrayNode.get(i);
|
|
|
+ ArrayNode shellArrNode = (ArrayNode) arr.get(0);
|
|
|
+ LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellArrNode));
|
|
|
+ LinearRing[] holes = null;
|
|
|
+ if(arr.size() > 1) {
|
|
|
+ holes = new LinearRing[arr.size() - 1];
|
|
|
+ for (int n = 1; n < arr.size(); n++) {
|
|
|
+ holes[n - 1] = geometryFactory.createLinearRing(buildCoords((ArrayNode) arr.get(n)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ps[i] = geometryFactory.createPolygon(shell, holes);
|
|
|
+ }
|
|
|
+ return ps;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Coordinate[] buildCoords(ArrayNode arrayNode){
|
|
|
+ Coordinate[] coords = new Coordinate[arrayNode.size()];
|
|
|
+ for (int i = 0; i < arrayNode.size(); i++) {
|
|
|
+ JsonNode pointNode = arrayNode.get(i);
|
|
|
+ coords[i] = new Coordinate(pointNode.get("x").asDouble(), pointNode.get("y").asDouble());
|
|
|
+ }
|
|
|
+ return coords;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean checkPolygon(ArrayList<ArrayList<ArrayList<CaseInsensitiveMap>>> outline){
|
|
|
+ if(CollUtil.isEmpty(outline))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ try {
|
|
|
+ Polygon[] ps = new Polygon[outline.size()];
|
|
|
+ for (int i = 0; i < ps.length; i++) {
|
|
|
+ List space = (List) outline.get(i);
|
|
|
+ if(CollUtil.isEmpty(space))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ List<Map> shellList = (List) space.get(0);
|
|
|
+ LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellList));
|
|
|
+ LinearRing[] holes = null;
|
|
|
+ if(space.size() > 1) {
|
|
|
+ holes = new LinearRing[space.size() - 1];
|
|
|
+ for (int n = 1; n < space.size(); n++) {
|
|
|
+ holes[n - 1] = geometryFactory.createLinearRing(buildCoords((List<Map>) space.get(n)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ps[i] = geometryFactory.createPolygon(shell, holes);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Coordinate[] buildCoords(List<Map> list){
|
|
|
+ Coordinate[] coords = new Coordinate[list.size()];
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ Map point = list.get(i);
|
|
|
+ coords[i] = new Coordinate((Double) point.get("x"), (Double)point.get("y"));
|
|
|
+ }
|
|
|
+ return coords;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean checkPolygon(ArrayNode outline){
|
|
|
+ if(outline == null || outline.size() == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ try {
|
|
|
+ Polygon[] ps = new Polygon[outline.size()];
|
|
|
+ for (int i = 0; i < ps.length; i++) {
|
|
|
+ ArrayNode space = (ArrayNode) outline.get(i);
|
|
|
+ if(space == null || space.size() == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ ArrayNode shellList = (ArrayNode) space.get(0);
|
|
|
+ LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellList));
|
|
|
+ LinearRing[] holes = null;
|
|
|
+ if(space.size() > 1) {
|
|
|
+ holes = new LinearRing[space.size() - 1];
|
|
|
+ for (int n = 1; n < space.size(); n++) {
|
|
|
+ holes[n - 1] = geometryFactory.createLinearRing(buildCoords((ArrayNode) space.get(n)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ps[i] = geometryFactory.createPolygon(shell, holes);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 两个几何对象是否是重叠的
|
|
|
+ * @return
|
|
|
+ * @throws ParseException
|
|
|
+ */
|
|
|
+ public boolean equalsGeo() throws ParseException {
|
|
|
+ WKTReader reader = new WKTReader( geometryFactory );
|
|
|
+ LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
|
|
|
+ LineString geometry2 = (LineString) reader.read("LINESTRING(5 0, 0 0)");
|
|
|
+ return geometry1.equals(geometry2);//true
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 几何对象没有交点(相邻)
|
|
|
+ * @return
|
|
|
+ * @throws ParseException
|
|
|
+ */
|
|
|
+ public boolean disjointGeo() throws ParseException{
|
|
|
+ WKTReader reader = new WKTReader( geometryFactory );
|
|
|
+ LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
|
|
|
+ LineString geometry2 = (LineString) reader.read("LINESTRING(0 1, 0 2)");
|
|
|
+ return geometry1.disjoint(geometry2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 至少一个公共点(相交)
|
|
|
+ * @return
|
|
|
+ * @throws ParseException
|
|
|
+ */
|
|
|
+ public boolean intersectsGeo() throws ParseException{
|
|
|
+ WKTReader reader = new WKTReader( geometryFactory );
|
|
|
+ LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
|
|
|
+ LineString geometry2 = (LineString) reader.read("LINESTRING(0 0, 0 2)");
|
|
|
+ Geometry interPoint = geometry1.intersection(geometry2);//相交点
|
|
|
+ System.out.println(interPoint.toText());//输出 POINT (0 0)
|
|
|
+ return geometry1.intersects(geometry2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断以x,y为坐标的点point(x,y)是否在geometry表示的Polygon中
|
|
|
+ * @param x
|
|
|
+ * @param y
|
|
|
+ * @param geometry wkt格式
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean withinGeo(double x,double y,String geometry) throws ParseException {
|
|
|
+
|
|
|
+ Coordinate coord = new Coordinate(x,y);
|
|
|
+ Point point = geometryFactory.createPoint( coord );
|
|
|
+
|
|
|
+ WKTReader reader = new WKTReader( geometryFactory );
|
|
|
+ Polygon polygon = (Polygon) reader.read(geometry);
|
|
|
+ return point.within(polygon);
|
|
|
+ }
|
|
|
+
|
|
|
+ public LinearRing createLinearRing(double[]... xys){
|
|
|
+ Coordinate[] coords = new Coordinate[xys.length];
|
|
|
+ for(int i=0;i<xys.length;i++){
|
|
|
+ coords[i] = new Coordinate(xys[i][0], xys[i][1]);
|
|
|
+ }
|
|
|
+ return geometryFactory.createLinearRing(coords);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Polygon createPolygon(double[]... xys){
|
|
|
+ Coordinate[] coords = new Coordinate[xys.length];
|
|
|
+ for(int i=0;i<xys.length;i++){
|
|
|
+ coords[i] = new Coordinate(xys[i][0], xys[i][1]);
|
|
|
+ }
|
|
|
+ return geometryFactory.createPolygon(coords);
|
|
|
+ }
|
|
|
+
|
|
|
+ public LineString createLine(double[]... xys){
|
|
|
+ Coordinate[] coords = new Coordinate[xys.length];
|
|
|
+ for(int i=0;i<xys.length;i++){
|
|
|
+ coords[i] = new Coordinate(xys[i][0], xys[i][1]);
|
|
|
+ }
|
|
|
+ return geometryFactory.createLineString(coords);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|