Chỉ mục Z trong OpenLayers 3: thứ tự lớp trong OL3


13

Có phương pháp nào để thay đổi chỉ mục Z của các lớp trong OpenLayers3 giống như trong phiên bản cũ không?

map.setLayerIndex(markers, 99); //set the marker layer to an arbitrarily high layer index

Tôi cần thay đổi thứ tự các lớp trong suốt bằng cách sử dụng bản đồ. Vì vậy, khả năng như xác định chỉ số z như thế này không giúp ích gì

var geoLayer = new ol.layer.Vector({
    source : new ol.source.GeoJSON({
        projection : 'EPSG:900913',
        url : './myGeoJson.json'
    }),
    style : function(feature, resolution) {
        var text = resolution < 5000 ? feature.get('name') : '';
        if (!styleCache[text]) {
            styleCache[text] = [new ol.style.Style({
                fill : new ol.style.Fill({
                    color : 'rgba(255, 255, 255, 0.1)'
                }),
                stroke : new ol.style.Stroke({
                    color : '#319FD3',
                    width : 1
                }),
                text : new ol.style.Text({
                    font : '12px Calibri,sans-serif',
                    text : text,
                    fill : new ol.style.Fill({
                        color : '#000'
                    }),
                    stroke : new ol.style.Stroke({
                        color : '#fff',
                        width : 3
                    })
                }),
                zIndex : 999
            })];
        }

    }
});

Tôi gặp khó khăn khi sử dụng giải pháp này, rất có thể là do tôi không hiểu những điều như vậy. bạn có thể xin vui lòng gửi một ví dụ về kết quả, tôi tin rằng nó sẽ thực sự giúp tôi ra?
dave_does_not_understand 10/12/14

Câu trả lời:


10

Hãy thử một cái gì đó như:

map.getLayers().setAt(99, markers)

Danh sách các lớp nằm trong một đối tượng kế thừa từ một ol.Collection. Xem tài liệu API cho nó.

Hãy cẩn thận, tôi khá chắc chắn, bạn không thể sử dụng số tùy ý như 99 in setAt: đối số thứ nhất là cho vị trí trong mảng các lớp và đối số thứ hai là dành cho tham chiếu phần tử lớp bạn muốn di chuyển. Để có được số lớp, chỉ cần sử dụngmap.getLayers().getArray().length

Mặc dù bạn thấy chúng ta có thể có được một mảng JS cho các lớp, nhưng tôi không chắc việc thao tác trực tiếp mảng này là cách tốt nhất vì các lớp có thể có các sự kiện được đính kèm. Bạn có thể sử dụng các ol.Collectionphương pháp thay thế.


Tôi đang tìm kiếm một giải pháp cho các lớp phủ, vì vậy tôi chỉ muốn thêm một bình luận nói rằng điều này (tất nhiên) cũng hoạt động cho các lớp phủ, vì map.getOverlays()trả về ol.Collectiongiống như map.getLayers()vậy.
decibyte

8

Nó không dễ dàng như trước đây, nhưng có một số phương pháp trợ giúp cho bộ sưu tập. Điều đó sẽ cho phép bạn làm những điều tương tự như ThomasG77 đã mô tả ở trên.

Giả sử bạn có một bản đồ có tên là bản đồ, với 4 lớp tức là [base_layer, đường bờ biển, bản đồ nhiệt, điểm đánh dấu]

Sau đó, bạn có thể lấy bộ sưu tập qua map.getLayers () và mảng các lớp thông qua map.getLayers (). GetArray () và các lớp riêng lẻ thông qua

var heatmap = map.getLayers().getArray()[2]

Bạn có thể thao tác thứ tự lớp thông qua các phương thức thu thập. Nó có thể sẽ giúp tạo ra một số chức năng của trình trợ giúp như:

function moveLayerBefore(map, old_idx, new_idx){
  var layer = map.getLayers().removeAt(old_idx);
  map.getLayers().insertAt(new_idx, layer);
}

Hy vọng rằng bạn có khả năng xác định các lớp của mình và tìm thấy chúng, tôi đã đặt id trên sáng tạo như layer.set ("layer_id" 44), sau đó có thể được truy xuất thông qua layer.get ("layer_id"). Sau đó, bạn có thể có một vòng lặp trình trợ giúp findLayer qua mảng lớp của bạn và trả về chỉ mục lớp.

function findLayer(map, layer_id){
  var layer_idx = -1;
  $.each(map.getLayers().getArray(), function (k,v){
    var this_layer_id = v.get("layer_id")
    if(this_layer_id == layer_id){
      layer_idx = k;
    }
  });
  return layer_idx;
}   

Theo cách này, tôi có thể có một cái gì đó như moveLayerB Before (map, findLayer (44), findLayer (22));

Dù sao, có rất nhiều phương pháp trong bộ sưu tập, nhưng hy vọng điều này sẽ giúp bạn bắt đầu. Và xin lỗi nếu có lỗi trong mã đó, đó là tất cả tâm trí được biên dịch ... :)


5

Dựa trên câu trả lời srussking tôi đã viết đoạn mã sau giả sử đối tượng bản đồ chính được gọi là map và nó là var toàn cầu, tôi thích sử dụng find layer theo tên chứ không phải id,

đây là mã của tôi:

function moveLayerBefore(old_idx, new_idx){
    if((old_idx === -1) || (new_idx === -1)){
        return false;
    }

    layer = map.getLayers().removeAt(old_idx);
    map.getLayers().insertAt(new_idx, layer);
}

function findLayer(layer_name){
    var layer_idx = -1;
    $.each(map.getLayers().getArray(), function (k,v){
        var this_layer_name = v.get('name');
        if(this_layer_name == layer_name){
            layer_idx = k;
        }
    });

    return layer_idx;
}

// set name1 before name2
moveLayerBefore(findLayer('name1'),findLayer('name2'));

1

Không cần xử lý các chỉ mục trong bộ sưu tập thông qua setAt hoặc insertAt. Cách dễ nhất là sử dụng phương thức setZIndex trên lớp như trong API

geoLayer.setZIndex(999);

Điều khó khăn ở đây là dường như chỉ hoạt động nếu các lớp đã có trên bản đồ. Nói, tôi đặt hai lớp vectơ thẳng lên bản đồ (từng lớp một, không phải tất cả cùng một lúc). Cái đầu tiên tôi đặt thành Z Index 10, cái thứ hai thành Z Index 9. Cái này không hoạt động. Cái thứ hai có
Z Index

1

Trong trường hợp của tôi, câu trả lời của ThomasG77 đã gây ra AssertionError, bởi vì lớp mà tôi sắp chuyển lên đầu đã được đính kèm vào bản đồ ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Giải pháp hiệu quả với tôi:

    let layers = map.getLayers();
    let markerTemp = layers.remove(refToMarkerLayer);
    layers.push(markerTemp);

(loại bỏ chức năng trả về lớp bị loại bỏ). Oneliner cũng hoạt động tốt, nhưng tôi đã không kiểm tra 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.