노드 :
폴리 라인의 끝점 (중간 노드 없음)과 교차점의 두 가지를 원합니다. 추가 문제가 있지만 일부 폴리선 끝점은 교차점이기도합니다.
해결책은 Python과 Shapely 및 Fiona 모듈을 사용하는 것입니다
1) shapefile을 읽으십시오.
from shapely.geometry import Point, shape
import fiona
lines = [shape(line['geometry']) for line in fiona.open("your_shapefile.shp")]
2) 선의 끝점을 찾으십시오 ( 어떻게 폴리선의 끝점을 얻습니까? ) :
endpts = [(Point(list(line.coords)[0]), Point(list(line.coords)[-1])) for line in lines]
# flatten the resulting list to a simple list of points
endpts= [pt for sublist in endpts for pt in sublist]
3) 교차점을 계산합니다 ( itertools 모듈 을 사용하여 레이어의 형상 쌍을 통해 반복 ). 일부 교차점의 결과는 MultiPoint이며 점 목록을 원합니다.
import itertools
inters = []
for line1,line2 in itertools.combinations(lines, 2):
if line1.intersects(line2):
inter = line1.intersection(line2)
if "Point" == inter.type:
inters.append(inter)
elif "MultiPoint" == inter.type:
inters.extend([pt for pt in inter])
elif "MultiLineString" == inter.type:
multiLine = [line for line in inter]
first_coords = multiLine[0].coords[0]
last_coords = multiLine[len(multiLine)-1].coords[1]
inters.append(Point(first_coords[0], first_coords[1]))
inters.append(Point(last_coords[0], last_coords[1]))
elif "GeometryCollection" == inter.type:
for geom in inter:
if "Point" == geom.type:
inters.append(geom)
elif "MultiPoint" == geom.type:
inters.extend([pt for pt in geom])
elif "MultiLineString" == geom.type:
multiLine = [line for line in geom]
first_coords = multiLine[0].coords[0]
last_coords = multiLine[len(multiLine)-1].coords[1]
inters.append(Point(first_coords[0], first_coords[1]))
inters.append(Point(last_coords[0], last_coords[1]))
4) 끝점과 교차점 사이의 중복을 제거하십시오 (그림에서 볼 수 있듯이)
result = endpts.extend([pt for pt in inters if pt not in endpts])
5) 결과 shapefile을 저장하십시오
from shapely.geometry import mapping
# schema of the shapefile
schema = {'geometry': 'Point','properties': {'test': 'int'}}
# creation of the shapefile
with fiona.open('result.shp','w','ESRI Shapefile', schema) as output:
for i, pt in enumerate(result):
output.write({'geometry':mapping(pt), 'properties':{'test':i}})
최종 결과:
선분
노드 사이의 세그먼트를 원한다면 shapefile 을 "평면화"( 평면 그래프 , 가장자리가 서로 교차하지 않음)해야합니다. 이것은 Shapely 의 unary_union 함수 로 수행 할 수 있습니다
from shapely.ops import unary_union
graph = unary_union(lines)