简体   繁体   English

检测多个多边形交叉点(java)

[英]Detecting multiple polygon intersections (java)

Background: This project involves mapping regions in GIS environment. 背景:该项目涉及在GIS环境中映射区域。 I need to find then the intersection of one set of polygons with another set of polygons. 我需要找到一组多边形与另一组多边形的交集。 I achieved this by casting my map-compatible polygons as Polygon2d ( http://geom-java.sourceforge.net/api/math/geom2d/polygon/package-summary.html ) and used the intersection method to find the list of vertices for the intersection polygons. 我通过将我的地图兼容多边形转换为Polygon2d( http://geom-java.sourceforge.net/api/math/geom2d/polygon/package-summary.html )并使用交集方法查找顶点列表来实现此目的对于交叉多边形。

The problem: This works except when there are multiple over lapping regions between the same two polygons. 问题:这是有效的,除非在相同的两个多边形之间存在多个重叠区域。 The list of vertices is correct, but I need to seperate the list into each individual polygon. 顶点列表是正确的,但我需要将列表分成每个单独的多边形。

The first image is what it should look like, the second is what is actually generated: 第一个图像应该是它​​的样子,第二个是实际生成的图像:

(ignore the area at the top. Thats a result of a different bug) (忽略顶部的区域。这是一个不同的错误的结果)

How do I detect and correct this situation? 如何检测并纠正这种情况?

You can use JTS . 您可以使用JTS

  1. Create your Polygons using LinearRing 使用LinearRing创建多边形
  2. Use the intersection method 使用交集方法

Simple code example: 简单的代码示例:

// 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());
}

Output is (like expected): 输出(如预期):

(5.0, 10.0, NaN)
(10.0, 5.0, NaN)

Well I figured it out. 好吧我明白了。 I took the vertex list for the intersection polygon (blue), iterated through each pair of point, cast each line segment in the two original polygons as LineSegment2D objects and used the .contains method to check if each pair of points was in one of the line segments. 我将交叉多边形(蓝色)的顶点列表,迭代通过每对点,将两个原始多边形中的每个线段作为LineSegment2D对象进行投射,并使用.contains方法检查每对点是否在其中一个点中。线段。 If each pair of points wasn't contained within 1 line, then there is an error. 如果每对点未包含在1行内,则存在错误。

Heres the method, but keep in mind there are several proprietary classes involved. 这是方法,但请记住,涉及几个专有类。

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM