Các nút:
Bạn muốn hai thứ, điểm cuối của polylines (không có nút trung gian) và điểm giao nhau. Có một vấn đề khác, một số điểm cuối của polylines cũng là điểm giao nhau:
Một giải pháp là sử dụng Python và các mô-đun Shapely và Fiona
1) Đọc shapefile:
from shapely.geometry import Point, shape
import fiona
lines = [shape(line['geometry']) for line in fiona.open("your_shapefile.shp")]
2) Tìm điểm cuối của các dòng ( làm thế nào để có được điểm cuối của một đa tuyến? ):
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) Tính toán các giao điểm (lặp qua các cặp hình học trong lớp với mô đun itertools ). Kết quả của một số giao điểm là MultiPoints và chúng tôi muốn có một danh sách các điểm:
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) Loại bỏ trùng lặp giữa điểm cuối và điểm giao nhau (như bạn có thể thấy trong hình)
result = endpts.extend([pt for pt in inters if pt not in endpts])
5) Lưu shapefile kết quả
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}})
Kết quả cuối cùng:
Các đoạn đường
Nếu bạn cũng muốn các phân đoạn giữa các nút, bạn cần "planarize" ( Đồ thị phẳng , không có cạnh nào giao nhau) shapefile của bạn. Điều này có thể được thực hiện bởi các unary_union chức năng của kiểu dáng cân đối
from shapely.ops import unary_union
graph = unary_union(lines)