检测多个多边形交叉点 (java)
Detecting multiple polygon intersections (java)
背景:该项目涉及在GIS环境中绘制区域。然后我需要找到一组多边形与另一组多边形的交集。我通过将 map-compatible 多边形转换为 Polygon2d (http://geom-java.sourceforge.net/api/math/geom2d/polygon/package-summary.html) 并使用交集方法查找相交多边形的顶点列表来实现此目的。
问题:除非在相同的两个多边形之间存在多个重叠区域,否则此方法有效。顶点列表是正确的,但我需要将列表分成每个单独的多边形。
第一张图片应该是这样的,第二张是实际生成的:
(忽略顶部区域。这是另一个错误的结果)
如何检测并纠正这种情况?
好吧,我想通了。我获取了相交多边形(蓝色)的顶点列表,遍历了每一对点,将两个原始多边形中的每条线段投射为 LineSegment2D 对象,并使用 .contains 方法检查每对点是否在其中一个线段。如果每对点不包含在一行中,则存在错误。
这是方法,但请记住,其中涉及多个专有 类。
public static boolean noErrors(SurfacePolygonX p1, SurfacePolygonX p2, List<LatLon> list) {
boolean allPointsInSamePolygon = true;
//for each latlon jl in locations, cast jl and jl2 as points
for (int j = 0; j < list.size(); j++) {
LatLon jl = list.get(j);
LatLon jl2 = list.get((j == list.size() - 1) ? 0 : j + 1);
Point2D pt = new Point2D(jl.longitude.degrees, jl.latitude.degrees);
Point2D pt2 = new Point2D(jl2.longitude.degrees, jl2.latitude.degrees);
List<LatLon> corners = p1.getCorners();
boolean bothPointsInSameSegment = false;
//for each latlon k selectedShape cast k and k+1 as 2lineseg
for (int k = 0; k < corners.size(); k++) {
LatLon kl = corners.get(k);
LatLon kl2 = corners.get((k == corners.size() - 1) ? 0 : k + 1);
LineSegment2D segment = new LineSegment2D(kl.longitude.degrees, kl.latitude.degrees, kl2.longitude.degrees, kl2.latitude.degrees);
boolean segContainsP1 = segment.contains(pt);
boolean segContainsP2 = segment.contains(pt2);
System.out.println("selectedShape: segment "+k+" contains p"+j+":("+segContainsP1+") and p"+(j+1)+":("+segContainsP2+")");
//check if each line contains the points.
if (segContainsP1 && segContainsP2)
{
bothPointsInSameSegment = true;
}
}
corners = p2.getCorners();
//for each latlon k tempShape cast k and k+1 as 2lineseg
for (int k = 0; k < corners.size(); k++) {
LatLon kl = corners.get(k);
LatLon kl2 = corners.get((k == corners.size() - 1) ? 0 : k + 1);
LineSegment2D segment = new LineSegment2D(kl.longitude.degrees, kl.latitude.degrees, kl2.longitude.degrees, kl2.latitude.degrees);
boolean segContainsP1 = segment.contains(pt);
boolean segContainsP2 = segment.contains(pt2);
System.out.println("intersectingShape: segment "+k+" contains p"+j+":("+segContainsP1+") and p"+(j+1)+":("+segContainsP2+")");
//check if each line contains the points.
if (segContainsP1 && segContainsP2)
{
bothPointsInSameSegment = true;
}
}
if (!bothPointsInSameSegment) allPointsInSamePolygon = false;
}
//if both points are not in the same line, then theres a conflict
return allPointsInSamePolygon;
}
您可以使用 JTS。
- 使用 LinearRing
创建您的多边形
- 使用intersection方法
简单代码示例:
// build polygon p1
LinearRing p1 = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0,0), new Coordinate(0,10), new Coordinate(10,10), new Coordinate(10,0), new Coordinate(0,0)});
// build polygon p2
LinearRing p2 = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(5,5), new Coordinate(15,5), new Coordinate(15,15), new Coordinate(5,15), new Coordinate(5,5)});
// calculate intersecting points
Geometry intersectingPoints = p1.intersection(p2);
// print result
for(Coordinate c : intersectingPoints.getCoordinates()){
System.out.println(c.toString());
}
输出是(如预期):
(5.0, 10.0, NaN)
(10.0, 5.0, NaN)
背景:该项目涉及在GIS环境中绘制区域。然后我需要找到一组多边形与另一组多边形的交集。我通过将 map-compatible 多边形转换为 Polygon2d (http://geom-java.sourceforge.net/api/math/geom2d/polygon/package-summary.html) 并使用交集方法查找相交多边形的顶点列表来实现此目的。
问题:除非在相同的两个多边形之间存在多个重叠区域,否则此方法有效。顶点列表是正确的,但我需要将列表分成每个单独的多边形。
第一张图片应该是这样的,第二张是实际生成的:
(忽略顶部区域。这是另一个错误的结果)
如何检测并纠正这种情况?
好吧,我想通了。我获取了相交多边形(蓝色)的顶点列表,遍历了每一对点,将两个原始多边形中的每条线段投射为 LineSegment2D 对象,并使用 .contains 方法检查每对点是否在其中一个线段。如果每对点不包含在一行中,则存在错误。
这是方法,但请记住,其中涉及多个专有 类。
public static boolean noErrors(SurfacePolygonX p1, SurfacePolygonX p2, List<LatLon> list) {
boolean allPointsInSamePolygon = true;
//for each latlon jl in locations, cast jl and jl2 as points
for (int j = 0; j < list.size(); j++) {
LatLon jl = list.get(j);
LatLon jl2 = list.get((j == list.size() - 1) ? 0 : j + 1);
Point2D pt = new Point2D(jl.longitude.degrees, jl.latitude.degrees);
Point2D pt2 = new Point2D(jl2.longitude.degrees, jl2.latitude.degrees);
List<LatLon> corners = p1.getCorners();
boolean bothPointsInSameSegment = false;
//for each latlon k selectedShape cast k and k+1 as 2lineseg
for (int k = 0; k < corners.size(); k++) {
LatLon kl = corners.get(k);
LatLon kl2 = corners.get((k == corners.size() - 1) ? 0 : k + 1);
LineSegment2D segment = new LineSegment2D(kl.longitude.degrees, kl.latitude.degrees, kl2.longitude.degrees, kl2.latitude.degrees);
boolean segContainsP1 = segment.contains(pt);
boolean segContainsP2 = segment.contains(pt2);
System.out.println("selectedShape: segment "+k+" contains p"+j+":("+segContainsP1+") and p"+(j+1)+":("+segContainsP2+")");
//check if each line contains the points.
if (segContainsP1 && segContainsP2)
{
bothPointsInSameSegment = true;
}
}
corners = p2.getCorners();
//for each latlon k tempShape cast k and k+1 as 2lineseg
for (int k = 0; k < corners.size(); k++) {
LatLon kl = corners.get(k);
LatLon kl2 = corners.get((k == corners.size() - 1) ? 0 : k + 1);
LineSegment2D segment = new LineSegment2D(kl.longitude.degrees, kl.latitude.degrees, kl2.longitude.degrees, kl2.latitude.degrees);
boolean segContainsP1 = segment.contains(pt);
boolean segContainsP2 = segment.contains(pt2);
System.out.println("intersectingShape: segment "+k+" contains p"+j+":("+segContainsP1+") and p"+(j+1)+":("+segContainsP2+")");
//check if each line contains the points.
if (segContainsP1 && segContainsP2)
{
bothPointsInSameSegment = true;
}
}
if (!bothPointsInSameSegment) allPointsInSamePolygon = false;
}
//if both points are not in the same line, then theres a conflict
return allPointsInSamePolygon;
}
您可以使用 JTS。
- 使用 LinearRing 创建您的多边形
- 使用intersection方法
简单代码示例:
// build polygon p1
LinearRing p1 = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0,0), new Coordinate(0,10), new Coordinate(10,10), new Coordinate(10,0), new Coordinate(0,0)});
// build polygon p2
LinearRing p2 = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(5,5), new Coordinate(15,5), new Coordinate(15,15), new Coordinate(5,15), new Coordinate(5,5)});
// calculate intersecting points
Geometry intersectingPoints = p1.intersection(p2);
// print result
for(Coordinate c : intersectingPoints.getCoordinates()){
System.out.println(c.toString());
}
输出是(如预期):
(5.0, 10.0, NaN)
(10.0, 5.0, NaN)