Мой вопрос: как я могу определить, какая из 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 как "левый" и "правый"?