Google Maps v3 fitBounds () 단일 마커에 대해 너무 가깝게 확대


93

최대 확대 / 축소 수준을 설정하는 방법이 fitBounds()있습니까? 내 문제는지도에 한 위치 만 제공 될 때 가능한 한 멀리 확대되어 실제로지도를 컨텍스트에서 벗어나 쓸모 없게 만든다는 것입니다. 아마도 내가 잘못된 접근 방식을 취하고 있습니까?

미리 감사드립니다!


2
stackoverflow.com/questions/4523023/… 훨씬 더 나은 솔루션입니다. 특히 @Nequins 대답
Kennet

답변:


139

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

}

4
원래 센터를 유지하는 데 좋은 아이디어입니다. fitBounds()메서드를 사용할 때 확대 / 축소 수준을 안정적으로 조정할 수없는 이유는 확대 / 축소가 비동기 적으로 발생하기 때문입니다. stackoverflow.com/questions/2989858/…
Metro Smurf

1
이것은 나를 위해 잘 작동했습니다. V3의 "function fitToMarkers (markers, map)"함수에지도 참조를 전달해야했지만 그 후에는 매력처럼 작동합니다!
Shane

4
그것을 사랑하십시오. 좋은 @ryan. 저에게 잘 맞았지만 제 경우에는 .01이 너무 많이 축소되어 .001이 최적의 지점에 도달했습니다.
willdanceforfun 2013 년

감사. @willdanceforfun 같은 경우처럼 001이 그 자리를 차지했습니다.
Goran Jakovljevic

1
이 솔루션을 추천합니다. stackoverflow.com/questions/2437683/…
NinjaOnSafari

40

다음과 maxZoom같이 MapOptions (api-reference) 에서 지도를 설정할 수 있습니다 .

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

이렇게하면 사용시지도가 더 깊게 확대되지 fitBounds()않고 확대 / 축소 컨트롤에서 확대 / 축소 수준이 제거됩니다.


@candlejack 내 대답에 정확히 설명되어 있습니까?
Flygenring 2017-04-26

8
당신은을 설정할 수 있습니다 maxZoom경계를 피팅하기 전에 다음 사용하여 다시 설정을 해제 map.setOptions({ maxZoom: undefined })켜기 idle이벤트의 경계를 변경하여 발사했다. 이렇게하면 idle이벤트 에서 확대 / 축소를 재설정하는 대신 확대 / 축소 효과를 방지 할 수 있습니다.
El Yobo

29

또 다른 해결책은 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);

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

MaxZoom 옵션을 사용하면 확대 / 축소하지 않아 마크에 가까워집니다.


환상적입니다! 생명의 은인!
Jaypee

18

실제 경계를 모두 추가했으면 다음 줄을 추가하십시오.

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

실제 경계의 중심을 얻은 다음 두 개의 추가 점을 하나는 북동쪽에, 다른 하나는 중심의 남서쪽에 추가합니다.

이것은 최소 줌을 효과적으로 설정하고, 오프셋 값을 변경하여 줌을 늘리거나 줄입니다.


12

단일 위치에 대한 경우 대신 setCenter () 및 setZoom ()을 사용할 수 있습니다.


가장 쉬운 솔루션
Alberto M

11

당신은 사용할 수 있습니다

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

이런 식으로지도가 초기화 된 후지도의 속성을 설정합니다. .... 원하는만큼 여러 번 설정할 수 있지만, 경우에 따라 ... fitBounds () 전에 설정할 수 있습니다.

행운을 빕니다, 라 루투


7

지도가 멀리까지 확대되는 것을 방지하는 방법은 다음 코드 줄을 추가하는 것입니다.

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- 에서 이에 대해 작성한 블로그 게시물에 댓글을 남겨주세요. 단일 마커에 너무 가까운 확대 / 축소에서지도


1
이 솔루션을 좋아하지만 매번 호출하지 않으려면 setzoom을 안에 삽입하십시오. getzoom ()에서 'undefined'를 반환하는 타이밍 부작용도있을 수 있습니다. 솔루션 : zoom = map.getZoom (); if (typeof zoom! == 'undefined'&& zoom> 8) map.setZoom (8);
Le Droid

5

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

이것이 누군가를 돕기를 바랍니다!


3

이를 통해 경계 피팅에 허용되는 최대 확대 / 축소를 직접 제어 할 수 있습니다.

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

3

저에게는 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);
  }
});

2

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 개 이상의 확대 / 축소 이벤트가 사용자에게 불가능합니다.


1

fitBounds()메서드를 호출 한 후 확대 / 축소 수준을 다시 설정하십시오. 지도가 해당 확대 / 축소 수준에 있어야하고 올바른 위치에 중앙에 위치하게됩니다.


0

경계를 맞출 때 최대 확대 / 축소 제한을 기반으로 한 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);
    }
});

0

그리고 .. 여기 또 하나가 있습니다.
mrt와 Ryan과 같은 생각이지만

  • 경계 크기가 정확히 0이 아닌 경우에도 작동합니다 (*).
  • 극 근처의 왜곡 방지
  • getNorthEast () 대신 getCenter () 사용

(*) 참고 : 상자가 이미 충분히 큰 경우이 두 점을 추가해도 효과가 없습니다. 따라서 더 이상의 검사가 필요하지 않습니다.

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

편집 : 메르카토르 투영법이 있다는 것을 고려할 때 비율 계산이 올바른지 정확히 모르겠습니다. 다시 편집 할 수 있습니다 ..



-1

두 개의 마커가 매우 가까울 때도 작동하는 솔루션을 소개합니다. 효과적인 최대 확대 / 축소 수준은 두 상황에서 동일합니다. 따라서 마커가 두 개 이상있을 때 불필요하게 축소되지 않습니다.

이 효과는 다시 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,
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.