Tentang data pengujian saya:
- Seperti Data Jalan OSM, setiap geometri jalan berakhir di perempatan.
- Setiap jalan memiliki ID unik.
SOLUSI I
Jika ada dua asumsi:
Jalan membangun perempat.
Anda bekerja dalam sistem metrik.
Idenya adalah untuk menambah / mengurangi koordinat X dan Y dari titik tersebut. Jika Anda bekerja dalam sistem metrik, Anda dapat pergi 1 m ke Timur dari titik Anda, buat titik baru dan buat garis dengan titik asli. Anda akan pergi lebih jauh ke Timur sampai garis memotong jalan. Untuk mencari persimpangan di Barat, Anda harus mengurangi 1m dari koordinat X asli. Hal yang sama untuk koordinat Y. Jika tidak ada jalan di Utara / Timur / Selatan / Barat konter berhenti di 1000 (m). Ketika Anda tahu mungkin ada jalan dalam jarak lebih dari 1000m Anda harus mengubah nilai ini.
Anda bisa menyelesaikan tugas dengan kode berikut:
Diedit
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "point":
startpoint = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "roads":
roads = lyr
startpoint_iter = startpoint.getFeatures()
for feature in startpoint_iter:
geom = feature.geometry()
if geom.type() == QGis.Point:
xy = geom.asPoint()
x,y = xy[0], xy[1]
line_start = QgsPoint(x,y)
def reached(direction, count_m):
road_reached = None
road = None
count=1
while road_reached < 1 and count <=count_m:
count += 1
if direction == 'N':
line_end = QgsPoint(x, y+count)
if direction == 'E':
line_end = QgsPoint(x+count,y)
if direction == 'S':
line_end = QgsPoint(x,y-count)
if direction == 'W':
line_end = QgsPoint(x-count,y)
line = QgsGeometry.fromPolyline([line_start,line_end])
for f in roads.getFeatures():
if line.intersects(f.geometry()):
road_reached = 1
road = f['name']
print road
reached('N', 1000)
reached('E', 1000)
reached('S', 1000)
reached('W', 1000)
Contoh lain untuk menunjukkan bahwa jalan e di Timur tidak diakui sebagai jalan terdekat dari titik tersebut.
Cara memanggil fungsi dan output:
>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d
Jika ada lebih dari 4 jalan yang melingkupi titik Anda harus melihat lebih banyak arah (ubah X dan Y). Atau Anda dapat mengubah azimuth garis Anda, berarti Anda dapat memutarnya satu derajat dalam kisaran 0-360 °.
SOLUSI II
Terinspirasi dari komentar kamu juga bisa Polygonize
jalan kamu dulu. Maka Anda dapat menggunakan alat dari QGIS: Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize
. Ubah nama layer sementara menjadi polygon
. Dengan asumsi bahwa Anda hanya ingin memiliki nama jalan untuk titik yang sepenuhnya tertutup oleh jalan. Jika tidak, Anda harus menggunakan SOLUSI saya . Ini hanya berfungsi jika semua jalan terhubung (bentak)!
Pertama, titik harus bersinggungan dengan poligon. Idenya adalah sekarang bahwa keduanya, AND
titik akhir mulai dari garis penutup harus bersinggungan dengan poligon.
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "point":
startpoint = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "polygon":
poly = lyr
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "roads":
roads = lyr
for h in startpoint.getFeatures():
for g in poly.getFeatures():
if h.geometry().intersects(g.geometry()):
poly_geom = g.geometry()
for f in roads.getFeatures():
geom = f.geometry().asPolyline()
start_point = QgsGeometry.fromPoint(QgsPoint(geom[0]))
end_point = QgsGeometry.fromPoint(QgsPoint(geom[-1]))
if poly_geom.intersects(start_point) and poly_geom.intersects(end_point):
print f['name']
Hasil:
road c
road b
road e
road f