วิธีการเปลี่ยนลำดับเลเยอร์ใน leaflet.js


10

ฉันต้องการที่จะเปลี่ยนลำดับของเลเยอร์ในแผ่นพับ

ฉันลองใช้ปลั๊กอินสองแผ่นเพื่อเปลี่ยนลำดับเลเยอร์

ครั้งแรกที่ฉันพยายามใบปลิว-ควบคุม orderlayersซึ่งดูเหมือนว่าจะทำงาน แต่ไม่สนับสนุน layerGroups ที่นี่เป็นของฉันข้อผิดพลาดที่ยื่น

ต่อไปฉันลองmapbbcodeซึ่งรองรับ layerGroups แต่ดูเหมือนจะไม่ทำงานหรือได้รับการบำรุงรักษา

ใครบ้างมีคำแนะนำสำหรับวิธีการใช้คุณสมบัตินี้?


ซ้ำเป็นไปได้: stackoverflow.com/questions/12848812/...
nothingisnecessary

คำตอบ:


9

คุณสามารถทำได้สองวิธี (อย่างน้อยนี่คือวิธีที่ฉันทำ):

  1. layer.bringToFront()และlayer.bringToBack()แต่สิ่งเหล่านี้จะทำเพียงครั้งละหนึ่งเลเยอร์เท่านั้นและจะผลักไปข้างหน้าหรือข้างหลังไม่ใช่ในระหว่าง ดังนั้นคุณจะต้องใส่เลเยอร์ของคุณในลำดับที่ต้องการเริ่มต้นด้วยเลเยอร์ที่คุณต้องการที่จะอยู่ด้านล่างและเรียกร้องlayer.bringToFront()ในแต่ละชั้น

  2. คุณสามารถทำได้โดยการลบและเพิ่มเลเยอร์อีกครั้ง ดูเหมือนว่าจะเป็นเรื่องที่สิ้นเปลือง แต่เนื่องจากแผนที่จะต้องวาดใหม่เมื่อเปลี่ยนตำแหน่งเลเยอร์ต่อไปดังนั้นโดยทั่วไปจึงไม่ใช่เรื่องใหญ่

นี่คือซอที่ซับซ้อนพอสมควรที่แสดงให้เห็นถึงปัญหา

โดยทั่วไปคุณจะลบเลเยอร์ทั้งหมดแล้วเพิ่มอีกครั้งz-indexตามลำดับจากน้อยไปหามาก ดังนั้นห่วงผ่านชั้นซ้อนทับของคุณทั้งหมดและโทรmap.removeLayer(layer)แล้วจัดเรียงพวกเขาโดยที่คุณต้องการแล้วเพิ่มอีกครั้งโดยใช้z-indexlayer.addTo(map)


1

ฉันมีปัญหาเดียวกันและฉันลองใช้วิธี fixZOrder () แต่น่าเศร้าที่มันไม่ได้สั่งให้เครื่องมาร์คเกอร์สำหรับฉันเพราะมันดูเหมือนจะไม่ส่งผลกระทบต่อ zindex ของเครื่องหมายแผ่นพับ

ดูเหมือน. bringToFront () ใช้งานได้เฉพาะกับรูปร่างเวกเตอร์ที่รองรับวิธีนี้ในทางตรงข้ามกับเครื่องหมายใบไม้ที่ฉันปรับใช้การแสดงผลโซลูชันนี้ใช้งานไม่ได้ไม่พูดถึงปัญหารหัสอื่น ๆ ที่ฉันพบกับ fixZOrder () กรณีของฉัน.

​​

แต่ฉันออกจากเลเยอร์ที่สั่งไปยัง Leaflet (ตัวเลือก) ตามลำดับที่ฉันโหลดซึ่งทำให้เกิดปัญหากับการซ้อนเครื่องหมาย (OMS Spiderf ปลั๊กอิน) เมื่อใช้การควบคุมเลเยอร์แต่ฉันจัดการเพื่อแก้ไขสิ่งเหล่านี้ด้วยความช่วยเหลือของ funtion ของฉันเองsetZIndexOffset ()

function myBring2Front() {
        //layer1.bringToFront();
        layer1.eachLayer(function (layer) {
          layer.setZIndexOffset(2000);
        });
        layer2.eachLayer(function (layer) {
          layer.setZIndexOffset(1000);
        });
    }

แม้ว่าสถานการณ์ของฉันไม่จำเป็นต้องใช้fixZOrder(layers)ในท้ายที่สุดใครก็ตามที่ใช้วิธีนี้ร่วมกับเครื่องหมายที่ซ้อนกันอาจต้องใช้วิธีการที่คล้ายกันดังนั้นฉันจึงโพสต์สิ่งนี้เป็นโซลูชันเพิ่มเติมสำหรับผู้ใช้ที่มีศักยภาพของวิธีการสั่งซื้อเลเยอร์ดังกล่าว

​​

เครดิต : คำตอบ ghybs ในstackoverflow.com/a/37850189/11106279


0

คล้ายกับคำตอบจาก @nothing จำเป็นต่อการใช้layer.bringToFront()z เพื่อรักษาลำดับเมื่อคุณรวมlayer controlและโหลดข้อมูลแบบอะซิงโครนัส

เราไม่ต้องการล้างเลเยอร์และเพิ่มกลับเข้าไปในแผนที่เนื่องจากจะเป็นการเพิ่มเลเยอร์ทั้งหมด แต่เราต้องการเคารพเลเยอร์ที่เลือกในการควบคุมเลเยอร์ด้วยค่าใช้จ่ายที่น้อยที่สุด bringToFront()สามารถทำได้ แต่เราต้องเรียกมันในกลุ่มเลเยอร์ที่มีเลเยอร์ (เนื้อหา) อยู่ภายใน

กำหนดเลเยอร์:

var dataLayers = {
    Districts: new L.geoJSON(),
    Farms: new L.featureGroup(),
    Paddocks: new L.geoJSON(),
    Surveys: new L.geoJSON()
};

L.control.layers(
    // base maps
    {
        OSM: L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: ['a', 'b', 'c'] });,
    },
    dataLayers,
    {
        collapsed: false,
        hideSingleBase: true
    }).addTo(map);

ใช้ฟังก์ชั่นต่อไปนี้เพื่อบังคับใช้คำสั่ง z:

/**
 * Ensure that layers are displayed in the correct Z-Order
 * Instead of explicitly defining z-order on the groups the order of the calls to beingToFront controls the resulting zOrder
 * @param {any} dataLayers Object that holds the references to the layer groups toggled by the layer control
 **/
function fixZOrder(dataLayers) {

    // only similar approach is to remove and re-add back to the map
    // use the order in the dataLayers object to define the z-order
    Object.keys(dataLayers).forEach(function (key) {

        // check if the layer has been added to the map, if it hasn't then do nothing
        // we only need to sort the layers that have visible data
        // Note: this is similar but faster than trying to use map.hasLayer()
        var layerGroup = dataLayers[key];
        if (layerGroup._layers
            && Object.keys(layerGroup._layers).length > 0
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path.parentNode)
            layerGroup.bringToFront();
    });
}

เมื่อใช้การควบคุมเลเยอร์เมื่อเลเยอร์ถูกสลับเป็นมุมมองมันจะอยู่ด้านบนของเลเยอร์อื่น ๆ เราจำเป็นต้องใช้ตรรกะการสั่งซื้ออีกครั้งเมื่อเพิ่มเลเยอร์ สิ่งนี้สามารถทำได้โดยผูกกับoverlayaddเหตุการณ์บนแผนที่และเรียกใช้fixZOrderฟังก์ชัน:

map.on('overlayadd', function (e) {
    fixZOrder(dataLayers);
}

หากคุณโหลดข้อมูลแบบอะซิงโครนัสคุณอาจต้องโทรหาfixZOrderเมื่อการโหลดข้อมูลของคุณเสร็จสิ้นเลเยอร์ใหม่ที่เพิ่มเข้ามาในขณะรันไทม์จะถูกแสดงผลที่ด้านบนของเลเยอร์อื่น ๆ ทั้งหมด


0

คุณต้องสร้างแผงควบคุมเพื่อควบคุมคำสั่งซื้อ

map.createPane('myPane1');
map.createPane('myPane2');
map.getPane('myPane1').style.zIndex = 400;
map.getPane('myPane2').style.zIndex = 800;

ด้วยวิธีนี้คุณสามารถเพิ่มเลเยอร์ลงในบานหน้าต่างที่คุณต้องการ

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