Saya mencari cara untuk secara otomatis mendefinisikan lingkungan di kota-kota sebagai poligon pada grafik.
Definisi saya tentang suatu lingkungan memiliki dua bagian:
- Blok : Suatu area yang dilingkupi antara sejumlah jalan, di mana jumlah jalan (tepi) dan persimpangan (simpul) minimal tiga (satu segitiga).
- Lingkungan : Untuk setiap blok yang diberikan, semua blok berbatasan langsung dengan blok itu dan blok itu sendiri.
Lihat ilustrasi ini sebagai contoh:
Misalnya B4 adalah blok yang didefinisikan oleh 7 node dan 6 tepi yang menghubungkannya. Seperti sebagian besar contoh di sini, blok lain didefinisikan oleh 4 node dan 4 edge yang menghubungkannya. Juga, lingkungan dari B1 meliputi B2 (dan sebaliknya) sementara B2 juga termasuk B3 .
Saya menggunakan osmnx untuk mendapatkan data jalan dari OSM.
- Menggunakan osmnx dan networkx, bagaimana saya bisa melintasi grafik untuk menemukan node dan tepi yang mendefinisikan setiap blok?
- Untuk setiap blok, bagaimana saya bisa menemukan blok yang berdekatan?
Saya bekerja sendiri menuju sepotong kode yang mengambil grafik dan sepasang koordinat (lintang, bujur) sebagai input, mengidentifikasi blok yang relevan dan mengembalikan poligon untuk blok itu dan lingkungan seperti yang didefinisikan di atas.
Berikut adalah kode yang digunakan untuk membuat peta:
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
G = ox.graph_from_address('Nørrebrogade 20, Copenhagen Municipality',
network_type='all',
distance=500)
dan usaha saya menemukan klik dengan jumlah node dan derajat yang berbeda.
def plot_cliques(graph, number_of_nodes, degree):
ug = ox.save_load.get_undirected(graph)
cliques = nx.find_cliques(ug)
cliques_nodes = [clq for clq in cliques if len(clq) >= number_of_nodes]
print("{} cliques with more than {} nodes.".format(len(cliques_nodes), number_of_nodes))
nodes = set(n for clq in cliques_nodes for n in clq)
h = ug.subgraph(nodes)
deg = nx.degree(h)
nodes_degree = [n for n in nodes if deg[n] >= degree]
k = h.subgraph(nodes_degree)
nx.draw(k, node_size=5)
Teori yang mungkin relevan:
Jawaban:
Mengejar blok kota menggunakan grafik sangat mengejutkan. Pada dasarnya, ini sama dengan menemukan set cincin terkecil terkecil (SSSR), yang merupakan masalah NP-complete. Ulasan masalah ini (dan masalah terkait) dapat ditemukan di sini . Pada SO, ada satu deskripsi algoritma untuk menyelesaikannya di sini . Sejauh yang saya tahu, tidak ada implementasi yang sesuai di
networkx
(atau dalam python dalam hal ini). Saya mencoba pendekatan ini secara singkat dan kemudian meninggalkannya - otak saya tidak siap untuk pekerjaan seperti itu hari ini. Yang sedang berkata, saya akan memberikan hadiah kepada siapa pun yang mungkin mengunjungi halaman ini di kemudian hari dan memposting implementasi teruji dari sebuah algoritma yang menemukan SSSR dalam python.Saya malah mengejar pendekatan yang berbeda, memanfaatkan fakta bahwa grafik dijamin planar. Secara singkat, alih-alih memperlakukan ini sebagai masalah grafik, kami memperlakukan ini sebagai masalah segmentasi gambar. Pertama, kami menemukan semua wilayah yang terhubung dalam gambar. Kami kemudian menentukan kontur di sekitar setiap wilayah, mengubah kontur dalam koordinat gambar kembali ke garis bujur dan garis lintang.
Diberikan impor dan definisi fungsi berikut:
Muat data. Cache impor, jika menguji ini berulang kali - jika tidak akun Anda dapat diblokir. Berbicara dari pengalaman di sini.
Pangkas node dan tepi yang tidak bisa menjadi bagian dari siklus. Langkah ini tidak sepenuhnya diperlukan tetapi menghasilkan kontur yang lebih bagus.
Konversikan plot ke gambar dan temukan wilayah yang terhubung:
Untuk setiap wilayah berlabel, temukan kontur dan ubah koordinat piksel kontur kembali ke koordinat data.
Tentukan semua titik dalam grafik asli yang termasuk dalam (atau pada) kontur.
Mencari tahu jika dua blok adalah tetangga cukup mudah. Periksa apakah mereka berbagi simpul:
sumber
Saya tidak sepenuhnya yakin itu
cycle_basis
akan memberi Anda lingkungan yang Anda cari, tetapi jika ya, itu adalah hal yang sederhana untuk mendapatkan grafik lingkungan dari itu:sumber
nx.Graph(G)
saya kehilangan banyak informasi (keteraturan dan tipe multigraf) jadi saya mengalami kesulitan memverifikasi jawaban Anda, karena saya sepertinya tidak bisa menghubungkan grafik baruI
ke grafik asli sayaG
.Saya tidak punya kode, tapi saya rasa begitu saya berada di trotoar, jika saya terus berbelok ke kanan di setiap sudut, saya akan siklus melalui tepi blok saya. Saya tidak tahu perpustakaan jadi saya hanya akan berbicara algo di sini.
Sebenarnya ini adalah algoritma yang digunakan untuk keluar dari labirin: jaga tangan kanan Anda di dinding dan berjalan. Ini tidak berfungsi jika loop di labirin, Anda hanya berputar-putar. Tetapi itu memberikan solusi untuk masalah Anda.
sumber
Ini adalah implementasi dari ide Hashemi Emad . Ini bekerja dengan baik selama posisi awal dipilih sedemikian rupa sehingga ada cara untuk melangkah berlawanan arah dalam lingkaran yang ketat. Untuk beberapa tepi, khususnya di bagian luar peta, ini tidak mungkin. Saya tidak tahu cara memilih posisi awal yang baik, atau cara memfilter solusi - tetapi mungkin orang lain memilikinya.
Contoh kerja (dimulai dengan edge (1204573687, 4555480822)):
Contoh, di mana pendekatan ini tidak berfungsi (dimulai dengan edge (1286684278, 5818325197)):
Kode
sumber