최대 확대 / 축소 수준을 설정하는 방법이 fitBounds()
있습니까? 내 문제는지도에 한 위치 만 제공 될 때 가능한 한 멀리 확대되어 실제로지도를 컨텍스트에서 벗어나 쓸모 없게 만든다는 것입니다. 아마도 내가 잘못된 접근 방식을 취하고 있습니까?
미리 감사드립니다!
답변:
저는 mrt의 솔루션을 좋아합니다 (특히 매핑하거나 조정할 지점 수를 모를 때). 단, 마커가 더 이상지도 중앙에 있지 않도록 표시를 해제한다는 점이 다릅니다. lat 및 lng에서 .01을 빼서 추가 포인트를 추가하기 만하면 마커가 중앙에 유지됩니다. 훌륭하게 작동합니다, 감사합니다 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 :/
}
fitBounds()
메서드를 사용할 때 확대 / 축소 수준을 안정적으로 조정할 수없는 이유는 확대 / 축소가 비동기 적으로 발생하기 때문입니다. stackoverflow.com/questions/2989858/…
다음과 maxZoom
같이 MapOptions
(api-reference) 에서 지도를 설정할 수 있습니다 .
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });
이렇게하면 사용시지도가 더 깊게 확대되지 fitBounds()
않고 확대 / 축소 컨트롤에서 확대 / 축소 수준이 제거됩니다.
maxZoom
경계를 피팅하기 전에 다음 사용하여 다시 설정을 해제 map.setOptions({ maxZoom: undefined })
켜기 idle
이벤트의 경계를 변경하여 발사했다. 이렇게하면 idle
이벤트 에서 확대 / 축소를 재설정하는 대신 확대 / 축소 효과를 방지 할 수 있습니다.
또 다른 해결책은 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);
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });
MaxZoom 옵션을 사용하면 확대 / 축소하지 않아 마크에 가까워집니다.
실제 경계를 모두 추가했으면 다음 줄을 추가하십시오.
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));
실제 경계의 중심을 얻은 다음 두 개의 추가 점을 하나는 북동쪽에, 다른 하나는 중심의 남서쪽에 추가합니다.
이것은 최소 줌을 효과적으로 설정하고, 오프셋 값을 변경하여 줌을 늘리거나 줄입니다.
지도가 멀리까지 확대되는 것을 방지하는 방법은 다음 코드 줄을 추가하는 것입니다.
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- 에서 이에 대해 작성한 블로그 게시물에 댓글을 남겨주세요. 단일 마커에 너무 가까운 확대 / 축소에서지도
나는 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);
}
이것이 누군가를 돕기를 바랍니다!
이를 통해 경계 피팅에 허용되는 최대 확대 / 축소를 직접 제어 할 수 있습니다.
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);
};
저에게는 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);
}
});
Google Maps V3는 이벤트 기반이기 때문에이 청크로 해결했습니다.
zoom_changed 이벤트가 트리거 될 때 확대 / 축소를 적절한 크기로 다시 설정하도록 API에 지시 할 수 있습니다 .
var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
if (intial == true){
if (map.getZoom() > 11) {
map.setZoom(11);
intial = false;
}
}
});
필자 는 최종 fitBounds가 수행 될 때지도를 너무 많이 확대하지 않도록 초기 설정을 사용 했습니다. 11 개 이상의 확대 / 축소 이벤트가 사용자에게 불가능합니다.
fitBounds()
메서드를 호출 한 후 확대 / 축소 수준을 다시 설정하십시오. 지도가 해당 확대 / 축소 수준에 있어야하고 올바른 위치에 중앙에 위치하게됩니다.
경계를 맞출 때 최대 확대 / 축소 제한을 기반으로 한 soulution이 있습니다. 나를 위해 작동합니다 (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);
}
});
그리고 .. 여기 또 하나가 있습니다.
mrt와 Ryan과 같은 생각이지만
(*) 참고 : 상자가 이미 충분히 큰 경우이 두 점을 추가해도 효과가 없습니다. 따라서 더 이상의 검사가 필요하지 않습니다.
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;
}
편집 : 메르카토르 투영법이 있다는 것을 고려할 때 비율 계산이 올바른지 정확히 모르겠습니다. 다시 편집 할 수 있습니다 ..
여기에 이미 답변되어 있습니다. Google Maps v3 : Enforcing min. fitBounds 를 사용할 때 확대 / 축소 수준이 예상대로 작동합니다. :) 이제 fit bounds 이후 확대 / 축소가 13보다 작 으면 원하는 새 확대 / 축소를 설정할 수 있습니다.
두 개의 마커가 매우 가까울 때도 작동하는 솔루션을 소개합니다. 효과적인 최대 확대 / 축소 수준은 두 상황에서 동일합니다. 따라서 마커가 두 개 이상있을 때 불필요하게 축소되지 않습니다.
이 효과는 다시 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,
});