OpenLayers: ridisegna la mappa dopo il ridimensionamento del contenitore


25

Nella mia applicazione Web, voglio consentire agli utenti di impostare la dimensione del contenitore della mappa.

Tutto ha funzionato bene quando il contenitore è stato leggermente espanso (apparentemente questo perché le piastrelle che erano appena dietro il bordo erano già state caricate). Tuttavia, quando il contenitore viene espanso in modo significativo (nell'esempio seguente, da 300 a 1000 pixel di larghezza), rimane spazio vuoto.

Come ridisegnare la mappa e adattarsi alle nuove dimensioni?

Chiamare redraw()su tutti i livelli non ha aiutato. Né lo zoom avanti e indietro.

Ho provato questo con i risultati descritti in Opera, Chrome e Firefox. In IE8, sorprendentemente, il problema non si è verificato e la mappa si è adattata automaticamente.

Una pagina web semplificata per i test:

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

Risposte:


35

È necessario chiamare l'API per aggiornare la dimensione della mappa.

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

Ecco come lo facciamo

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

Puoi vedere che abbiamo fatto un leggero ritardo, e onestamente non ricordo il motivo esatto, ma abbiamo dovuto aspettare un attimo prima di chiamare l'API per ridimensionare se stesso.


1
Bene, credo che il ritardo sia specifico dell'applicazione. ;) Comunque, grazie, ancora una volta mi è mancato qualcosa nei documenti.
Imp

1
Inoltre non vedo alcun motivo per il ritardo, quindi l'ho lasciato fuori. Grazie
zod

1
@Vadim Ottima risposta, ma non funziona per me. Il mio codice è simile body onload=init()e initinizializza la mappa. È per questo? Inoltre, sarebbe una buona soluzione per un design reattivo? window.onload=window.onresize=function(){//resize here. Grazie
slevin,

Mi chiedo se setTimout sia stato un tentativo di farlo chiamare solo ogni 200ms. Sfortunatamente è un po 'più complicato, è necessario avere un valore setIntervalche gira ogni 200 ms, quindi avere un valore booleano var didResizeimpostato su true onresize()e impostato su falsedopo che map.updateSize()viene chiamato.
Andrew

1
È probabile che setTimeout assicuri il caricamento della mappa e il rendering del resto della dom. Attualmente sto usando lo stesso trucco a causa della mia scarsa comprensione del ciclo di vita della vista Marionette.
circa

8

Sì, usa map.updateSize () come dice Vadim (anche non sai perché il ritardo!) Documentazione

Di solito metto un pulsante di attivazione / disattivazione a schermo intero sulle mappe, che funziona semplicemente cambiando la classe css del contenitore delle mappe e chiamando quindi updateSize ()

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

2

Non è elegante, ma ha funzionato bene per me

window.onresize = function(event)
{
   map.zoomOut(); map.zoomIn();
}

questa è stata l'unica risposta che ha funzionato per me
Matthew Lock,

2

Un altro commento alla prima (corretta) risposta:

Il timeout-Event è necessario se si attende l'evento window.resize. Altrimenti la mappa verrà ridimensionata ogni millisecondo se un utente inizia a ridimensionare la finestra (ne avevo bisogno per Firefox). Pertanto, se si desidera verificare la dimensione della finestra, il timeout è piuttosto utile resp. necessario. Vedi: /programming/5489946/jquery-how-to-wait-for-the-end-or-resize-event-and-only-then-perform-an-ac o jQuery resize end event

(scusa, non posso aggiungere un commento, quindi un'altra risposta)


1

Ho provato tutte le cose descritte qui, ma niente ha funzionato per me. Quindi, mi sono reso conto che quando stavo inserendo una classe "a schermo intero" sulla mappa, l'evento di ridimensionamento non era stato attivato. Lo risolvo con:

$(window).trigger('resize');

1

Il modo in cui setTimeout è usato sopra non ha molto senso per me (forse una soluzione alternativa per una versione OL precedente), ma setTimeout può essere utilizzato per ridurre il numero di chiamate a map.updateSize () e altri codici associati come Questo:

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

0

penso che cambiare lo stile del div mappa automaticamente cambierà la dimensione del pannello della mappa.

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

spero che ti aiuti ...


Al ridimensionamento, la modifica degli attributi di dimensione del contenitore funziona per la mappa, ma non per le funzioni disegnate. L'aggiunta di updateSize () assicura che le funzionalità siano visibili.
kode

0

Questo funziona per me:

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

$ NextTick è importante perché consentirà di attendere il prossimo aggiornamento prima di prendere in considerazione le nuove dimensioni del contenitore della mappa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.