Saya perlu menemukan centroid (atau titik label) untuk poligon berbentuk tidak teratur di Google Maps. Saya menunjukkan InfoWindows untuk paket dan memerlukan tempat untuk melabuhkan InfoWindow yang dijamin ada di permukaan. Lihat gambar di bawah.
Pada kenyataannya saya tidak memerlukan apa pun yang spesifik dengan Google Maps, hanya mencari ide tentang cara menemukan poin ini secara otomatis.
Gagasan pertama saya adalah menemukan centroid "salah" dengan mengambil rata-rata lat dan lngs dan titik-titik penempatan acak dari sana sampai saya menemukan satu yang memotong poligon. Saya sudah memiliki kode point-in-polygon. Ini sepertinya sangat "meretas" bagi saya.
Saya harus mencatat bahwa saya tidak memiliki akses ke kode sisi server mana pun yang mengeluarkan geometri jadi saya tidak dapat melakukan sesuatu seperti ST_PointOnSurface (the_geom).
Anda mungkin ingin melihat ini: http://github.com/tparkin/Google-Maps-Point-in-Polygon
Tampaknya menggunakan algoritma Ray Casting yang harus cocok dengan kasus yang Anda sajikan.
Ada posting blog di sini. http://appdelegateinc.com/blog/2010/05/16/point-in-polygon-checking/
sumber
Algoritma ESRI (lebih tua) menghitung pusat massa dan, setelah mengujinya untuk dimasukkan dalam poligon, menggerakkannya secara horizontal jika perlu sampai terletak di dalam poligon. (Ini bisa dilakukan dalam banyak cara tergantung pada operasi fundamental apa yang tersedia dalam lingkungan pemrograman Anda.) Ini cenderung menghasilkan titik label yang cukup dekat dengan pusat visual poligon: coba pada ilustrasi.
sumber
Saya memecahkan masalah saya dengan memperluas kode epoly populer dari http://econym.org.uk/gmap . Pada dasarnya apa yang akhirnya saya lakukan adalah:
Kode epoly diperpanjang di bawah ini:
Masih sedikit retas tetapi tampaknya berhasil.
sumber
Algoritma 'kotor' lain untuk melakukan itu:
Ambil kotak pembatas geometri
(Xmax, Ymax, Xmin, Ymin)
Loop sampai titik acak
( Xmin+rand*(Xmax-Xmin), Ymin+rand*(Ymax-Ymin) )
ditemukan dalam geometri (menggunakan Google-Maps-Point-in-Polygon )sumber
Mengingat klarifikasi Anda baru-baru ini bahwa Anda lebih suka lokasi yang benar-benar interior, Anda dapat memilih titik pada Medial Axis Transform yang tidak juga pada batas poligon. (Jika Anda tidak memiliki kode untuk MAT, Anda dapat memperkirakannya dengan buffer negatif terhadap poligon. Pencarian biner atau garis potong akan dengan cepat menghasilkan poligon interior kecil yang mendekati bagian dari MAT; gunakan titik apa pun pada batasnya.)
sumber
Mengapa tidak menggunakan centroid hanya untuk posisi vertikal (lintang)? Kemudian, Anda dapat memposisikan label secara horizontal dengan memilih garis bujur rata-rata pada garis lintang itu . (Untuk ini, Anda perlu menemukan nilai bujur untuk tepi poligon pada garis lintang tertentu, yang seharusnya tidak memberi Anda masalah).
Juga, berhati-hatilah dengan bentuk U, dan yang lebih kompleks. :) Mungkin bagi mereka, pilih rata-rata dari pasangan garis bujur paling kanan (masing-masing pasangan akan sesuai dengan sepotong poligon), karena jendela info berorientasi seperti itu?
Ini memberi Anda sedikit lebih banyak kontrol atas penentuan posisi, juga; misalnya, mungkin lebih baik untuk memposisikan jendela info di 66 atau 75% secara vertikal, agar poligon lebih terlihat. (Atau mungkin tidak! Tetapi Anda memiliki tombol untuk mengubah.)
sumber
Bagaimana kalau hanya menggunakan titik yang diklik pengguna untuk memilihnya, jika dipilih oleh pengguna itu.
sumber
Saya mencoba menyelesaikan ini juga. Saya telah memberlakukan syarat pada poligon saya bahwa mereka tidak dapat memiliki garis silang yang masuk ke dalam apa yang akan saya uraikan.
Jadi, pendekatan saya menggunakan triangulasi. Mengambil simpul acak (mungkin mengambil simpul pada titik ekstrim N, E, W, atau S dapat menyederhanakan hal-hal).
Dari dhuwur ini, tarik garis ke dhuwur satu dhuwur, yaitu jika dhuwur Anda adalah dwma 3, lihatlah dwma 3 + 2.
Buat garis dari titik awal Anda ke titik ini. Jika garis yang dibangun:
Maka Anda telah membuat segitiga yang berada di dalam poligon. Jika simpul yang berhasil adalah n + 2, maka segitiga Anda adalah {n, n + 1, n + 2}, yang akan kita sebut sebagai {v, v1, v2}. Jika tidak, coba simpul berikutnya, dan lanjutkan sampai semua simpul telah dicoba.
Saat Anda menemukan segitiga, temukan pusatnya dengan mengambil garis dari titik v ke titik tengah v1 dan v2. Titik tengah garis itu dijamin berada di dalam segitiga, dan di dalam poligon.
Saya belum mengkodekan ini, tetapi saya bisa melihat ketika saya memikirkannya bahwa poligon dengan garis silang sebenarnya akan menyebabkan beberapa kondisi eksotis di mana ini tidak bekerja. Jika itu jenis poligon yang Anda miliki, Anda harus menguji setiap segmen garis pada poligon dan pastikan itu tidak dilintasi. Lewati segmen garis yang dilintasi, dan saya pikir itu akan berhasil.
sumber
https://github.com/mapbox/polylabel mungkin berguna (javascript dan C ++). C # implementasi di sini: https://gist.github.com/dfaivre/acfef42cdbf411555956e9eba65dd30d .
Pertanyaan SO asli di sini: /programming//a/38522611/79113
sumber