Fitbounds API Карт Google V3 () уменьшает, но никогда не - PullRequest
8 голосов
/ 15 июля 2010

Я создал довольно сложный тип поиска магазинов. Пользователь вводит свой почтовый индекс, и таблица возвращает результаты с соответствующими маркерами на карте. Они могут пролистывать результаты, и маркеры перемещаются все дальше и дальше, а функция fitbounds() отлично работает для уменьшения масштаба до соответствующего уровня масштабирования, чтобы соответствовать маркерам. Проблема в том, что если вы вернетесь к более близким местам, fitbounds() не увеличит масштаб. Даже если вы введете новый поиск, он не увеличит масштаб вокруг этих новых маркеров - он центрируется над ними, но остается на любом уровне масштабирования. это было ранее. Я надеюсь это имеет смысл. Если кто-то знает, что мне нужно добавить, чтобы увеличить приблизительные результаты, помогите. Это функции Google, которые я вызываю в конце своей функции нажатия маркеров:

  map.setCenter(bounds.getCenter());
  map.panToBounds(bounds);
  map.fitBounds(bounds);

Спасибо!

Ответы [ 10 ]

10 голосов
/ 24 апреля 2012

Проблема заключается в следующем: мы устанавливаем

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

, чтобы мы могли позже разместить наши маркеры в ограниченной области на карте. GMaps всегда будет уменьшать масштаб асинхронно, чтобы соответствовать fitBounds () соответственно, но не будет увеличивать для достижения того же (как ранее отмечалось @broady). Это не идеально для многих приложений, так как после того, как вы ушли и отобразили серию маркеров на карте, которые вызвали уменьшение карты (возможно, <10), она не будет увеличиваться без того, чтобы пользователь не сделал этого вручную. </p>

GMaps будет по-прежнему использовать границы (нехватки лучших слов) наиболее уменьшенного статуса коллекции маркеров (извините). Установка 'null' перед каждым вызовом новых маркеров дает вам новую карту для работы.

Для автоматического увеличения просто установите LatLngBounds (); 'null', например, так (см. псевдо-пример ниже, чтобы увидеть его размещение):

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

Псевдо пример:

// map stuff/initiation
...

var bounds = new google.maps.LatLngBounds();
var gmarkers = [];

function CreateMarker (obj) {
    myLatLng = new google.maps.LatLng(obj['latitude'], obj['longitude']);
    marker = new google.maps.Marker({
        position: myLatLng,
        map: map
    });
    google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
            infowindow.setContent(obj['job']);
            infowindow.open(map, marker);
        }
    })(marker, i));
    bounds.extend(myLatLng);
    gmarkers.push(marker);
}

....

// here's an AJAX method I use to grab marker coords from a database:

$.ajax({
    beforeSend: function() {
        clear_markers(gmarkers); // see below for clear_markers() function declaration
    },
    cache: false,
    data: params,
    dataType: 'json',
    timeout: 0,
    type: 'POST',
    url: '/map/get_markers.php?_=<?php echo md5(session_id() . time() . mt_rand(1,9999)); ?>',
    success: function(data) {
        if (data) {
            if (data['count'] > 0) {
                var obj;
                var results = data['results'];

                // Plot the markers
                for (r in results) {
                    if (r < (data['count'])) {
                        CreateMarker(results[r]);
                    }
                }
            }
        }
    },
    complete: function() {
        map.fitBounds(bounds);
    }
});

// clear_markers()
function clear_markers(a) {
    if (a) {
        for (i in a) {
            a[i].setMap(null);
        }
        a.length = 0;
    }
    bounds = new google.maps.LatLngBounds(null); // this is where the magic happens; setting LatLngBounds to null resets the current bounds and allows the new call for zoom in/out to be made directly against the latest markers to be plotted on the map
}
8 голосов
/ 07 сентября 2011

Ничего особенного здесь не нужно. Сначала подгоните границы, затем передвиньте к нему. Это даст вам правильный масштаб и содержит все границы.

map.fitBounds(bounds);
map.panToBounds(bounds);
4 голосов
/ 04 ноября 2010

Хм, интересно .. Я использую PHP, чтобы пройти через все (чтобы быть) координаты маркера и вычислить значения southWest и northEast;координаты происхождения находятся на полпути между ними.Если все координаты маркера очень близки друг к другу, коэффициент масштабирования, установленный fitBounds, намного выше (увеличен), чем 15, используемый при создании карты.Вот почему я добавил эту последнюю строку ..

var map;

function mapInit() {
  var origin = new google.maps.LatLng(59.33344615, 18.0678188);
  var options = {
    zoom: 15,
    center: origin,
    mapTypeControlOptions: {
      mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID]
    },
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById("googlemap"), options);

  var southWest = new google.maps.LatLng(59.3308415, 18.0643054);
  var northEast = new google.maps.LatLng(59.3360508, 18.0713322);
  var bounds = new google.maps.LatLngBounds(southWest, northEast);
  map.fitBounds(bounds);

  google.maps.event.addListenerOnce(map, "idle", function() {
    if (map.getZoom() > 16) map.setZoom(16);
  });

Итак, либо Google перепрограммировал функцию с момента отправки вопроса, либо .. Мне нужна дополнительная информация о вашем коде.

4 голосов
/ 11 октября 2010

Все верно, fitBounds только гарантирует , что указанные границы видны. Не приближается к соответствующему уровню.

Вы можете сначала позвонить setZoom(20), затем fitBounds.

3 голосов
/ 10 июля 2018

Что мне помогло, так это использование 0-отступа в качестве второго параметра для fitBounds (bounds, padding), вот полный пример кода:

function initMap() {
    var mapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        minZoom: 1
    };
    map = new google.maps.Map(document.getElementById('officeMap'), mapOptions);
    google.maps.event.addListenerOnce(map, 'idle', function() {
        //Map is ready
        worldViewFit(map);
    });
}
function worldViewFit(mapObj) {
    var worldBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(70.4043,-143.5291),  //Top-left
        new google.maps.LatLng(-46.11251, 163.4288)  //Bottom-right
    );
    mapObj.fitBounds(worldBounds, 0);
    var actualBounds = mapObj.getBounds();
    if(actualBounds.getSouthWest().lng() == -180 && actualBounds.getNorthEast().lng() == 180) {
        mapObj.setZoom(mapObj.getZoom()+1);
    }
}
2 голосов
/ 12 октября 2013

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

// This is a stationary point tho dynamic will work too

var myLat = someLat,
    myLng = someLong;

var map = false,
    markersArray = [];

function makeOrderMap(lat, lng) { // pass in dynamic point when updating map

  var mapOptions = {
      center: new google.maps.LatLng(myLat, myLng),
      zoom: 16,
      mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  deleteOverlays(); // remove any existing markers..
  if(!map) {  
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  } 

  // Find the mid-point to center the map

  midLat = (parseFloat(lat) + parseFloat(myLat)) / 2;
  midLng = (parseFloat(lng) + parseFloat(myLng)) / 2;
  map.setCenter(new google.maps.LatLng(midLat, midLng));
  var newSpot = new google.maps.LatLng(lat, lng); 

  placeMarker(mapOptions.center);    
  placeMarker(newSpot);   

  // determine the distance between points for deciding the zoom level

  var dist = distHaversine(mapOptions.center, newSpot);

  var zoom = 10;
  if(dist < 1.25) {
    zoom = 15;
  } else if(dist < 2.5) {
    zoom = 14;
  } else if(dist < 5) {
    zoom = 13;
  } else if(dist < 10) {
    zoom = 12;
  } else if(dist < 20) {
    zoom = 11;
  }
  map.setZoom(zoom);  
}


rad = function(x) {return x*Math.PI/180;}

distHaversine = function(p1, p2) {
  var R = 6371; // earth's mean radius in km
  var dLat  = rad(p2.lat() - p1.lat());
  var dLong = rad(p2.lng() - p1.lng());

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;

  return d.toFixed(3);
}

function deleteOverlays() {
    if (markersArray) {
        for (i in markersArray) {
            markersArray[i].setMap(null);
        }
    markersArray = [];    
    markersArray.length = 0;
    }    
}

function placeMarker(location, alt_icon) {

    var marker = new google.maps.Marker({
        position: location, 
        map: map
      });

    // add marker in markers array
    markersArray.push(marker);
}
2 голосов
/ 12 апреля 2013

Оказывается, что когда вы вызываете map.getBounds(), он возвращает окно просмотра с небольшим полем по краям.Поскольку эти новые границы больше, чем текущие границы, карта всегда будет уменьшаться.Мне удалось решить эту проблему, вообще не используя границы текущей карты и поддерживая отдельную переменную LatLngBounds.Каждый раз, когда я добавлял точку, я звонил:

markersBounds.extend(newMarkersLatLng);
map.fitBounds(markersBounds);
map.panToBounds(markersBounds);

Чтобы удалить точки (я всегда их добавлял), вы можете создать новый объект LatLngBounds с первой точкой, а затем расширить каждую оставшуюся точку, чтобы получить новуюграницы:

var markersBounds = new google.maps.LatLngBounds(markers[0].getPosition(),
                                                 markers[0].getPosition());
for(var i=1; i<markers.length; i++){
    markersBounds.extend(markers[i].getPosition());
}

map.fitBounds(markersBounds);
map.panToBounds(markersBounds);
0 голосов
/ 06 января 2014

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

(для этого используется модуль массива Dojo, просто удобная оболочка вокруг базовой итерации массива)

var origBounds = map.getBounds(),
    newBounds = new google.maps.LatLngBounds(null),
    anyFailed = false;
array.forEach(markers, function (m) {
    newBounds.extend(m.position);
    if (!origBounds.contains(m.position)) {
        anyFailed = true;
    }
});
if (anyFailed) {
    map.setCenter(newBounds.getCenter());
    map.fitBounds(newBounds);
}

Можно легко изменить это, чтобы убедиться, что отображается только новый маркер, не зацикливаясь и просто выполняя проверку содержимого () для нового маркера.

0 голосов
/ 13 марта 2011
fitBounds: function(bounds, mapId)
    {
        //bounds: bounds, id: map id
        if (bounds==null) return false;
        maps[mapId].fitBounds(bounds);
    },  

Это должно помочь, я использую этот метод и работает нормально, на карте v2 немного по-другому.

0 голосов
/ 15 июля 2010
map.setZoom(10);

Я считаю, что допустимый диапазон составляет 1-20.Только целые числа, десятичные дроби сломали карту в моем опыте.

...