GeoUtils.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package com.ruoyi.common.utils.geo;
  2. import org.locationtech.jts.geom.Coordinate;
  3. import org.locationtech.jts.geom.Geometry;
  4. import org.locationtech.jts.geom.GeometryFactory;
  5. import org.locationtech.jts.geom.Point;
  6. import org.locationtech.jts.geom.Polygon;
  7. import org.locationtech.jts.io.ParseException;
  8. import org.locationtech.jts.io.WKTReader;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import java.util.List;
  12. public class GeoUtils {
  13. private static final Logger log = LoggerFactory.getLogger(GeoUtils.class);
  14. /**
  15. * geometryFactory
  16. */
  17. private static final GeometryFactory geometryFactory = new GeometryFactory();
  18. /**
  19. * Gets distance.
  20. *
  21. * @param lat1 the lat 1
  22. * @param lon1 the lon 1
  23. * @param lat2 the lat 2
  24. * @param lon2 the lon 2
  25. * @return the distance
  26. * @author chen.cheng
  27. */
  28. public static double getDistance(double lat1, double lon1, double lat2, double lon2) {
  29. Point p1 = geometryFactory.createPoint(new Coordinate(lon1, lat1));
  30. Point p2 = geometryFactory.createPoint(new Coordinate(lon2, lat2));
  31. return p1.distance(p2);
  32. }
  33. /**
  34. * Gets poly center.
  35. * POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))
  36. *
  37. * @param wktPolygon the wkt polygon
  38. * @return the poly center
  39. * @author chen.cheng
  40. */
  41. public static Point getPolyCenter(String wktPolygon) {
  42. // 创建WKTReader对象
  43. WKTReader reader = new WKTReader(geometryFactory);
  44. // 从WKT字符串中读取几何对象
  45. Geometry geometry = null;
  46. try {
  47. geometry = reader.read(wktPolygon);
  48. } catch (ParseException e) {
  49. log.info("Invalid WKT string: " + e.getMessage());
  50. }
  51. // 获取中心点
  52. return geometry.getCentroid();
  53. }
  54. /**
  55. * getPolygon
  56. * POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))
  57. *
  58. * @param wktPolygon the wkt polygon
  59. * @return the poly center
  60. * @author chen.cheng
  61. */
  62. public static Polygon getPolygon(String wktPolygon) {
  63. // 创建WKTReader对象
  64. WKTReader reader = new WKTReader(geometryFactory);
  65. // 从WKT字符串中读取几何对象
  66. Polygon geometry = null;
  67. try {
  68. geometry = (Polygon) reader.read(wktPolygon);
  69. } catch (ParseException e) {
  70. log.info("Invalid WKT string: " + e.getMessage());
  71. }
  72. // 获取中心点
  73. return geometry;
  74. }
  75. /**
  76. * 判断指定的GPS点是否在电子围栏内
  77. *
  78. * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
  79. * @param pointStr 指定的GPS点,格式为 "经度,纬度"
  80. * @return 如果在电子围栏内则返回true,否则返回false
  81. */
  82. public static boolean isPointInGeoFence(List<String> fencePointsList, String pointStr) {
  83. // 将电子围栏的经纬度数据转换为坐标数组
  84. Coordinate[] fencePoints = parseCoordinates(fencePointsList);
  85. // 将指定的GPS点转换为坐标
  86. Coordinate targetPoint = parseCoordinate(pointStr);
  87. // 创建电子围栏多边形
  88. Polygon geoFencePolygon = createPolygon(fencePoints);
  89. // 创建指定的GPS点
  90. Point point = geometryFactory.createPoint(targetPoint);
  91. // 检查指定的GPS点是否在电子围栏内
  92. return geoFencePolygon.contains(point);
  93. }
  94. /**
  95. * 判断指定的GPS点是否在电子围栏内
  96. *
  97. * @param geoFencePolygon geo fence polygon
  98. * @param pointStr 指定的GPS点,格式为 "经度,纬度"
  99. * @return 如果在电子围栏内则返回true ,否则返回false
  100. * @since 2.0.0
  101. */
  102. public static boolean isPointInGeoFence(Polygon geoFencePolygon, String pointStr) {
  103. // 将指定的GPS点转换为坐标
  104. Coordinate testPoint = parseCoordinate(pointStr);
  105. // 创建指定的GPS点
  106. Point point = geometryFactory.createPoint(testPoint);
  107. // 检查指定的GPS点是否在电子围栏内
  108. return geoFencePolygon.contains(point);
  109. }
  110. public static boolean isPointInGeoFence(Polygon geoFencePolygon, String lng, String lat) {
  111. // 将指定的GPS点转换为坐标
  112. Coordinate testPoint = parseCoordinate(lng, lat);
  113. // 创建指定的GPS点
  114. Point point = geometryFactory.createPoint(testPoint);
  115. // 检查指定的GPS点是否在电子围栏内
  116. return geoFencePolygon.contains(point);
  117. }
  118. public static void main(String[] args) {
  119. Polygon polygon = getPolygon("POLYGON((0.63 2.95, 2.6 2.78, 3.97 6.14, 0 5.7, 0.63 2.95))");
  120. System.out.println(isPointInGeoFence(polygon, "1.23", "4.56"));
  121. }
  122. /**
  123. * 判断指定的GPS点是否在电子围栏内
  124. *
  125. * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
  126. * @return 如果在电子围栏内则返回true,否则返回false
  127. */
  128. public static Polygon getPointInGeoFence(List<String> fencePointsList) {
  129. // 将电子围栏的经纬度数据转换为坐标数组
  130. Coordinate[] fencePoints = parseCoordinates(fencePointsList);
  131. // 创建电子围栏
  132. return createPolygon(fencePoints);
  133. }
  134. /**
  135. * 根据GPS点集合创建多边形
  136. *
  137. * @param coordinates GPS点集合
  138. * @return 多边形对象
  139. */
  140. private static Polygon createPolygon(Coordinate[] coordinates) {
  141. // Ensure the polygon is closed by adding the first coordinate at the end if necessary
  142. if (!coordinates[0].equals(coordinates[coordinates.length - 1])) {
  143. Coordinate[] closedCoordinates = new Coordinate[coordinates.length + 1];
  144. System.arraycopy(coordinates, 0, closedCoordinates, 0, coordinates.length);
  145. closedCoordinates[closedCoordinates.length - 1] = coordinates[0];
  146. coordinates = closedCoordinates;
  147. }
  148. return geometryFactory.createPolygon(coordinates);
  149. }
  150. /**
  151. * 将包含经纬度数据的列表转换为坐标数组
  152. *
  153. * @param pointsList 包含经纬度数据的列表
  154. * @return 坐标数组
  155. */
  156. private static Coordinate[] parseCoordinates(List<String> pointsList) {
  157. Coordinate[] coordinates = new Coordinate[pointsList.size()];
  158. for (int i = 0; i < pointsList.size(); i++) {
  159. coordinates[i] = parseCoordinate(pointsList.get(i));
  160. }
  161. return coordinates;
  162. }
  163. /**
  164. * 将经纬度数据字符串转换为坐标
  165. *
  166. * @param pointStr 经纬度数据字符串,格式为 "经度,纬度"
  167. * @return 坐标
  168. */
  169. private static Coordinate parseCoordinate(String pointStr) {
  170. String[] parts = pointStr.split(",");
  171. double lon = Double.parseDouble(parts[0]);
  172. double lat = Double.parseDouble(parts[1]);
  173. return new Coordinate(lon, lat);
  174. }
  175. private static Coordinate parseCoordinate(String lng, String lat) {
  176. return new Coordinate(Double.parseDouble(lng), Double.parseDouble(lat));
  177. }
  178. }