Saya punya beberapa kode yang saya gunakan untuk menentukan Shapely Polygon / MultiPolygons berpotongan dengan sejumlah Shapely LineStrings. Melalui jawaban atas pertanyaan ini , kodenya telah berubah dari ini:
import fiona
from shapely.geometry import LineString, Polygon, MultiPolygon, shape
# Open each layer
poly_layer = fiona.open('polygon_layer.shp')
line_layer = fiona.open('line_layer.shp')
# Convert to lists of shapely geometries
the_lines = [shape(line['geometry']) for line in line_layer]
the_polygons = [(poly['properties']['GEOID'], shape(poly['geometry'])) for poly in poly_layer]
# Check for Polygons/MultiPolygons that the LineString intersects with
covered_polygons = {}
for poly_id, poly in the_polygons:
for line in the_lines:
if poly.intersects(line):
covered_polygons[poly_id] = covered_polygons.get(poly_id, 0) + 1
di mana setiap persimpangan yang mungkin diperiksa, untuk ini:
import fiona
from shapely.geometry import LineString, Polygon, MultiPolygon, shape
import rtree
# Open each layer
poly_layer = fiona.open('polygon_layer.shp')
line_layer = fiona.open('line_layer.shp')
# Convert to lists of shapely geometries
the_lines = [shape(line['geometry']) for line in line_layer]
the_polygons = [(poly['properties']['GEOID'], shape(poly['geometry'])) for poly in poly_layer]
# Create spatial index
spatial_index = rtree.index.Index()
for idx, poly_tuple in enumerate(the_polygons):
_, poly = poly_tuple
spatial_index.insert(idx, poly.bounds)
# Check for Polygons/MultiPolygons that the LineString intersects with
covered_polygons = {}
for line in the_lines:
for idx in list(spatial_index.intersection(line.bounds)):
if the_polygons[idx][1].intersects(line):
covered_polygons[idx] = covered_polygons.get(idx, 0) + 1
di mana indeks spasial digunakan untuk mengurangi jumlah pemeriksaan persimpangan.
Dengan shapefile yang saya miliki (sekitar 4000 poligon, dan 4 baris), kode asli melakukan 12936 .intersection()
pemeriksaan dan membutuhkan waktu sekitar 114 detik untuk dijalankan. Sepotong kode kedua yang menggunakan indeks spasial hanya melakukan 1816 .intersection()
pemeriksaan tetapi juga membutuhkan waktu sekitar 114 detik untuk dijalankan.
Kode untuk membangun indeks spasial hanya membutuhkan waktu 1-2 detik untuk dijalankan, sehingga pemeriksaan 1816 pada potongan kode kedua menghabiskan waktu yang hampir sama untuk melakukan sebagaimana 12936 memeriksa dalam kode asli (sejak pemuatan shapefile dan mengkonversi ke geometri Shapely adalah sama di kedua bagian kode).
Saya tidak dapat melihat alasan mengapa indeks spasial akan membuat .intersects()
cek lebih lama, jadi saya bingung mengapa ini terjadi.
Saya hanya bisa berpikir bahwa saya menggunakan indeks spasial RTree secara tidak benar. Pikiran?
sumber
intersects()
Metode membutuhkan waktu lebih lama ketika indeks spasial yang digunakan (lihat perbandingan waktu di atas), itulah sebabnya saya tidak yakin jika saya menggunakan indeks spasial tidak benar. Dari membaca dokumentasi dan posting yang terhubung saya pikir saya, tetapi saya berharap seseorang dapat menunjukkan jika saya tidak.Tambahkan saja ke mgri jawab.
Penting untuk memahami apa itu indeks spasial ( Bagaimana Cara Menerapkan Kotak Bounding untuk Shapely & Fiona? ). Dengan contoh saya di Bagaimana cara efisien menentukan mana dari ribuan poligon bersinggungan dengan linestring
Anda dapat membuat indeks spasial dengan poligon
Batas indeks spasial (batas poligon berwarna hijau)
Atau dengan LineStrings
Batas indeks spasial (LineString terikat warna merah)
Sekarang, Anda beralih hanya melalui geometri yang memiliki kesempatan untuk berpotongan dengan geometri Anda saat ini (berwarna kuning)
Saya menggunakan di sini indeks spasial LineStrings (hasilnya sama tetapi dengan contoh Anda 4000 poligon dan 4 baris ....).
Anda juga dapat menggunakan generator ( example.py )
Anda dapat memeriksa skrip GeoPandas sjoin.py untuk memahami penggunaan Rtree .
Ada banyak solusi tetapi jangan lupakan itu
sumber
Sunting: Untuk memperjelas jawaban ini, saya salah meyakini bahwa semua tes persimpangan memakan waktu yang kira-kira sama. Ini bukan kasusnya. Alasan saya tidak mendapatkan kecepatan yang saya harapkan dari menggunakan indeks spasial adalah bahwa pemilihan tes persimpangan adalah yang paling lama dilakukan di tempat pertama.
Seperti yang dikatakan oleh gen dan mgri, indeks spasial bukanlah tongkat ajaib. Meskipun indeks spasial mengurangi jumlah tes persimpangan yang perlu dilakukan dari 12936 menjadi hanya 1816, tes 1816 adalah tes yang mengambil sebagian besar waktu untuk menghitung di tempat pertama.
Indeks spasial digunakan dengan benar, tetapi asumsi bahwa setiap tes persimpangan memakan waktu yang kira-kira sama adalah yang salah. Waktu yang dibutuhkan oleh uji persimpangan dapat sangat bervariasi (0,05 detik versus 0,000007 detik).
sumber