Google Haritalar v3 fitBounds () Tek işaretçi için çok yakın yakınlaştırma


93

Maksimum yakınlaştırma düzeyi belirlemenin bir yolu var mı fitBounds()? Benim sorunum, harita yalnızca bir konumla beslendiğinde, gidebildiği kadar yakınlaştırması, bu da haritayı gerçekten bağlamından çıkarması ve işe yaramaz hale getirmesidir. Belki de yanlış yaklaşımı benimsiyorum?

Şimdiden teşekkürler!


2
stackoverflow.com/questions/4523023/… çok daha iyi bir çözümdür. Özel @Nequins yanıtı
Kennet

Yanıtlar:


139

Mrt'nin çözümünü seviyorum (özellikle kaç noktayı haritalayacağınızı veya ayarlayacağınızı bilmediğinizde), ancak artık haritanın merkezinde olmaması için işaretçiyi atıyor. Enlem ve boylamdan 0,01 çıkararak ek bir nokta çıkararak genişlettim, böylece işaretçiyi merkezde tutar. Harika çalışıyor, teşekkürler mrt!

// Pan & Zoom map to show all markers
function fitToMarkers(markers) {

    var bounds = new google.maps.LatLngBounds();

    // Create bounds from markers
    for( var index in markers ) {
        var latlng = markers[index].getPosition();
        bounds.extend(latlng);
    }

    // Don't zoom in too far on only one marker
    if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
       var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
       var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
       bounds.extend(extendPoint1);
       bounds.extend(extendPoint2);
    }

    map.fitBounds(bounds);

    // Adjusting zoom here doesn't work :/

}

4
Orijinal merkezi korumak için iyi fikir. fitBounds()Yöntemi kullanırken yakınlaştırma seviyesinin güvenilir bir şekilde ayarlanamamasının nedeni, yakınlaştırmanın eşzamansız olarak gerçekleşmesidir: stackoverflow.com/questions/2989858/…
Metro Smurf

1
Bu benim için harika çalıştı. Harita referansını V3'teki "fitToMarkers (işaretçiler, harita) işlevi" işlevine geçirmek zorunda kaldım, ancak bundan sonra bir cazibe gibi çalışıyor!
Shane

4
Bunu sevdim. İyi olan @ryan. Benim için harika çalıştı, ancak benim durumumda 0,01 çok uzaklaştı, 0,001 tatlı noktayı vurdu.
willdanceforfun

Teşekkürler. @ Willdanceforfun aynı durum gibi, 001 isabetli.
Goran Jakovljevic

1

40

Sen ile kurulum haritanızı can maxZoomiçinde MapOptions (api-referans) böyle:

var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

Bu, haritanın kullanılırken daha derin yakınlaştırmasını engeller fitBounds()ve hatta yakınlaştırma kontrolünden yakınlaştırma seviyelerini kaldırır.


@candlejack Tam olarak cevabımda anlatıldığı gibi?
Flygenring

8
maxZoomSınırları sığdırmadan önce ayarlayabilir ve ardından sınırları değiştirerek tetiklenen olay map.setOptions({ maxZoom: undefined })üzerinde kullanarak yeniden ayarını kaldırabilirsiniz idle. Bu, idleolayda yakınlaştırmayı sıfırlamak yerine yakınlaştırma, uzaklaştırma efektini önler .
El Yobo

29

Diğer bir çözüm, fitBounds () 'u çalıştırmadan önce sınırların çok küçük olduğunu tespit ederseniz, sınırları genişletmektir:

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
   var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
   bounds.extend(extendPoint);
}
map.fitBounds(bounds);

19
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

MaxZoom seçeneğini kullanmak, sahip olduğunuz işaretlere yakınlaşmak için yakınlaştırmamak için en iyi sonucu verir.


Fantastik! Hayat kurtarıcı!
Jaypee

18

Tüm gerçek sınırları ekledikten sonra bu satırları ekleyin

var offset = 0.002;     
var center = bounds.getCenter();                            
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset));
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset));

gerçek sınırların merkezini alır ve sonra merkezinizin kuzeydoğusuna ve güneybatısına iki ek nokta ekler

Bu, minimum yakınlaştırmayı etkili bir şekilde ayarlar, yakınlaştırmayı artırmak veya azaltmak için ofset değerini değiştirir



11

kullanabilirsin

map.setOptions({
    maxZoom: [what u want],
    minZoom: [what u want]
});

bu şekilde harita başlatıldıktan sonra haritanın özelliklerini ayarlarsınız .... onları istediğiniz kadar ayarlayabilirsiniz ... ama sizin durumunuzda ... bunları fitBounds () 'dan önce ayarlayabilirsiniz.

iyi şanslar rarutu


7

Haritanın uzaklaşmasını engellememin yolu şu kod satırını eklemektir:

var zoomOverride = map.getZoom();
        if(zoomOverride > 15) {
        zoomOverride = 15;
        }
      map.setZoom(zoomOverride);

Bu satırdan hemen sonra:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

Yakınlaştırma seviyesini haritanın yakınlaştırmasını istemediğiniz seviyeye değiştirmekten çekinmeyin.

Herhangi bir sorununuz veya sorunuz varsa, http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the- adresinde bununla ilgili yazdığım blog gönderisine bir yorum bırakın. harita-tek bir işaretleyiciye çok yakın-yakınlaştırma


1
Bu çözümü beğendim ama setzoom'u her seferinde çağırmamak için if'in içine ekleyin. Ayrıca getzoom () işlevinden 'tanımsız' döndüren bir zamanlama yan etkisi olabilir. Çözüm: zoom = map.getZoom (); eğer (yakınlaştırma türü! == 'tanımlanmamış' && yakınlaştır> 8) map.setZoom (8);
Le Droid

5

Mrt'nin çözümünü gerçekten çok seviyorum ve her zaman üzerinde çalışacak tek bir noktanız varsa mükemmel çalışıyor. Bununla birlikte, sınırlayıcı kutu bir noktaya dayalı değilse, ancak noktalar birbirine çok yakın olsaydı, bu yine de haritanın çok fazla yakınlaştırılmasına neden olabilirdi.

İlk olarak noktaların birbirlerinden belirli bir mesafede olup olmadığını kontrol etmenin bir yolu var, sonra bu minimum mesafeden daha küçüklerse, sınırları bu minimum mesafe kadar uzatın:

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like

// ...

var minDistance = 0.002;
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng();
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat();

if((sumA < minDistance && sumA > -minDistance) 
&& (sumB < minDistance && sumB > -minDistance)){
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance);
    var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance);
    bounds.extend(extendPoint1);
    bounds.extend(extendPoint2);
}

Umarım bu birine yardımcı olur!


3

Bu size sınır uydurma üzerinde izin verilen maksimum yakınlaştırma üzerinde doğrudan kontrol sağlar.

var fitToMarkers = function(map, markers, maxZoom) {
    if (typeof maxZoom == 'undefined') maxZoom = 15;

    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom() > maxZoom) {
            this.setZoom(maxZoom);
        }
    });

    var bounds = new google.maps.LatLngBounds();
    for (var m = 0; m < markers.length; m++) {
        var marker = markers[m];
        var latlng = marker.getPosition();
        bounds.extend(latlng);
    }

    map.fitBounds(bounds);
};

3

Bana gelince çocuklar bunu fitBounds'dan sonra boşta bir olay oluşturarak çözüyorum. Mükemmel çalışıyor. Sanırım buradaki en temiz çözümlerden biri bu

var locations = [['loc', lat, lng], ['loc', lat, lng]];
.....
for (i = 0; i < locations.length; i++) { 
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10
  });
  .... create markers, etc.
}
....
map.fitBounds(bounds);  
google.maps.event.addListenerOnce(map, 'idle', function() {
  if (locations.length == 1) {
    map.setZoom(11);
  }
});

2

Google Haritalar V3 olay odaklı olduğundan, bu parçayla çözdüm:

zoom_changed olayı tetiklendiğinde API'ye yakınlaştırmayı uygun bir miktara geri getirmesini söyleyebilirsiniz :

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (intial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         intial = false;
       }
    }
}); 

Kullandığım İntial nihai fitBounds permorfed zaman haritası onsuz 11 üzerinden herhangi bir yakınlaştırma olay kullanıcı için imkansız olurdu, çok fazla yükleme yakınlaştırma değil markasını.


1

fitBounds()Yöntemi çağırdıktan sonra , yakınlaştırma düzeyini yeniden ayarlamayı deneyin. Doğru yerde ortalanırken haritayı bu yakınlaştırma düzeyinde olmaya zorlar.


0

Sınırları yerleştirirken maksimum yakınlaştırmayı sınırlandırmaya dayalı bir ruhum var. Benim için çalışıyor (Win 7 - IE 9, FF 13, Chrome 19'da test edildi):

// When fitting bounds:
var bounds = new google.maps.LatLngBounds();
// ...
// extend bounds as you like
// ..

// now set global variable when fitting bounds
window.fittingBounds = true;
map.fitBounds(bounds);
window.fittingBounds = false;


// attach this event listener after map init
google.maps.event.addListener(map, 'zoom_changed', function() {
    // set max zoom only when fitting bounds
    if (window.fittingBounds && map.getZoom() > 16) {
        this.setZoom(16);
    }
});

0

Ve .. işte bir tane daha.
Mrt ve Ryan ile aynı fikir, ama

  • sınır boyutu tam olarak sıfır değilse de çalışır (*)
  • kutupların yakınında bozulmayı önler
  • getNorthEast () yerine getCenter () kullanır

(*) Not: Kutu zaten yeterince büyükse, bu iki ekstra noktayı eklemenin bir etkisi olmamalıdır. Yani daha fazla kontrole ihtiyacımız yok.

function calcBounds(markers) {
  // bounds that contain all markers
  var bounds = new google.maps.LatLngBounds();
  // Using an underscore _.each(). Feel free to replace with standard for()
  _.each(markers, function(marker) {
    bounds.extend(marker.getPosition());
  });
  // prevent lat/lng distortion at the poles
  var lng0 = bounds.getNorthEast().lng();
  var lng1 = bounds.getSouthWest().lng();
  if (lng0 * lng1 < 0) {
    // Take the cos at the equator.
    var cos = 1;
  }
  else {
    var cos0 = Math.cos(lng0);
    var cos1 = Math.cos(lng1);
    // Prevent division by zero if the marker is exactly at the pole.
    var cos_safe = Math.max(cos0, cos1, 0.0001);
  }
  var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI / 180);
  var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI / 180);
  // "radius" in either direction.
  // 0.0006 seems to be an ok value for a typical city.
  // Feel free to make this value a function argument.
  var rLat = 0.0006;
  var rLng = rLat / cos_safe;
  // expand the bounds to a minimum width and height
  var center = bounds.getCenter();
  var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng);
  var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng);
  bounds.extend(p0);
  bounds.extend(p1);
  return bounds;
}

DÜZENLEME: Bir Mercator projeksiyonumuz olduğunu düşünürsek oran hesaplamamın doğru olup olmadığından tam olarak emin değilim. Bunu yeniden düzenleyebilirim ..



-1

İşte iki işaret çok yakın olduğunda da işe yarayan bir çözüme gidiyorum. Etkili maksimum yakınlaştırma seviyesi her iki durumda da aynıdır. Bu nedenle, birden fazla işaretçi olduğunda, gereksiz yere yakınlaştırma yapmayız.

Etkisi yine maxZoom seçeneğini kullanmadan maksimum yakınlaştırma sağlamaktır; bu, kullanıcının yakınlaştırma kontrolü ile maksimum yakınlaştırma düzeyinden daha fazla yakınlaştırmasını imkansız hale getirme gibi muhtemelen istenmeyen bir etkiye sahiptir.

MaxLat, minLat, maxLng ve minLng'yi önceden hesapladım ...

var minLatSpan = 0.002;
if (maxLat - minLat < minLatSpan) {
  // ensures that we do not zoom in too much
  var delta = (minLatSpan - (maxLat - minLat)) / 2;
  maxLat += delta;
  minLat -= delta;
}

map.fitBounds({
  east: maxLng,
  west: minLng,
  north: maxLat,
  south: minLat,
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.