|
@@ -0,0 +1,144 @@
|
|
|
+package com.ruoyi.common.utils.geo;
|
|
|
+
|
|
|
+import org.locationtech.jts.geom.Coordinate;
|
|
|
+import org.locationtech.jts.geom.Geometry;
|
|
|
+import org.locationtech.jts.geom.GeometryFactory;
|
|
|
+import org.locationtech.jts.geom.Point;
|
|
|
+import org.locationtech.jts.geom.Polygon;
|
|
|
+import org.locationtech.jts.io.ParseException;
|
|
|
+import org.locationtech.jts.io.WKTReader;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+public class GeoUtils {
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(GeoUtils.class);
|
|
|
+ /**
|
|
|
+ * geometryFactory
|
|
|
+ */
|
|
|
+ private static final GeometryFactory geometryFactory = new GeometryFactory();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Gets poly center.
|
|
|
+ * POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))
|
|
|
+ *
|
|
|
+ * @param wktPolygon the wkt polygon
|
|
|
+ * @return the poly center
|
|
|
+ * @author chen.cheng
|
|
|
+ */
|
|
|
+ public static Point getPolyCenter(String wktPolygon) {
|
|
|
+ // 创建WKTReader对象
|
|
|
+ WKTReader reader = new WKTReader(geometryFactory);
|
|
|
+ // 从WKT字符串中读取几何对象
|
|
|
+ Geometry geometry = null;
|
|
|
+ try {
|
|
|
+ geometry = reader.read(wktPolygon);
|
|
|
+ } catch (ParseException e) {
|
|
|
+ log.info("Invalid WKT string: " + e.getMessage());
|
|
|
+ }
|
|
|
+ // 获取中心点
|
|
|
+ return geometry.getCentroid();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断指定的GPS点是否在电子围栏内
|
|
|
+ *
|
|
|
+ * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
|
|
|
+ * @param pointStr 指定的GPS点,格式为 "经度,纬度"
|
|
|
+ * @return 如果在电子围栏内则返回true,否则返回false
|
|
|
+ */
|
|
|
+ public static boolean isPointInGeoFence(List<String> fencePointsList, String pointStr) {
|
|
|
+ // 将电子围栏的经纬度数据转换为坐标数组
|
|
|
+ Coordinate[] fencePoints = parseCoordinates(fencePointsList);
|
|
|
+
|
|
|
+ // 将指定的GPS点转换为坐标
|
|
|
+ Coordinate targetPoint = parseCoordinate(pointStr);
|
|
|
+
|
|
|
+ // 创建电子围栏多边形
|
|
|
+ Polygon geoFencePolygon = createPolygon(fencePoints);
|
|
|
+
|
|
|
+ // 创建指定的GPS点
|
|
|
+ Point point = geometryFactory.createPoint(targetPoint);
|
|
|
+
|
|
|
+ // 检查指定的GPS点是否在电子围栏内
|
|
|
+ return geoFencePolygon.contains(point);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断指定的GPS点是否在电子围栏内
|
|
|
+ *
|
|
|
+ * @param geoFencePolygon geo fence polygon
|
|
|
+ * @param pointStr 指定的GPS点,格式为 "经度,纬度"
|
|
|
+ * @return 如果在电子围栏内则返回true ,否则返回false
|
|
|
+ * @since 2.0.0
|
|
|
+ */
|
|
|
+ public static boolean isPointInGeoFence(Polygon geoFencePolygon, String pointStr) {
|
|
|
+ // 将指定的GPS点转换为坐标
|
|
|
+ Coordinate testPoint = parseCoordinate(pointStr);
|
|
|
+
|
|
|
+ // 创建指定的GPS点
|
|
|
+ Point point = geometryFactory.createPoint(testPoint);
|
|
|
+
|
|
|
+ // 检查指定的GPS点是否在电子围栏内
|
|
|
+ return geoFencePolygon.contains(point);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断指定的GPS点是否在电子围栏内
|
|
|
+ *
|
|
|
+ * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
|
|
|
+ * @return 如果在电子围栏内则返回true,否则返回false
|
|
|
+ */
|
|
|
+ public static Polygon getPointInGeoFence(List<String> fencePointsList) {
|
|
|
+ // 将电子围栏的经纬度数据转换为坐标数组
|
|
|
+ Coordinate[] fencePoints = parseCoordinates(fencePointsList);
|
|
|
+ // 创建电子围栏
|
|
|
+ return createPolygon(fencePoints);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据GPS点集合创建多边形
|
|
|
+ *
|
|
|
+ * @param coordinates GPS点集合
|
|
|
+ * @return 多边形对象
|
|
|
+ */
|
|
|
+ private static Polygon createPolygon(Coordinate[] coordinates) {
|
|
|
+ // Ensure the polygon is closed by adding the first coordinate at the end if necessary
|
|
|
+ if (!coordinates[0].equals(coordinates[coordinates.length - 1])) {
|
|
|
+ Coordinate[] closedCoordinates = new Coordinate[coordinates.length + 1];
|
|
|
+ System.arraycopy(coordinates, 0, closedCoordinates, 0, coordinates.length);
|
|
|
+ closedCoordinates[closedCoordinates.length - 1] = coordinates[0];
|
|
|
+ coordinates = closedCoordinates;
|
|
|
+ }
|
|
|
+ return geometryFactory.createPolygon(coordinates);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将包含经纬度数据的列表转换为坐标数组
|
|
|
+ *
|
|
|
+ * @param pointsList 包含经纬度数据的列表
|
|
|
+ * @return 坐标数组
|
|
|
+ */
|
|
|
+ private static Coordinate[] parseCoordinates(List<String> pointsList) {
|
|
|
+ Coordinate[] coordinates = new Coordinate[pointsList.size()];
|
|
|
+ for (int i = 0; i < pointsList.size(); i++) {
|
|
|
+ coordinates[i] = parseCoordinate(pointsList.get(i));
|
|
|
+ }
|
|
|
+ return coordinates;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将经纬度数据字符串转换为坐标
|
|
|
+ *
|
|
|
+ * @param pointStr 经纬度数据字符串,格式为 "经度,纬度"
|
|
|
+ * @return 坐标
|
|
|
+ */
|
|
|
+ private static Coordinate parseCoordinate(String pointStr) {
|
|
|
+ String[] parts = pointStr.split(",");
|
|
|
+ double lon = Double.parseDouble(parts[0]);
|
|
|
+ double lat = Double.parseDouble(parts[1]);
|
|
|
+ return new Coordinate(lon, lat);
|
|
|
+ }
|
|
|
+}
|