Saya mencoba untuk mengambil dua baris satu sama lain menggunakan Shapely / Geopandas tetapi hasil gertakan sangat aneh. Saya mencoba :
import geopandas as gpd
from shapely.geometry import *
from shapely.ops import snap
lines1 = gpd.GeoDataFrame.from_file('lines1.shp')
lines1 = lines1.to_crs({'init': 'epsg:2227'})
lines2 = gpd.GeoDataFrame.from_file('lines2.shp')
lines2 = lines2.to_crs({'init': 'epsg:2227'})
res = lines1
lines2_union = lines2.geometry.unary_union
res.geometry = res.geometry.apply(lambda x: snap(x, lines2_union, 14))
res.to_file('result.shp', driver="ESRI Shapefile")
Dan dapatkan hasil ini:
lines1 = garis merah
lines2 = garis hitam
Setelah gertakan (dengan 14 sebagai toleransi): garis biru adalah hasil gertakan
Dalam hal ini, garis-garisnya terpotong dengan benar
Contoh lain di mana itu tidak berfungsi seperti yang diharapkan: (sebelum gertakan)
Dan inilah hasilnya setelah patah. Hanya sebagian yang tersentak ke garis hitam (sisi selatan). Meskipun garis aslinya cukup dekat dan dalam 14 kaki
Jika saya meningkatkan toleransi, saya mendapatkan output yang salah, kira-kira seperti ini (setelah mendefinisikan 20 sebagai toleransi dari gertakan, garis hijau adalah hasilnya):
Adakah ide mengapa gertakan tidak berfungsi dengan baik? Ada saran tentang cara mengatasi masalah ini?
Jawaban:
The
shapely.ops.snap
Fungsi terkunci ke simpul dari geometri saja.Lihat ilustrasi di bawah ini. Di sebelah kiri, simpul merah berada dalam toleransi gertakan ke simpul biru, sehingga akan patah. Di sebelah kanan titik merah berada di luar toleransi gertakan (meskipun lebih dekat ke tepi!).
Shapely tidak menyediakan algoritma untuk menjentikkan simpul ke tepi. Seharusnya tidak terlalu sulit untuk menulis satu menggunakan
shapely.ops.nearest_points
. Sesuatu seperti ini (tidak diuji, dan tidak terlalu efisien):sumber
if p1.distance(p2 <= threshold):
seharusnyaif p1.distance(p2) <= threshold: