我的问题是:如何确定an already split rotated rectangular geometry的charset
和Aside
方面中的哪一方是任意Bside
的“左”和“右”方?分裂那个几何?
出于这个问题的目的,“左”和“右”被定义为LineString
分离器在从节点到节点“行走”时的左手侧和右手侧。 / p>
我创建了这个函数,用于将任意任意LineString
几何(非集合)分成两个部分 - “左”和“右”:
shapely
上面的想法在这里链接的笔记本中说明(与上面相同的链接):
总结: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_rectangle
和geom
线字符串的两面。执行splitter
时,结果是该方包含的原始给定几何side.intersection(geom)
的部分。
注意:
geom
),因为ops.split
函数只返回一个拆分对象的“包”,并且没有办法确定它们在哪一边是(我知道)目前我对ops.split
的调用只执行此功能,这显然毫无价值:
get_LRsides
如何成功将A和B标记为“左”和“右”?
答案 0 :(得分:2)
这可行:
LinearRing
object.is_ccw
True
,则旁边是分割器的左侧。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))