OpenLayers - vẽ lại bản đồ sau khi thay đổi kích thước container


25

Trong ứng dụng web của mình, tôi muốn cho phép người dùng đặt kích thước của vùng chứa bản đồ.

Mọi thứ hoạt động tốt khi container được mở rộng một chút (rõ ràng điều này là do các gạch ngay phía sau đường viền đã được tải). Tuy nhiên, khi vùng chứa được mở rộng đáng kể (trong ví dụ sau, chiều rộng từ 300 đến 1000px), có khoảng trống còn lại.

Làm thế nào để làm cho bản đồ vẽ lại và thích ứng với kích thước mới?

Gọi redraw()tất cả các lớp đã không giúp đỡ. Không phóng to và thu nhỏ.

Tôi đã thử nghiệm điều này với các kết quả được mô tả trong Opera, Chrome và Firefox. Trong IE8, đáng ngạc nhiên, sự cố đã không xảy ra và bản đồ tự động điều chỉnh.

Một trang web đơn giản để thử nghiệm:

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

Câu trả lời:


35

Bạn cần gọi API để cập nhật kích thước bản đồ.

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

Đây là cách chúng tôi làm điều đó

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

Bạn có thể thấy chúng tôi đã làm một chút chậm trễ và thành thật mà nói tôi không nhớ lý do chính xác tại sao, nhưng chúng tôi phải chờ một chút trước khi gọi API để thay đổi kích thước.


1
Vâng, tôi tin rằng sự chậm trễ là ứng dụng cụ thể của bạn. ;) Dù sao, cảm ơn bạn, một lần nữa tôi đã bỏ lỡ một cái gì đó trong các tài liệu.
Imp

1
Tôi cũng thấy không có lý do cho sự chậm trễ, vì vậy hãy bỏ nó đi. Cảm ơn
zod

1
@Vadim Tuyệt vời anser, nhưng không làm việc cho tôi. Mã của tôi là như thế body onload=init()initkhởi tạo bản đồ. Có phải vì điều đó? Ngoài ra, đây sẽ là một giải pháp tốt cho thiết kế đáp ứng? window.onload=window.onresize=function(){//resize here. Cảm ơn
slevin

Tôi tự hỏi nếu setTimout là một nỗ lực để làm cho nó chỉ gọi mỗi 200ms. Thật không may, nó phức tạp hơn một chút, cần phải có một setInterval200 giây chạy, sau đó có một boolean var didResizeđược đặt thành true onresize()và được đặt thành falsesau map.updateSize()được gọi.
andrewb

1
SetTimeout có khả năng đảm bảo bản đồ đã được tải và phần còn lại của dom được hiển thị. Hiện tại tôi đang sử dụng cùng một bản hack do tôi không hiểu về vòng đời của Marionette.
ca0v 30/03/2015

8

Có, sử dụng map.updateSize () như Vadim nói (cũng không chắc chắn lý do tại sao sự chậm trễ!) Tài liệu

Tôi thường đặt nút chuyển đổi toàn màn hình trên bản đồ, hoạt động đơn giản bằng cách chuyển lớp css của bộ chứa bản đồ và sau đó gọi updateSize ()

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

2

Không thanh lịch, nhưng nó hoạt động tốt với tôi

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

đây là câu trả lời duy nhất có hiệu quả với tôi
Matthew Lock

2

Một nhận xét khác cho câu trả lời đầu tiên (đúng):

Sự kiện hết thời gian là cần thiết nếu bạn chờ đợi sự kiện window.resize. Nếu không, bản đồ sẽ được thay đổi kích thước mỗi mili giây nếu người dùng bắt đầu thay đổi kích thước cửa sổ (tôi cần nó cho Firefox). Do đó, nếu bạn muốn kiểm tra kích thước Cửa sổ, thì thời gian chờ là khá hữu ích. cần thiết Xem: /programming/5489946/jquery-how-to-wait-for-the-end-or-resize-event-and-only-then-perform-an-ac hoặc jQuery thay đổi kích thước sự kiện kết thúc

(xin lỗi, tôi không thể thêm một bình luận, vì vậy một câu trả lời khác)


1

Tôi đã thử tất cả những điều được mô tả ở đây nhưng không có gì làm việc cho tôi. Vì vậy, tôi nhận ra rằng khi tôi đưa lớp 'toàn màn hình' lên bản đồ, sự kiện thay đổi kích thước sẽ không bị hủy. Tôi sửa lỗi này bằng:

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

1

Cách setTimeout được sử dụng ở trên không có ý nghĩa nhiều đối với tôi (có thể là cách giải quyết cho phiên bản OL cũ hơn), nhưng setTimeout có thể được sử dụng để giảm số lượng cuộc gọi đến map.updateSize () và các mã liên quan khác như điều này:

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

0

Tôi nghĩ rằng việc thay đổi phong cách của div bản đồ sẽ tự động thay đổi kích thước của bảng bản đồ.

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

Tôi hy vọng nó sẽ giúp bạn...


Khi thay đổi kích thước thay đổi các thuộc tính kích thước của bộ chứa hoạt động cho bản đồ, nhưng không phải cho các tính năng được vẽ. Thêm updateSize () đảm bảo rằng các tính năng được hiển thị.
kode

0

Điều này làm việc cho tôi:

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

$ NextTick rất quan trọng vì nó sẽ cho phép chờ làm mới tiếp theo trước khi tính đến kích thước mới của bộ chứa bản đồ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.