2010-07-26 2 views
65

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

Заранее благодарен!

+2

http: // stackoverflow.com/questions/4523023/use-setzoom-after-use-fitbounds-with-google-maps-api-v3 - гораздо лучшее решение. Особенно @Nequins ответить – Kennet

ответ

10

Если это место для одного места, вы можете использовать setCenter() и setZoom().

+0

Самое простое решение –

21

Другим решением является расширение границ, если вы обнаружили, что они слишком малы, прежде чем выполнить fitBounds():

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); 
+0

отлично работает на моем футляре. – trungk18

98

мне нравится решение MrT (особенно, если вы не знаете, сколько очков вы будете картирование или настройка для), за исключением того, что он выталкивает маркер, чтобы он больше не находился в центре карты. Я просто расширил его дополнительным вычитанием точки .01 из lat и lng, поэтому он удерживает маркер в центре. Отлично работает, спасибо!

// 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 :/ 

} 
+3

Хорошая идея по сохранению оригинального центра. Причина, по которой уровень масштабирования не может быть надежно отрегулирован при использовании метода 'fitBounds(), заключается в том, что масштаб происходит асинхронно: http://stackoverflow.com/questions/2989858/google-maps-v3-enforcing-min-zoom -level-when-use-fitbounds/2990316 # 2990316 –

+1

Это отлично подойдет для меня. Мне пришлось передать ссылку на карту в функцию «function fitToMarkers (markers, map)» на V3, но после этого она работает как шарм! – Shane

+2

Любовь, что. Хороший один. Отлично работал для меня, но .01 в моем случае слишком сильно замер, 1001 попал в сладкое место. – willdanceforfun

24

Вы можете настроить вашу карту с maxZoom в MapOptions(api-reference) как это:

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

Это будет держать карту от масштабирования глубже при использовании fitBounds() и даже удаляет уровни масштабирования от зум-контроль.

+0

Этот запретный пользователь может установить вручную увеличение. – candlejack

+0

@candlejack Так точно, как описано в моем ответе? – Flygenring

+2

Вы можете установить 'maxZoom' перед установкой границ, а затем снова отключить его, используя' map.setOptions ({maxZoom: undefined}) 'в событии' idle', запущенном путем изменения границ. Это предотвращает эффект масштабирования и уменьшения, вместо этого уменьшает масштаб в событии 'idle'. –

6

Путь предотвратить карту от масштабирования далеко, добавляя эту строку кода:

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

Сразу после этой строки:

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

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

Если у вас есть какие-либо проблемы или вопросы, просто оставьте меня комментарий на блоге я писал об этом в http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the-map-from-zooming-in-too-close-on-a-single-marker

+1

Мне нравится это решение, но вставьте setzoom внутри if, если вы не вызываете его каждый раз. Также может быть временный побочный эффект, который возвращает «undefined» из getzoom(). Решение: zoom = map.getZoom(); if (typeof zoom! == 'undefined' && zoom> 8) map.setZoom (8); –

3

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

Вот способ сначала проверить, если точки находятся в пределах определенного расстояния друг от друга, а затем, если они меньше, чем минимальное расстояние, расширить границы с помощью этого минимального расстояния:

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

Надежда это помогает кто то!

0

У меня есть душа, основанная на ограничении максимального увеличения при установке границ. Работы для меня (проверено на 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); 
    } 
}); 
16
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 }); 

Использование опции MaxZoom лучше работают для не масштабирования, чтобы закрыть на отметки у вас есть.

+1

+1 прямолинейный! – Tamir

+0

простой и удобный ... – Lupin

+0

лучшее и самое простое решение. благодаря! –

0

И .. вот еще один.
Та же самая идея, как MRT и Райана, но

  • также работает, если размер границы не в точности равна нулю (*)
  • предотвращает искажение вблизи полюсов
  • использует 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; 
} 

EDIT: Я не совсем уверен, правильно ли вычисляется отношение, учитывая, что у нас есть проекция Меркатора. Я мог бы повторно редактировать этот ..

9

и можно использовать

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

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

удачи, rarutu

+0

Отлично! Благодаря ;) – RevConcept

2

Это дает вам прямой контроль на максимально допустимый масштаб на границах подгонки.

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

Я решил с этим куском, так как 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 для пользователя было бы невозможно.

0

Ее здесь Google Maps v3: Enforcing min. zoom level when using fitBounds уже ответил он работает, как ожидалось :), так что теперь, если после того, как подходят границы масштабирования меньше позволяет говорить 13, то вы можете установить новый масштаб, который вы preffer

7

После того, как вы добавили все реальные границы добавить эти строки

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

это получить центр реальных границ добавляет две дополнительные точки один на северо-восток и один к юго-западу от вас центрирования

Это эффективно устанавливает минимальное увеличение, изменение Вэл ue смещения для увеличения или уменьшения увеличения

0

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

0

Что касается меня, ребята, я решаю его, создавая праздное событие после 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); 
    } 
});