Google Maps API v3: можно ли установить Zoom после fitBounds? - PullRequest
196 голосов
/ 13 марта 2010

У меня есть набор точек, которые я хочу нанести на встроенную карту Google (API v3). Я бы хотел, чтобы границы вмещали все точки, если уровень масштабирования не слишком низкий (то есть слишком сильно уменьшен). Мой подход был такой:

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

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

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

Есть ли способ получить уровень масштабирования границ, не применяя его к карте? Другие идеи, чтобы решить эту проблему?

Ответы [ 23 ]

2 голосов
/ 09 ноября 2012

Была такая же проблема, нужно было разместить много маркеров на карте. Это решило мой случай:

  1. Объявить границы
  2. Использовать схему, предоставляемую koderoid (для каждого набора маркеров bounds.extend(objLatLng))
  3. Выполнить подгонку после ПОСЛЕ составления карты:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });
    
1 голос
/ 10 октября 2015

Как и я, если вы не хотите играть со слушателями, я придумаю простое решение: Добавьте метод на карту, который работает строго в соответствии с вашими требованиями, как этот:

    map.fitLmtdBounds = function(bounds, min, max){
        if(bounds.isEmpty()) return;
        if(typeof min == "undefined") min = 5;
        if(typeof max == "undefined") max = 15;

        var tMin = this.minZoom, tMax = this.maxZoom;
        this.setOptions({minZoom:min, maxZoom:max});
        this.fitBounds(bounds);
        this.setOptions({minZoom:tMin, maxZoom:tMax});
    }

, затем вы можете вызвать map.fitLmtdBounds(bounds) вместо map.fitBounds(bounds), чтобы установить границы в определенном диапазоне масштабирования ... или map.fitLmtdBounds(bounds,3,5), чтобы переопределить диапазон масштабирования ..

1 голос
/ 16 июля 2010

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

"fitGeometries" - это функция JSON, расширяющая объект карты.

«Геометрия» - это общий массив JavaScript, а не MVCArray ().

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},
1 голос
/ 13 марта 2013

это работа для меня с API v3, но с установкой фиксированного увеличения:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );
1 голос
/ 21 июля 2010

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

Добавить слушателя к событию zoom_changed. Это дает дополнительное преимущество, заключающееся в управлении масштабированием в пользовательском интерфейсе.

Выполнять setZoom можно только при необходимости, поэтому оператор if предпочтительнее Math.max или Math.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

Для предотвращения слишком большого уменьшения:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);
0 голосов
/ 23 марта 2018

Для меня самым простым решением было следующее:

map.fitBounds(bounds);

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
0 голосов
/ 05 марта 2018

Чтобы присоединиться к другому решению - я обнаружил, что подход «прослушать событие bounds_changed и затем установить новое масштабирование» не работает для меня надежно. Я думаю, что я иногда вызывал fitBounds до того, как карта была полностью инициализирована, и инициализация вызывала событие bounds_changed, которое использовало бы слушателя, до того как fitBounds изменило границы и уровень масштабирования. Я закончил с этим кодом, который, кажется, работает до сих пор:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});
0 голосов
/ 05 марта 2016

Если «bounds_changed» не запускается корректно (иногда Google, похоже, не совсем правильно принимает координаты), вместо этого рассмотрите возможность использования «center_changed».

Событие center_changed возникает при каждом вызове fitBounds (), хотя оно запускается сразу и не обязательно после перемещения карты.

В обычных случаях 'idle' по-прежнему лучший слушатель событий, но это может помочь паре людей, сталкивающихся со странными проблемами с их вызовами fitBounds ().

См. Google Maps FitBounds обратный вызов

0 голосов
/ 05 декабря 2013
google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});
0 голосов
/ 07 июля 2010

Пожалуйста, попробуйте это.

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

Если это будет полезно для вас.

Всего наилучшего

...