ดัชนี Z ใน OpenLayers 3: การสั่งซื้อเลเยอร์ใน OL3


13

มีวิธีในการเปลี่ยนดัชนี Z ของเลเยอร์ใน OpenLayers3 เหมือนในเวอร์ชันเก่าหรือไม่?

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

ฉันต้องเปลี่ยนลำดับของเลเยอร์ตลอดการใช้แผนที่ ดังนั้นความเป็นไปได้เช่นการกำหนดดัชนีซีแบบนี้ไม่ได้ช่วยอะไร

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
            })];
        }

    }
});

ฉันมีปัญหาในการใช้โซลูชันนี้น่าจะเป็นเพราะฉันไม่เข้าใจสิ่งต่าง ๆ คุณช่วยโพสต์ตัวอย่างของผลลัพธ์ได้ไหมฉันเชื่อว่ามันจะช่วยฉันได้จริงๆ
dave_does_not_understand

คำตอบ:


10

ลองสิ่งที่ชอบ:

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

ol.Collectionรายการของชั้นที่อยู่ในวัตถุที่สืบทอดจากนักการ ดูเอกสาร APIสำหรับมัน

โปรดระวังฉันค่อนข้างแน่ใจว่าคุณไม่สามารถใช้เลขที่กำหนดเองเช่น 99 ในsetAt: arg แรกคือตำแหน่งในอาร์เรย์ของเลเยอร์และ arg ที่สองสำหรับการอ้างอิงองค์ประกอบเลเยอร์ที่คุณต้องการย้าย ในการรับจำนวนเลเยอร์เพียงใช้map.getLayers().getArray().length

แม้ว่าคุณจะเห็นว่าเราสามารถรับอาเรย์ JS สำหรับเลเยอร์ได้ แต่ฉันไม่แน่ใจว่าการจัดการอาเรย์นี้โดยตรงเป็นวิธีที่ดีที่สุดเนื่องจากเลเยอร์สามารถแนบกิจกรรมได้ คุณสามารถใช้ol.Collectionวิธีการแทน


ผมกำลังมองหาวิธีแก้ปัญหาสำหรับการวางซ้อนดังนั้นฉันแค่อยากจะเพิ่มความคิดเห็นบอกว่านี้ (แน่นอน) ยังสามารถใช้ได้กับการวางซ้อนเป็นmap.getOverlays()ส่งกลับol.Collectionเช่นเดียวmap.getLayers()ไม่
decibyte

8

มันไม่ง่ายอย่างที่เคยเป็น แต่มีวิธีการช่วยเหลือบางอย่างสำหรับคอลเลกชัน สิ่งนี้จะช่วยให้คุณทำสิ่งที่คล้ายกันตามที่ ThomasG77 อธิบายไว้ข้างต้น

สมมติว่าคุณมีแผนที่ชื่อแผนที่ซึ่งมี 4 เลเยอร์เช่น [base_layer, แนวชายฝั่ง, แผนที่ความร้อน, เครื่องหมาย]

จากนั้นคุณสามารถรับคอลเล็กชันผ่าน map.getLayers () และอาร์เรย์ของเลเยอร์ผ่าน map.getLayers (). getArray () และเลเยอร์แต่ละรายการผ่าน

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

คุณสามารถจัดการลำดับเลเยอร์ผ่านวิธีการรวบรวม มันอาจจะช่วยในการสร้างฟังก์ชั่นตัวช่วยบางอย่างเช่น:

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

หวังว่าคุณมีความสามารถในการระบุเลเยอร์ของคุณและค้นหาพวกเขาฉันตั้ง id ในการสร้างเช่น layer.set ("layer_id" 44) ซึ่งสามารถเรียกดูผ่าน layer.get ("layer_id") จากนั้นคุณสามารถมีตัวช่วย findLayer วนรอบชั้นของคุณและส่งกลับดัชนีชั้น

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

ด้วยวิธีนี้ฉันสามารถมีบางสิ่งบางอย่างเช่น moveLayerBefore (แผนที่, findLayer (44), findLayer (22));

อย่างไรก็ตามมีวิธีมากมายในการรวบรวม แต่หวังว่าจะช่วยให้คุณเริ่มต้นได้ และขออภัยหากมีข้อผิดพลาดในรหัสนั่นคือทั้งหมดที่ใจรวบรวม ... :)


5

ตามคำตอบ srussking ฉันเขียนรหัสต่อไปนี้สมมติว่าวัตถุแผนที่หลักที่เรียกว่าแผนที่และเป็น var ทั่วโลกฉันต้องการใช้เลเยอร์ค้นหาตามชื่อไม่ใช่ id

นี่คือรหัสของฉัน:

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

ไม่จำเป็นต้องจัดการดัชนีในการรวบรวมผ่าน setAt หรือ insertAt วิธีที่ง่ายที่สุดคือใช้เมธอด setZIndex บนเลเยอร์เหมือนกับในAPI

geoLayer.setZIndex(999);

สิ่งที่ยุ่งยากที่นี่ดูเหมือนจะใช้ได้เฉพาะเมื่อเลเยอร์อยู่บนแผนที่แล้ว บอกเด็ก ๆ ว่าฉันวางเวกเตอร์สองชั้นลงบนแผนที่ (ทีละคนไม่ใช่ทั้งหมดในคราวเดียว) อันแรกฉันตั้งค่าเป็น ZIndex 10 อันที่สองเป็น ZIndex 9. สิ่งนี้ไม่ทำงาน รายการที่สองที่มี ZIndex 9 จะปรากฏเหนือ ZIndex 10
kiradotee

1

ในกรณีที่คำตอบของ ThomasG77 เกิดขึ้นAssertionErrorเพราะเลเยอร์ที่ฉันกำลังจะย้ายไปด้านบนได้แนบกับแผนที่แล้ว ( https://openlayers.org/en/v4.4.2/doc/errors/#58 )

โซลูชันที่เหมาะกับฉัน:

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

(ฟังก์ชั่นลบส่งกลับชั้นที่ถูกลบ) Oneliner ควรทำงานได้เช่นกัน แต่ฉันไม่ได้ทดสอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.