确定分割形状几何体的“左”和“右”侧

时间:2018-05-17 14:14:23

标签: python shapely

我的问题是:如何确定an already split rotated rectangular geometrycharsetAside方面中的哪一方是任意Bside的“左”和“右”方?分裂那个几何?

出于这个问题的目的,“左”和“右”被定义为LineString分离器在从节点到节点“行走”时的左手侧和右手侧。 / p>

我创建了这个函数,用于将任意任意LineString几何(非集合)分成两个部分 - “左”和“右”:

shapely

上面的想法在这里链接的笔记本中说明(与上面相同的链接):

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

总结:A面和B面是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)) 几何体周围的minimum_rotated_rectanglegeom线字符串的两面。执行splitter时,结果是该方包含的原始给定几何side.intersection(geom)的部分。

注意:

  • 可能 - 对于形状奇特的“马铃薯”型物体 - 这个交叉点会在一侧或两侧产生多个物体(参见nbviewer示例)
  • 我在这里创建了自己的函数(而不是使用geom),因为ops.split函数只返回一个拆分对象的“包”,并且没有办法确定它们在哪一边是(我知道)

目前我对ops.split的调用只执行此功能,这显然毫无价值:

get_LRsides

如何成功将A和B标记为“左”和“右”?

2 个答案:

答案 0 :(得分:2)

这可行:

  1. 使用分割器的端点和Aside
  2. 中的一个点形成LinearRing
  3. 申请object.is_ccw
  4. 如果它返回True,则旁边是分割器的左侧。
  5. https://shapely.readthedocs.io/en/stable/manual.html#object.is_ccw

答案 1 :(得分:0)

我不是工具箱中最敏锐的 GIS 工具,并且正在努力弄清楚如何在接受的答案中向 LinearRing 中“添加一个点”。这是我可以用它代替的技巧。

我将相交拆分器 LineString 的两个点投影到第一个多边形的外部,这为我提供了沿该外部线串的距离。如果该距离增加,则第一个多边形是分裂的“右侧”。

这是一个示例代码:

from shapely.ops import split
from shapely.geometry import Polygon, LineString, Point


def rhs_split(poly, splitter):
    intersect_splitter = splitter.intersection(poly)
    geomcollect = split(poly, splitter)
    polya, polyb = geomcollect.geoms[0], geomcollect.geoms[1]
    # Test directionality
    pt0 = Point(intersect_splitter.coords[0])
    pt1 = Point(intersect_splitter.coords[1])
    start_dist = polya.exterior.project(pt0)
    end_dist = polya.exterior.project(pt1)
    return polya if end_dist > start_dist else polyb


print(
    rhs_split(
        Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]),
        LineString([(0.5, -0.1), (0.5, 1.1)]),
    )
)
# POLYGON ((0.5 1, 1 1, 1 0, 0.5 0, 0.5 1))
print(
    rhs_split(
        Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]),
        LineString([(0.5, 1.1), (0.5, -0.1)]),
    )
)
# POLYGON ((0 0, 0 1, 0.5 1, 0.5 0, 0 0))