import numpy as np from functools import partial from shapely.geometry import Point, LineString from shapely.ops import substring, split, linemerge class removeRingOnLineSting(): # 去除自相交线上的小环 # 基本思路 1 定位自相交点 2 自相交点分割线 3 分割线合并 根据长度筛选最长的两个 # todo1 如环上环 def __init__(self, ls, torelance=1): self.ls = ls self.torelance = torelance def crossPoint(self): # 定位自相交点 N = int(self.ls.length) // self.torelance sp = np.linspace(0, 1, N)[1:-1] pfun = partial(substring, geom=self.ls, normalized=1) cp = set() for p in sp: t1 = pfun(start_dist=0, end_dist=p) tp = pfun(start_dist=p, end_dist=p) t2 = pfun(start_dist=p, end_dist=1) if not t1.touches(t2): mp = [_ for _ in t1.intersection(t2).geoms if _ != tp] cp.update(mp) return cp def removeRing(self): sp = self.crossPoint() for p in sp: mls = split(self.ls, p.buffer(self.torelance/2)) mls = [_ for _ in mls.geoms] mls = sorted(mls, key=lambda x: x.length) line1, line2 = mls[-2:] self.ls = self.mergeLineWithGap(line1, line2) return self.ls @staticmethod def mergeLineWithGap(line1, line2, torelance=3): ps1, pe1 = Point(line1.coords[0]), Point(line1.coords[-1]) ps2, pe2 = Point(line2.coords[0]), Point(line2.coords[-1]) if ps1.distance(pe2) > pe1.distance(ps2): gap_line = LineString([pe1, ps2]) return linemerge([line1, gap_line, line2]) else: gap_line = LineString([pe2, ps1])
return linemerge([line2, gap_line, line1]) if __name__ == "__main__": pnts = [(-7,0), (1,0), (1,1), (0,1), (0,-2), (-1,-2),(-1,-1),(7,-1)] ls = LineString(pnts) algo = removeRingOnLineSting(ls) rls = algo.removeRing()
标签:__,self,line2,相交,mls,ls,line1,剔除,线上 From: https://www.cnblogs.com/ddzhen/p/18061444