OpenLayers - перерисовка карты после изменения размера контейнера

25

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

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

Как заставить карту перерисоваться и адаптироваться к новому размеру?

Обращение redraw()ко всем слоям не помогло. Ни один не сделал увеличение и уменьшение.

Я протестировал это с описанными результатами в Opera, Chrome и Firefox. В IE8, к удивлению, проблема не возникла, и карта автоматически адаптировалась.

Упрощенная веб-страница для тестирования:

<html>
  <head>
    <style>
      #mapbox { 
        width: 300px;
        height: 500px;
        border: 1px solid black;
      }
    </style>

    <script src="http://openlayers.org/api/OpenLayers.js"></script>
  </head>

  <body>
    <div id="mapbox"></div>
    <input type="button" id="test" value="resize">

    <script>    
      var map = new OpenLayers.Map('mapbox');
      map.addLayer(new OpenLayers.Layer.OSM());      

      map.setCenter(
        new OpenLayers.LonLat(1000000, 7000000), 5);

      document.getElementById('test').onclick = function() {
        document.getElementById('mapbox').style.width = '1000px';
      }
    </script>
  </body>
</html>
чертенок
источник

Ответы:

35

Вам необходимо вызвать API для обновления размера карты.

http://dev.openlayers.org/docs/files/OpenLayers/Map-js.html#OpenLayers.Map.updateSize

Вот как мы это делаем

window.onresize = function()
{
  setTimeout( function() { map.updateSize();}, 200);
}

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

Вадим
источник
1
Ну, я считаю, что задержка зависит от вашего приложения. ;) В любом случае, спасибо, еще раз я что-то пропустил в документах.
Бес
1
Я также не вижу причин для задержки, поэтому оставил это. Спасибо
zod
1
@ Вадим Отличный ответ, но у меня не работает. Мой код похож body onload=init()и initинициализирует карту. Это из-за этого? Кроме того, это будет хорошим решением для адаптивного дизайна? window.onload=window.onresize=function(){//resize here, Спасибо
Слевин
Интересно, был ли setTimout попыткой вызова только каждые 200 мс. К сожалению, это немного сложнее, нужно иметь a, setIntervalкоторый запускается каждые 200 мс, а затем иметь логическое значение var didResize, которое установлено в значение true onresize()и установлено falseпосле map.updateSize().
andrewb
1
SetTimeout, вероятно, должен был гарантировать, что карта была загружена, а остальная часть dom была визуализирована. В настоящее время я использую тот же хак из-за моего непонимания жизненного цикла представления Marionette.
ca0v
8

Да, используйте map.updateSize (), как говорит Вадим (также не уверен, почему задержка!) Документация

Я обычно помещаю полноэкранный переключатель на карты, который работает просто путем переключения класса css контейнера карты и последующего вызова updateSize ()

function toggleFullScreen(mapContainer) {
    if ($(mapContainer).hasClass("normal")) {
        $(mapContainer).addClass("fullscreen").removeClass("normal");
    } else {
        $(mapContainer).addClass("normal").removeClass("fullscreen");
    }
    map.updateSize();
}
andyb
источник
2

Это не элегантно, но у меня это хорошо сработало

window.onresize = function(event)
{
   map.zoomOut(); map.zoomIn();
}
JFHack
источник
это был единственный ответ, который работал для меня
Мэтью Локк
2

Еще один комментарий к первому (правильному) ответу:

Timeout-Event необходим, если вы ожидаете события window.resize. В противном случае размер карты будет изменяться каждую миллисекунду, если пользователь начнет изменять размер окна (мне это нужно для Firefox). Поэтому, если вы хотите проверить размер окна, тайм-аут весьма полезен, соответственно. необходимо. См .: /programming/5489946/jquery-how-to-wait-for-the-end-or-resize-event-and-only-then-perform-an-ac или событие завершения изменения размера jQuery

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

leole
источник
1

Я перепробовал все вещи, описанные здесь, но у меня ничего не получалось. Итак, я понял, что когда я помещал «полноэкранный» класс на карту, событие resize не было запущено. Я исправляю это с помощью:

$(window).trigger('resize');
nicolasaiz173
источник
1

Использование метода setTimeout, описанного выше, не имеет для меня большого смысла (возможно, это обходной путь для более старой версии OL), но setTimeout можно использовать для уменьшения количества вызовов map.updateSize () и другого связанного кода, такого как это:

$(window).resize(function () {
  if (window.resizeMapUpdateTimer) {
    clearTimeout(window.resizeMapUpdateTimer)
  }
  window.resizeMapUpdateTimer= setTimeout(function () {
    // Update container size
    map.updateSize()
  }, 200)
})
Саймон Хатчисон
источник
0

Я думаю, что изменение стиля карты div автоматически изменит размер панели карты.

document.getElementById("map-panel").style.width = "500px";

я надеюсь, что это поможет вам ...

Арагон
источник
При изменении размера изменение атрибутов размера контейнера работает для карты, но не для нарисованных объектов. Добавление updateSize () гарантирует, что функции видны.
Код
0

Это работает для меня:

this.$nextTick(
    function() {
        OL_MAP_INSTANCE.updateSize();
    }
);

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

Доктор
источник