OpenLayers - redibujando el mapa después de cambiar el tamaño del contenedor

25

En mi aplicación web, quiero permitir a los usuarios establecer el tamaño del contenedor del mapa.

Todo funcionó bien cuando el contenedor se expandió ligeramente (aparentemente esto se debe a que las baldosas que estaban justo detrás del borde ya estaban cargadas). Sin embargo, cuando el contenedor se expande significativamente (en el siguiente ejemplo, de 300 a 1000 px de ancho), queda espacio en blanco.

¿Cómo volver a dibujar el mapa y adaptarlo al nuevo tamaño?

Llamar redraw()a todas las capas no ayudó. Tampoco acercar y alejar.

Probé esto con los resultados descritos en Opera, Chrome y Firefox. En IE8, sorprendentemente, el problema no ocurrió y el mapa se adaptó automáticamente.

Una página web simplificada para probar:

<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>
Diablillo
fuente

Respuestas:

35

Debe llamar a la API para actualizar el tamaño del mapa.

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

Así es como lo hacemos

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

Puedes ver que hicimos un ligero retraso, y sinceramente, no recuerdo la razón exacta por qué, pero tuvimos que esperar un poco antes de llamar a API para cambiar el tamaño.

Vadim
fuente
1
Bueno, creo que la demora es específica de su aplicación. ;) De todos modos, gracias, una vez más me perdí algo en los documentos.
Imp
1
Tampoco veo ninguna razón para el retraso, así que lo dejé fuera. Gracias
zod
1
@Vadim Gran respuesta, pero no funciona para mí. Mi código es como body onload=init()e initinicializa el mapa. ¿Es por eso? Además, ¿sería una buena solución para un diseño receptivo? window.onload=window.onresize=function(){//resize here. Gracias
slevin
Me pregunto si setTimout fue un intento de llamar solo cada 200 ms. Desafortunadamente es un poco más complicado, necesita tener un setIntervalque se ejecute cada 200 ms, luego tener un valor booleano var didResizeque se establece true onresize()y se llama a establecer falsedespués map.updateSize().
andrewb
1
Es probable que setTimeout garantice que se cargó el mapa y se procesó el resto del dom. Actualmente estoy usando el mismo truco debido a mi falta de comprensión del ciclo de vida de la vista Marionette.
ca0v
8

Sí, utilice map.updateSize () como dice Vadim (que tampoco está seguro de por qué el retraso!) La documentación

Comúnmente pongo un botón de alternancia de pantalla completa en los mapas, que funciona simplemente cambiando la clase css del contenedor del mapa y luego llamando a updateSize ()

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

No es elegante, pero funcionó bien para mí.

window.onresize = function(event)
{
   map.zoomOut(); map.zoomIn();
}
JFHack
fuente
esta fue la única respuesta que funcionó para mí
Matthew Lock
2

Otro comentario a la primera respuesta (correcta):

El evento de tiempo de espera es necesario si espera el evento window.resize. De lo contrario, el mapa cambiará de tamaño cada milisegundo si un usuario comienza a cambiar el tamaño de la ventana (lo necesitaba para Firefox). Por lo tanto, si desea verificar el tamaño de la ventana, el tiempo de espera es bastante útil resp. necesario. Ver: /programming/5489946/jquery-how-to-wait-for-the-end-or-resize-event-and-only-then-perform-an-ac o jQuery cambiar el tamaño del evento final

(lo siento, no puedo agregar un comentario, por lo tanto, otra respuesta)

leole
fuente
1

Intenté todas las cosas descritas aquí, pero nada funcionó para mí. Entonces, me di cuenta de que cuando estaba colocando una clase de 'pantalla completa' en el mapa, no se activó el evento de cambio de tamaño. Arreglo esto con:

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

La forma en que setTimeout se usa arriba no tiene mucho sentido para mí (tal vez una solución para una versión OL más antigua), pero setTimeout se puede usar para reducir la cantidad de llamadas a map.updateSize () y otros códigos asociados como esta:

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

Creo que cambiar el estilo del mapa div automáticamente cambiará el tamaño del panel del mapa.

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

Espero que te ayude...

Aragón
fuente
Al cambiar el tamaño, cambiar los atributos de tamaño del contenedor funciona para el mapa, pero no para las entidades dibujadas. Agregar updateSize () asegura que las características sean visibles.
kode
0

Esto es trabajo para mí:

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

El $ nextTick es importante porque permitirá esperar la próxima actualización antes de tener en cuenta el nuevo tamaño del contenedor del mapa.

Doctor
fuente