Saya mencari cara untuk menghitung tingkat zoom untuk batas tertentu menggunakan Google Maps V3 API, mirip dengan getBoundsZoomLevel()
di V2 API.
Inilah yang ingin saya lakukan:
// These are exact bounds previously captured from the map object
var sw = new google.maps.LatLng(42.763479, -84.338918);
var ne = new google.maps.LatLng(42.679488, -84.524313);
var bounds = new google.maps.LatLngBounds(sw, ne);
var zoom = // do some magic to calculate the zoom level
// Set the map to these exact bounds
map.setCenter(bounds.getCenter());
map.setZoom(zoom);
// NOTE: fitBounds() will not work
Sayangnya, saya tidak dapat menggunakan fitBounds()
metode ini untuk kasus penggunaan khusus saya. Ini bekerja dengan baik untuk memasang penanda pada peta, tetapi tidak berfungsi dengan baik untuk menetapkan batas yang tepat. Ini adalah contoh mengapa saya tidak bisa menggunakan fitBounds()
metode ini.
map.fitBounds(map.getBounds()); // not what you expect
google-maps
google-maps-api-3
Nick Clark
sumber
sumber
fitBounds()
. Pertanyaan ini menanyakan apa yang harus dilakukan ketikafitBounds()
tidak mencukupi - baik karena terlalu besar atau Anda tidak ingin memperbesar (yaitu, Anda hanya ingin tingkat zoom).Jawaban:
Pertanyaan serupa telah diajukan di grup Google: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
Level zoom terpisah, dengan skala berlipat ganda di setiap langkah. Jadi secara umum Anda tidak dapat memenuhi batas yang Anda inginkan dengan tepat (kecuali jika Anda sangat beruntung dengan ukuran peta tertentu).
Masalah lain adalah rasio antara panjang sisi misalnya Anda tidak dapat memasukkan batas tepat ke persegi panjang tipis di dalam peta persegi.
Tidak ada jawaban yang mudah untuk bagaimana menyesuaikan batas yang tepat, karena meskipun Anda bersedia mengubah ukuran div peta, Anda harus memilih ukuran dan tingkat zoom terkait yang Anda ubah (secara kasar, apakah Anda membuatnya lebih besar atau lebih kecil) daripada saat ini?).
Jika Anda benar-benar perlu menghitung zoom, alih-alih menyimpannya, ini harus dilakukan caranya:
Proyeksi Mercator melengkungkan lintang, tetapi setiap perbedaan dalam bujur selalu mewakili fraksi yang sama dari lebar peta (perbedaan sudut dalam derajat / 360). Pada zoom nol, seluruh peta dunia adalah 256x256 piksel, dan memperbesar setiap level menggandakan lebar dan tinggi. Jadi setelah aljabar kecil kita dapat menghitung zoom sebagai berikut, asalkan kita tahu lebar peta dalam piksel. Perhatikan bahwa karena garis bujur membungkus, kita harus memastikan sudutnya positif.
sumber
Terima kasih kepada Giles Gardam untuk jawabannya, tetapi hanya membahas garis bujur dan bukan garis lintang. Solusi lengkap harus menghitung level zoom yang diperlukan untuk garis lintang dan tingkat zoom yang diperlukan untuk garis bujur, dan kemudian mengambil yang lebih kecil (lebih jauh) dari keduanya.
Berikut adalah fungsi yang menggunakan lintang dan bujur:
Demo on jsfiddle
Parameter:
Nilai parameter "batas" harus menjadi
google.maps.LatLngBounds
objek.Nilai parameter "mapDim" harus berupa objek dengan properti "height" dan "width" yang mewakili tinggi dan lebar elemen DOM yang menampilkan peta. Anda mungkin ingin mengurangi nilai-nilai ini jika Anda ingin memastikan bantalan. Artinya, Anda mungkin tidak ingin penanda peta di dalam batas terlalu dekat dengan tepi peta.
Jika Anda menggunakan perpustakaan jQuery,
mapDim
nilainya dapat diperoleh sebagai berikut:Jika Anda menggunakan pustaka Prototipe, nilai mapDim dapat diperoleh sebagai berikut:
Nilai Pengembalian:
Nilai kembali adalah tingkat pembesaran maksimum yang masih akan menampilkan seluruh batas. Nilai ini akan berada di antara
0
dan tingkat zoom maksimum, inklusif.Level zoom maksimum adalah 21. (Saya yakin itu hanya 19 untuk Google Maps API v2.)
Penjelasan:
Google Maps menggunakan proyeksi Mercator. Dalam proyeksi Mercator, garis bujur sama spasi, tetapi garis lintang tidak. Jarak antara garis lintang meningkat saat mereka bergerak dari garis khatulistiwa ke kutub. Bahkan jaraknya cenderung menuju infinity saat mencapai kutub. Namun, peta Google Maps tidak menunjukkan garis lintang di atas sekitar 85 derajat Utara atau di bawah sekitar -85 derajat Selatan. ( referensi ) (Saya menghitung cutoff aktual pada +/- 85.05112877980658 derajat.)
Ini membuat perhitungan fraksi untuk batas lebih rumit untuk lintang daripada untuk bujur. Saya menggunakan rumus dari Wikipedia untuk menghitung fraksi lintang. Saya menganggap ini cocok dengan proyeksi yang digunakan oleh Google Maps. Lagi pula, halaman dokumentasi Google Maps yang saya tautkan di atas berisi tautan ke halaman Wikipedia yang sama.
Catatan lain:
sumber
fitBounds
, Anda harus membuat peta dan kemudian menunggu acara "bounds_changed".map.getProjection()
akan menghilangkan beberapa matematika (dan asumsi tentang proyeksi), tetapi itu berarti fungsi tidak dapat dipanggil sampai setelah peta dibuat dan acara "projection_changed" telah diaktifkan.Untuk versi 3 API, ini sederhana dan berfungsi:
dan beberapa trik opsional:
sumber
maxZoom
akan mencegah pengguna melakukan pembesaran manual . Contoh saya hanya mengubah DefaultZoom dan hanya jika perlu.getBoundsZoomLevel
. dengan begitu, ketika Anda memanggil setZoom, ia akan bergerak ke level zoom yang diinginkan. dari sana itu tidak masalah untuk melakukan panTo dan Anda berakhir dengan animasi peta yang indah yang sesuai dengan batasBerikut versi fungsi Kotlin:
sumber
Terima kasih, itu banyak membantu saya dalam menemukan faktor zoom yang paling cocok untuk menampilkan polyline dengan benar. Saya menemukan koordinat maksimum dan minimum di antara titik-titik yang harus saya lacak dan, jika jalurnya sangat "vertikal", saya hanya menambahkan beberapa baris kode:
Sebenarnya, faktor zoom yang ideal adalah zoomfactor-1.
sumber
var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;
. Tetap saja, sangat membantu.Karena semua jawaban lain tampaknya memiliki masalah bagi saya dengan satu atau beberapa keadaan (lebar peta / tinggi, lebar batas / tinggi, dll.) Saya pikir saya akan meletakkan jawaban saya di sini ...
Ada file javascript yang sangat berguna di sini: http://www.polyarc.us/adjust.js
Saya menggunakan itu sebagai dasar untuk ini:
Anda tentu dapat membersihkan ini atau memperkecil jika diperlukan, tapi saya menyimpan nama variabel lama dalam upaya untuk membuatnya lebih mudah untuk dipahami.
Jika Anda bertanya-tanya dari mana OFFSET berasal, tampaknya 268435456 adalah setengah dari keliling bumi dalam piksel pada level zoom 21 (menurut http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google -maps ).
sumber
Valerio hampir benar dengan solusinya, tetapi ada beberapa kesalahan logis.
Anda harus terlebih dahulu memeriksa apakah sudut2 lebih besar dari sudut, sebelum menambahkan 360 pada negatif.
jika tidak, Anda selalu memiliki nilai lebih besar dari sudut
Jadi solusi yang benar adalah:
Delta ada di sana, karena saya memiliki lebar lebih besar daripada tinggi.
sumber
map.getBounds()
bukan operasi sesaat, jadi saya gunakan dalam event handler kasus serupa. Ini contoh saya di Coffeescriptsumber
Contoh kerja untuk menemukan pusat default rata-rata dengan react-google-maps di
ES6
:sumber
Perhitungan tingkat zoom untuk garis bujur Giles Gardam bekerja dengan baik untuk saya. Jika Anda ingin menghitung faktor zoom untuk garis lintang, ini adalah solusi mudah yang berfungsi dengan baik:
sumber