Google Maps v3 fitBounds () Увеличение слишком близко для одного маркера - PullRequest
81 голосов
/ 26 июля 2010

Есть ли способ установить максимальный уровень масштабирования для fitBounds()?Моя проблема в том, что, когда на карту подается только одно местоположение, она максимально увеличивает масштаб, что действительно вынимает карту из контекста и делает ее бесполезной.Возможно, я ошибаюсь?

Заранее спасибо!

Ответы [ 17 ]

2 голосов
/ 20 октября 2013

Я решил с этим чанком, так как Google Maps V3 управляется событиями:

Вы можете сказать API, чтобы он уменьшил масштаб до нужного значения, когда событие zoom_changed вызывает:

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

Я использовал intial , чтобы карта не слишком сильно увеличивала загрузку при окончательном завершении fitBounds, без чего любое событие масштабирования свыше 11 было бы невозможно для пользователя.

2 голосов
/ 13 октября 2017

Что касается меня, ребята, я решаю это, создавая простое событие после fitBounds. Работает отлично. Думаю, это одно из самых чистых решений здесь

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);
  }
});
0 голосов
/ 25 августа 2016

После вызова метода fitBounds() попробуйте снова установить уровень масштабирования. Это заставит карту находиться на том же уровне масштабирования, в то время как она будет в центре в нужном месте.

0 голосов
/ 07 декабря 2013

Здесь уже ответили Google Maps v3: Обеспечение мин.Уровень масштабирования при использовании fitBounds работает как положено :), так что теперь, если после подгонки границ масштабирование меньше, чем, скажем, 13, вы можете установить новый масштаб, который вы предпочитаете

0 голосов
/ 22 июня 2012

У меня есть решение, основанное на ограничении максимального увеличения при установке границ. У меня работает (проверено на Win 7 - IE 9, FF 13, Chrome 19):

// 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 голосов
/ 22 июня 2018

Вот мое решение, которое также работает, когда два маркера очень близки. Эффективный максимальный уровень масштабирования одинаков в обеих ситуациях. Таким образом, мы не заканчиваем излишним увеличением масштаба, когда есть более одного маркера

Эффект, опять же, обеспечивает максимальное увеличение без использования опции maxZoom, что, вероятно, приводит к нежелательному эффекту, когда пользователь не может увеличить масштаб больше уровня maxZoom с помощью элемента управления масштабированием

Я заранее рассчитал maxLat, minLat, maxLng и minLng ...

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,
});
0 голосов
/ 04 января 2013

И .. вот еще один.
Та же идея, что и у мистера и Райана, но

  • также работает, если размер границ не равен нулю (*)
  • предотвращает искажения вблизи полюсов
  • использует getCenter () вместо getNorthEast ()

(*) Примечание. Если поле уже достаточно велико, добавление этих двух дополнительных точек не должно иметь никакого эффекта. Поэтому нам не нужна дополнительная проверка.

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;
}

РЕДАКТИРОВАТЬ: Я не совсем уверен, правильно ли мой расчет отношения, учитывая, что у нас есть проекция Меркатора. Я мог бы отредактировать это ..

...