OpenLayers - Neuzeichnen der Karte nach der Größenänderung des Containers


25

In meiner Webanwendung möchte ich Benutzern ermöglichen, die Größe des Kartencontainers festzulegen.

Alles hat gut funktioniert, als der Container leicht erweitert wurde (anscheinend, weil die Fliesen, die sich direkt hinter der Grenze befanden, bereits geladen waren). Wenn der Container jedoch erheblich erweitert wird (im folgenden Beispiel von 300 auf 1000 Pixel Breite), verbleibt ein leerer Bereich.

Wie kann ich die Karte neu zeichnen und an die neue Größe anpassen?

Das Aufrufen redraw()aller Ebenen hat nicht geholfen. Zoomen und Zoomen nicht.

Ich habe dies mit den beschriebenen Ergebnissen in Opera, Chrome und Firefox getestet. In IE8 trat das Problem überraschenderweise nicht auf und die Karte wurde automatisch angepasst.

Eine vereinfachte Webseite zum Testen:

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

Antworten:


35

Sie müssen die API aufrufen, um die Kartengröße zu aktualisieren.

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

So machen wir es

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

Sie sehen, wir haben uns etwas verzögert, und ehrlich gesagt weiß ich nicht genau, warum, aber wir mussten ein wenig warten, bevor wir API aufriefen, um die Größe selbst zu ändern.


1
Nun, ich glaube, die Verzögerung ist anwendungsspezifisch. ;) Wie auch immer, danke, ich habe mal wieder etwas in den Dokumenten verpasst.
Imp

1
Ich sehe auch keinen Grund für die Verzögerung, also habe ich sie weggelassen. Danke
zod

1
@Vadim Großartiger Anser, funktioniert aber bei mir nicht. Mein Code ist wie body onload=init()und initinitialisiert die Karte. Liegt es daran? Wäre dies auch eine gute Lösung für Responsive Design? window.onload=window.onresize=function(){//resize here. Vielen Dank
Slevin

Ich frage mich, ob setTimout ein Versuch war, es nur alle 200ms aufzurufen. Leider ist es etwas komplizierter, es muss eine haben setInterval, die alle 200 ms ausgeführt wird, dann muss ein Boolescher Wert auf var didResizegesetzt true onresize()werden und falsedanach map.updateSize()wird aufgerufen.
Andrewb

1
Das setTimeout stellte wahrscheinlich sicher, dass die Karte geladen und der Rest des Doms gerendert wurde. Ich verwende momentan den gleichen Hack, da ich den Marionette-Lebenszyklus nicht verstehe.
30.

8

Ja, verwenden map.updateSize () als Vadim sagt (auch nicht sicher , warum die Verzögerung!) Dokumentation

Ich habe Karten normalerweise mit einer Vollbild-Umschaltfläche versehen, die einfach durch Umschalten der CSS-Klasse des Kartencontainers und anschließenden Aufruf von updateSize () funktioniert.

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

2

Ist nicht elegant, hat aber bei mir gut funktioniert

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

Dies war die einzige Antwort, die für mich funktioniert hat
Matthew Lock

2

Noch ein Kommentar zur ersten (richtigen) Antwort:

Das Timeout-Event wird benötigt, wenn Sie auf das window.resize-Event warten. Andernfalls wird die Größe der Karte jede Millisekunde geändert, wenn ein Benutzer die Größe des Fensters ändert (ich brauchte es für Firefox). Wenn Sie also nach der Fenstergröße suchen möchten, ist das Timeout sehr nützlich. erforderlich. Siehe: https://stackoverflow.com/questions/5489946/jquery-how-to-wait-for-end-or-resize-event-and-only-then-perform-an-ac oder jQuery resize end event

(Entschuldigung, ich kann keinen Kommentar hinzufügen, daher eine andere Antwort)


1

Ich habe alle hier beschriebenen Dinge ausprobiert, aber nichts hat für mich funktioniert. Als ich der Karte eine Vollbildklasse hinzufügte, wurde das Größenänderungsereignis nicht ausgelöst. Ich behebe das mit:

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

1

Die Art und Weise, wie setTimeout oben verwendet wird, ist für mich nicht sehr sinnvoll (möglicherweise eine Problemumgehung für eine ältere OL-Version), aber setTimeout kann verwendet werden, um die Anzahl der Aufrufe von map.updateSize () und anderen zugehörigen Codes zu verringern Dies:

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

0

Ich denke, dass das Ändern des Stils von Map Div automatisch die Größe des Map Panels ändert.

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

ich hoffe es hilft dir ...


Beim Ändern der Größe wirkt sich das Ändern der Größenattribute des Containers auf die Karte aus, nicht jedoch auf die gezeichneten Features. Durch Hinzufügen von updateSize () wird sichergestellt, dass die Funktionen sichtbar sind.
Kode

0

Das funktioniert bei mir:

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

Der $ nextTick ist wichtig, da auf die nächste Aktualisierung gewartet werden kann, bevor die neue Größe des Kartencontainers berücksichtigt wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.