Строка (JTS) входит или выходит из полигона

Если у меня есть linestring в JTS (или вообще какая-то открытая полилиния) с направлением, определяемым начальной точкой, есть ли какой-нибудь умный способ определить на пересечениях с закрытым polygon, «входит» ли linestring в полигон или выходит из него , либо:

  • В JRS (я не могу найти способ в документах) только координаты, где линия и замкнутая форма пересекаются с intersection
  • Какой-то общий хитрый способ. В настоящее время я сделал это, проверяя точку на очень небольшом расстоянии вдоль linestring по обе стороны от polygon края и проверяя, что было «внутри», а что «наружу». Вероятно, это могло бы вернуть неверный результат, если бы polygon имел (маловероятно) ДЕЙСТВИТЕЛЬНО острую внутреннюю кромку.

person Jon    schedule 14.08.2016    source источник


Ответы (2)


Проверьте, находится ли начальная точка сегмента linestring внутри полигона или снаружи, чтобы выяснить, входит ли он в polygon или выходит из него. Простой пример кода:

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

Этот код не охватывает все возможности. Например. если отдельные сегменты пересекают многоугольник несколько раз (вход + выход), это не рассматривается в этом примере. В этом случае просто подсчитайте количество пересечений и создайте соответствующее количество линий между точками пересечения.

person Lars    schedule 14.08.2016

Отвечая на мой собственный вопрос - для тех, у кого есть аналогичная проблема. В итоге я написал немного кода на основе количества пересечений (поскольку они уже были у меня через JTS). Идеи основаны на материалах из алгоритма пересекающихся чисел и четно-нечетное правило.

«Правила» (я не думаю, что есть исключения, вероятно, неправильные):

  1. За въездом на перекресток должен следовать выезд, и наоборот.
  2. Если вы начинаете в замкнутом многоугольнике, первая точка пересечения является выходом.
  3. Если вы не начинаете в многоугольнике, первое пересечение является входом.

Как псевдокод, что-то вроде этого:

    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.

Не просматривал исходный код для методов JTS intersect и contains, поэтому может быть некоторое удвоение того, что я делаю, и некоторая оптимизация.

person Jon    schedule 27.08.2016