2009-06-16 2 views
7

Я пытаюсь получить границы карты после изменения масштаба, , но событие zoom_changed срабатывает до Оценки были пересчитаны. Поэтому в обработчике zoom_changed вы получаете предыдущие оценки, а не новые границы.Получите границы карты google v3 после изменения масштаба

Есть ли способ получить правильные границы при изменении масштаба?

ответ

3

От API documentation:

Если вы пытаетесь обнаружить изменение в окне просмотра, обязательно использовать специальное событие bounds_changed, а не составной zoom_changed и center_changed событий. Поскольку API Карт запускает эти события независимо друг от друга, get_bounds() может не сообщать о полезных результатах до тех пор, пока авторитетная версия окна просмотра не изменится. Если вы хотите get_bounds() после такого события, обязательно прослушайте событие bounds_changed.

+0

Использование события bounds_changed вместо zoom_changed в этом случае является нонсенсом. Он срабатывает в любом случае, когда границы меняются, но его интересуют только случаи, когда масштаб изменяется. – TMS

+1

@ tomas-t Я не согласен с тем, что обработка события bounds_changed является «бессмыслицей». Если вы после границ изменили масштаб, не можете ли вы проверить getZoom в вашем обработчике bounds_change? Документация, которую я опубликовал, оправдывает поведение (ошибка краевого случая), но обходной путь кажется мне довольно простым. – RedBlueThing

+0

, конечно, вы можете, но для того, что OP хочет обработать событие bounds_changed, а не zoom_changed, является излишним излишним, потому что событие срабатывает даже во время панорамирования и т. Д. Посмотрите на обходной путь в моем ответе. – TMS

17

Это bug, пожалуйста, напишите эту проблему, если вы заинтересованы.

Существует уродливая обходной путь для этого:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function (e) { 
      my_zoom_handler(); // do your job here 
    }); 
}); 
+0

+1 Я согласен, что это ошибка, и API для этого случая не является интуитивным. Было бы неплохо, если бы zoom_change был отправлен после вычисления новых границ. – RedBlueThing

+0

Этот код не будет работать, если перед событием масштабирования произойдет событие 'bounds_changed'. API Maps запускает эти последние события самостоятельно. – mgPePe

+0

Большой обходной путь. Я изменил внутренний event-listener на '' idle'' вместо '' bounds_changed'', поскольку во время анимации запускается событие 'bounds_changed''. Я думаю, что ФП хотел, чтобы это произошло после. – Todd

2

Чтобы связать bounds_changed и работать с маркерами/карты материала после масштабирования используйте:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    this.zoomChanged = true; 
}); 

google.maps.event.addListener(map,"bounds_changed",function() { 
    if (this.zoomChanged) { 
     this.zoomChanged = false; 
     // DO YOUR STUFF 
    } 
}); 
0

У меня была такая же проблема. Вот что я, наконец, получил, чтобы решить некоторые из проблем, которые у меня были с другими решениями.

* Правильно навязывает границы независимо от того, используете ли вы мышь или клавиши со стрелками

* Не остановятся края, если удерживать нажатой клавиши со стрелками, из-за кастрюли ускорения, заставляя его «выброс» (попробуйте удерживать клавишу со стрелкой в ​​одном направлении, пока вы не нажмете край, затем отпустите и снова нажмите ее), а с некоторыми решениями она будет прокручиваться чуть больше)

* Не отскакивает назад, когда он попадает в край

* Правильно применяет ограничения при изменении масштаба

EDIT: Хорошо, поэтому он работает, когда вы изменяете масштаб с помощью колесика прокрутки, но не с помощью регулятора зуммирования. Позвольте мне немного поиграть с ним, и я посмотрю, смогу ли я это сделать тоже ...

EDIT 2: Оказывается, проблема в том, что я удалил элемент управления панорамированием. Пока присутствует управление панорамированием, это отлично работает, как с колесиком прокрутки, так и с регулятором зуммирования.

РЕДАКТИРОВАТЬ 3: Нет ... это не так. Я обновил код для управления зуммированием.

// bounds of the desired area 
var allowedBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(-64, -64), 
        new google.maps.LatLng(64, 64) 
        ); 

var zoomChanged = false; 

google.maps.event.addListener(map, 'center_changed', function() { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 
}, this); 

google.maps.event.addListener(map, 'zoom_changed', function() { 
    zoomChanged = true; 
}, this); 

google.maps.event.addListener(map, 'bounds_changed', function() { 
    if(zoomChanged) { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    zoomChanged = false; 
    } 
}, this); 
+0

При таком подходе я получаю ошибки «слишком много рекурсии». Если я вместо этого просто слушаю событие bounds_changed (игнорируя center_changed и zoom_changed), эта ошибка исчезает. С другой стороны, движения не на 100% идеальны, так как есть еще некоторый отскок. –

+0

@ JoseGómez, похоже, проблема, характерная для Google Chrome, попробуйте в Firefox. Я изучаю его дальше, чтобы проверить, могу ли я исправить эту проблему. См. Этот вопрос: http://stackoverflow.com/questions/15671480/uncaught-rangeerror-maximum-call-stack-size-exceeded-google-maps-when-i-try-to – qwertymodo

+0

@ JoseGómez Я решил проблему, установив v = 3 в строке запроса для скрипта API включает строку. то есть '' – qwertymodo

Смежные вопросы