package org.sxkj.common.geo.utils; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LinearRing; import org.locationtech.jts.geom.MultiPolygon; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.operation.valid.IsValidOp; public class GeometryCheck { // 新增 polygonCheck 方法,返回 boolean 值表示几何体是否正常 public static boolean polygonCheck(String polygonData) { try { WKTReader reader = new WKTReader(); Geometry geometry = reader.read(polygonData); // 解析 WKT 数据 // 检查是否是 Polygon 或 MultiPolygon if (geometry instanceof Polygon) { Polygon polygon = (Polygon) geometry; return checkPolygon(polygon); } else if (geometry instanceof MultiPolygon) { MultiPolygon multiPolygon = (MultiPolygon) geometry; boolean allValid = true; for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { Polygon polygon = (Polygon) multiPolygon.getGeometryN(i); if (!checkPolygon(polygon)) { allValid = false; // 只要有一个多边形不正常,返回 false break; } } return allValid; } else { return false; // 如果几何类型不匹配,返回 false } } catch (Exception e) { e.printStackTrace(); return false; // 解析异常时返回 false } } // 检查 Polygon 是否完整且无异常,返回 boolean 表示是否正常 private static boolean checkPolygon(Polygon polygon) { // 检查外环是否闭合 boolean outerRingClosed = isRingClosed(polygon.getExteriorRing()); // 检查每个内环(孔)是否闭合 boolean innerRingsClosed = true; for (int i = 0; i < polygon.getNumInteriorRing(); i++) { if (!isRingClosed(polygon.getInteriorRingN(i))) { innerRingsClosed = false; break; } } // 使用 IsValidOp 检查几何体是否有效(例如,是否有自相交等问题) IsValidOp isValidOp = new IsValidOp(polygon); boolean isValid = isValidOp.isValid(); // 返回该 Polygon 是否正常,即闭合且无自相交等问题 return isValid && outerRingClosed && innerRingsClosed; } // 检查 LinearRing 是否闭合(首尾点是否相同) private static boolean isRingClosed(LinearRing ring) { return ring.isClosed(); } }