简体   繁体   中英

Is (JTS) linestring is entering or exiting a polygon

If I have a linestring in JTS (or some sort of open polyline generally) with its direction defined by it start point, is there some smart way to tell at intersections with a closed polygon whether the linestring is 'entering' the polygon or exiting it, either:

  • In JRS ( I cant find a way in docs), only the coordinates where the line and closed shape intersect with intersection
  • Some general clever way. I currently have done it by testing a point a very small distance, along linestring on either side of polygon edge and testing which was 'in', and which was 'out'. This could conceivably return an incorrect result if the polygon had a (unlikely) REALLY sharp internal edge.

Check if the startpoint of a segment of the linestring is inside the polygon or outside to figure out if it is entering or exiting the polygon . Simple code example:

// some demo polygon + line
Polygon polygon = new GeometryFactory().createPolygon(new Coordinate[]{new Coordinate(1,1), new Coordinate(6,1), new Coordinate(6,6), new Coordinate(1,6), new Coordinate(1,1)});
LineString line = new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(0, 0), new Coordinate(5,5), new Coordinate(10,5)});

// check for intersection in the first place
if(line.intersects(polygon)){
    System.out.println("line intersects polygon!");
    // iterate over all segments of the linestring and check for intersections
    for(int i = 1; i < line.getNumPoints(); i++){
        // create line for current segment
        LineString currentSegment = new GeometryFactory().createLineString(new Coordinate[]{line.getCoordinates()[i-1], line.getCoordinates()[i]});
        // check if line is intersecting with ring
        if(currentSegment.intersects(polygon)){
            // segment is entering the ring if startpoint is outside the ring
            if(!polygon.contains(currentSegment.getStartPoint())){
                System.out.println("This segment is entering the polygon -> ");
                System.out.println(currentSegment.toText());
            // startpoint is inside the ring
            }
            if (polygon.contains(currentSegment.getStartPoint())) {
                System.out.println("This segment is exiting the polygon -> ");
                System.out.println(currentSegment.toText());
            }
        }
    }
} else {
    System.out.println("line is not intersecting the polygon!");
}

This code does not cover all possibilities. Eg if single segments are intersecting the polygon multiple times (entering + exiting) this is not covered in this example. In this case just count the number of intersections and create the according number of linestrings between the intersection points.

Answering my own question - for anyone who has similar problem. I ended up writing a bit of code based on number of intersections (since I had these already via JTS). Ideas stemmed on stuff from crossing number algorithm and odd-even rule .

The 'rules' ( I do not think there are exceptions, probably wrong) are:

  1. An enter intersection must be followed by an exit, and vice versa.
  2. If you start in the closed polygon, the first intersection point is an exit.
  3. If you do not start in the polygon, the first intersection is an enter.

As pseudocode, something like this:

    Get intersection_points between polyline and closed polygon // using JTS.intersect()
    Sort intersection_points along chainage of polyline
    if polyline start_point in polygon // using JTS.contains()
        first intersect_point is an EXIT, next is an ENTER, EXIT, ENTER and so on alternating along chainage.
    else //start point not in polygon
        first intersect_point is an ENTER, next is an EXIT, ENTER, EXIT and so on along chainage.

Haven't looked at source for JTS intersect and contains methods so might be some doubling in what I am doing and some optimisation there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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