问题描述
我想从MultiLinestring
过滤掉所有短(例如,length MultiLinestring。对于孤立的行,我的意思是那些不会touch或intersect其他人。
from shapely.geometry import MultiLinestring
from pprint import pprint
from matplotlib import pyplot
from figures import SIZE,set_limits,plot_line,plot_bounds,color_issimple
from figures import plot_coords as _plot_coords
def plot_coords(ax,ob):
for line in ob:
_plot_coords(ax,line,zorder=1)
def plot_lines(ax,ob):
color = color_issimple(ob)
for line in ob:
plot_line(ax,color=color,alpha=0.7,zorder=2)
fig = pyplot.figure(1,figsize=SIZE,dpi=90)
#1: line1 original
ax = fig.add_subplot(121)
mline1 = MultiLinestring([((0,0),(2,0)),((1,(1,1)),2),(3,2)),((3,1))])
plot_coords(ax,mline1)
plot_bounds(ax,mline1)
plot_lines(ax,mline1)
ax.set_title('a) original')
set_limits(ax,-1,4,3)
#2: line2 goal
ax = fig.add_subplot(122)
mline2 = MultiLinestring([((0,2))])
plot_coords(ax,mline2)
plot_bounds(ax,mline2)
plot_lines(ax,mline2)
ax.set_title('b) goal')
set_limits(ax,3)
pyplot.show()
因此,这可以分为两个子问题:
- 如何选择所有隔离的行?
- 如何按长度过滤这些隔离的线?
第二个问题大概可以这样解决:
filtered = [line for line in list(mline1) if line.length<2]
解决方法
解决方案:
from shapely.geometry import MultiLineString
from pprint import pprint
from matplotlib import pyplot
from figures import SIZE,set_limits,plot_line,plot_bounds,color_issimple
from figures import plot_coords as _plot_coords
def plot_coords(ax,ob):
for line in ob:
_plot_coords(ax,line,zorder=1)
def plot_lines(ax,ob):
color = color_issimple(ob)
for line in ob:
plot_line(ax,color=color,alpha=0.7,zorder=2)
fig = pyplot.figure(1,figsize=SIZE,dpi=90)
# 3: line3 lines that intersecting each other
mline1 = MultiLineString([((0,0),(2,0)),((1,(1,1)),2),(3,2)),((3,1))])
ax = fig.add_subplot(121)
# append all intersecting lines,this will create duplicates for lines
# intersecting more than one line
intersection = []
for i in range(len(mline1)):
for j in range(i + 1,len(mline1)):
if mline1[i].intersects(mline1[j]):
intersection.append(mline1[i])
intersection.append(mline1[j])
# remove duplicates
uniq_intersection = []
for line in intersection:
if not any(p.equals(line) for p in uniq_intersection):
uniq_intersection.append(line)
uniq_intersection = MultiLineString(uniq_intersection)
plot_coords(ax,uniq_intersection)
plot_bounds(ax,uniq_intersection)
plot_lines(ax,uniq_intersection)
ax.set_title('c) intersection')
set_limits(ax,-1,4,3)
# 4: line4 filtered lines
ax = fig.add_subplot(122)
isolated = [line for line in mline1 if line not in uniq_intersection]
# filter by length
isolated_short = [line for line in isolated if line.length < 2]
filtered = [line for line in mline1 if line not in isolated_short]
filtered = MultiLineString(filtered)
plot_coords(ax,filtered)
plot_bounds(ax,filtered)
plot_lines(ax,filtered)
ax.set_title('d) filtered')
set_limits(ax,3)
pyplot.show()