OpenLayers - redesenhando o mapa após o redimensionamento do contêiner

25

No meu aplicativo da web, desejo permitir que os usuários definam o tamanho do contêiner de mapa.

Tudo funcionou bem quando o contêiner foi expandido levemente (aparentemente, porque os ladrilhos que estavam logo atrás da borda já estavam carregados). No entanto, quando o contêiner é expandido significativamente (no exemplo a seguir, de 300 a 1000 px de largura), resta espaço em branco.

Como fazer o mapa redesenhar e se adaptar ao novo tamanho?

Chamar redraw()todas as camadas não ajudou. Nem zoom in e out.

Eu testei isso com os resultados descritos no Opera, Chrome e Firefox. Surpreendentemente, no IE8, o problema não ocorreu e o mapa foi adaptado automaticamente.

Uma página da web simplificada para teste:

<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>
Criança levada
fonte

Respostas:

35

Você precisa chamar a API para atualizar o tamanho do mapa.

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

Aqui está como fazemos

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

Você pode ver que fizemos um pequeno atraso e, sinceramente, não me lembro exatamente o motivo, mas tivemos que esperar um pouco antes de chamar a API para redimensionar-se.

Vadim
fonte
1
Bem, acredito que o atraso é específico da sua aplicação. ;) De qualquer forma, obrigado, mais uma vez eu perdi algo nos documentos.
Imp
1
Também não vejo razão para o atraso, então deixei de fora. Graças
Zod
1
@Vadim Great anser, mas não funciona para mim. Meu código é como body onload=init()e initinicializa o mapa. É por isso? Além disso, essa seria uma boa solução para o design responsivo? window.onload=window.onresize=function(){//resize here. Graças
slevin
Gostaria de saber se setTimout foi uma tentativa de fazer com que ele chamasse apenas a cada 200ms. Infelizmente, é um pouco mais complicado, é necessário ter um setIntervalque seja executado a cada 200 ms e, em seguida, ter um booleano var didResizedefinido como true onresize()e definido como falsedepois map.updateSize().
58568 Andrewb
1
O setTimeout provavelmente garantiria que o mapa fosse carregado e o restante do dom fosse renderizado. Atualmente, estou usando o mesmo hack devido à minha falta de entendimento do ciclo de vida da exibição Marionette.
ca0v
8

Sim, usar map.updateSize () como diz Vadim (também não sei por que o atraso!) Documentação

Costumo colocar um botão de alternância de tela cheia nos mapas, que funciona simplesmente alternando a classe css do contêiner de mapa e depois chamando updateSize ()

function toggleFullScreen(mapContainer) {
    if ($(mapContainer).hasClass("normal")) {
        $(mapContainer).addClass("fullscreen").removeClass("normal");
    } else {
        $(mapContainer).addClass("normal").removeClass("fullscreen");
    }
    map.updateSize();
}
andyb
fonte
2

Não é elegante, mas funcionou bem para mim

window.onresize = function(event)
{
   map.zoomOut(); map.zoomIn();
}
JFHack
fonte
esta foi a única resposta que funcionou para mim
Matthew Bloqueio
2

Outro comentário para a primeira resposta (correta):

O timeout-Event é necessário se você esperar pelo evento window.resize. Caso contrário, o mapa será redimensionado a cada milissegundo se um usuário começar a redimensionar a janela (eu precisava dele para o Firefox). Portanto, se você deseja verificar o tamanho da janela, o tempo limite é bastante útil. necessário. Consulte: /programming/5489946/jquery-how-to-wait-for-the-end-or-resize-event-and-only-then-perform-an-ac ou jQuery redimensionar o evento final

(desculpe, não posso adicionar um comentário, portanto, outra resposta)

leole
fonte
1

Eu tentei todas as coisas descritas aqui, mas nada funcionou para mim. Então, percebi que quando eu colocava uma classe 'tela cheia' no mapa, o evento de redimensionamento não era disparado. Corrijo isso com:

$(window).trigger('resize');
nicolasaiz173
fonte
1

A maneira como setTimeout é usado acima não faz muito sentido para mim (talvez uma solução alternativa para uma versão OL mais antiga), mas setTimeout pode ser usado para reduzir o número de chamadas para map.updateSize () e outros códigos associados, como isto:

$(window).resize(function () {
  if (window.resizeMapUpdateTimer) {
    clearTimeout(window.resizeMapUpdateTimer)
  }
  window.resizeMapUpdateTimer= setTimeout(function () {
    // Update container size
    map.updateSize()
  }, 200)
})
Simon Hutchison
fonte
0

Eu acho que mudar o estilo do mapa div automaticamente mudará o tamanho do painel do mapa.

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

espero que ajude você ...

Aragão
fonte
Ao redimensionar, a alteração dos atributos de tamanho do contêiner funciona para o mapa, mas não para os recursos desenhados. A adição de updateSize () garante que os recursos estejam visíveis.
Kde
0

Isso está funcionando para mim:

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

O $ nextTick é importante porque permitirá aguardar a próxima atualização antes de levar em conta o novo tamanho do contêiner de mapa.

Médico
fonte