Определите «левую» и «правую» стороны расщепленной стройной геометрии - PullRequest
0 голосов
/ 17 мая 2018

Мой вопрос: как я могу определить, какая из Aside и Bside сторон уже повернутой прямоугольной геометрии является "левой" и "правой" стороной произвольной LineString что разбивает эту геометрию?

Для целей этой задачи «левый» и «правый» определяются как левая и правая сторона сплиттера LineString при «ходьбе» от узла к узлу по порядку.

Я создал эту функцию для разбиения любой произвольной shapely геометрии (не коллекции) на две стороны - «левую» и «правую»:

import shapely.geometry as geo
import shapely.ops as ops

def splitLR(geom, splitter):
    """Split a geometry into a 'left' and 'right' side using the shapely API"""
    if not isinstance(splitter, geo.LineString):
        raise TypeError("The splitter must be a LineString")
    if not splitter.is_simple:
        raise ValueError("Only simple splitter objects allowed")
    if hasattr(geom, "__iter__"):
        raise ValueError("Geometry collections not allowed")
    geom_extents = geo.GeometryCollection([geom, splitter]).minimum_rotated_rectangle
    sides = ops.split(geom_extents, splitter)
    try:
        Aside, Bside = sides
    except TypeError:
        # only 1 result - rotated rectangle wasn't split
        if len(ops.split(geom,splitter)) == 1:
            # geom isn't split by splitter
            raise ValueError("the splitter does not appear to split the geometry")
        else:
            # splitter too small for algorithm
            raise ValueError("the splitter must extend beyond minimum_rotated_rectangle "
                             "of the combined geometry")
    # determine which is Lside and Rside here
    Lside,Rside = get_LRsides(Aside, Bside, splitter)
    return tuple(side.intersection(geom) for side in (Lside, Rside))

Идея вышесказанного проиллюстрирована в блокноте, связанном здесь (та же ссылка, что и выше):

http://nbviewer.jupyter.org/urls/dl.dropbox.com/s/ll3mchnx0jwzjnf/determine%20left-right%20split.ipynb

Подводя итог: стороны A и B - это две стороны minimum_rotated_rectangle, окружающие геометрию geom и строку splitter вместе. Когда выполняется side.intersection(geom), результатом является часть изначально заданной геометрии geom, содержащейся на этой стороне.

Примечания:

  • для объектов типа "картошка" странной формы возможно, чтобы это пересечение приводило к нескольким объектам с одной или обеих сторон (см. Пример nbviewer)
  • Я создал здесь свою собственную функцию (вместо того, чтобы использовать ops.split), потому что функция ops.split просто возвращает «мешок» разделенных объектов, и нет способа определить, на какой стороне они находятся (что Я в курсе)

В настоящее время мой вызов get_LRsides просто выполняет эту функцию, которая явно бесполезна:

def get_LRsides(Aside, Bside, splitter):
    """Determine the 'left' and 'right' sides of an already split geometry"""
    return Aside,Bside

Как я могу успешно пометить A и B как "левый" и "правый"?

1 Ответ

0 голосов
/ 15 июня 2018

Это может работать:

  1. Форма a LinearRing с конечными точками сплиттера и точкой в ​​стороне
  2. Применить object.is_ccw
  3. Если он возвращает True, слева от разделителя находится Aside.

https://shapely.readthedocs.io/en/stable/manual.html#object.is_ccw

...