3

I'm trying to make a simple interactive map of Germany. I'm using mapbox.js (2.4.0) and have it set up like this:

var map;
var currLayer, citiesLayer, riversLayer;

$(document).on("ready", function() {
L.mapbox.accessToken = '';
map = L.mapbox.map('map', 'vantuch.d55cb2a1', {zoomControl: true, scrollWheelZoom: true}).
setView([51.0621,10.9863], 6);

    // CALL AJAX REQUEST FOR TESTING
    findCities();
    findRivers();
    findCityPlaces();
});

I am calling AJAX functions to set up a L.geojson layer after success like this:

/* functions for setting up MARKERS (find_river_places) */
function showMarkers(map, geojson, selectType) {

    geojsonLayer = L.geoJson(geojson, {
        // setting up markers
    });

currLayer = geojsonLayer;
map.addLayer(geojsonLayer);
}

function showCitiesMarkers(map, geojson) {
    geojsonLayer = L.geoJson(geojson, {
    pointToLayer: function(feature, latlng) {
    var marker;

        //return new L.CircleMarker(latlng, {radius: 5, fillOpacity: 1.0}).bindPopup(popup);
        marker = new L.Marker(latlng, {
        icon: new L.DivIcon({
            className: 'circle-border-city',
            html: '<div>' +
          '<span class="circle-marker-city">' + feature.properties.name  +
          '</span>' + '</div>'
        })
    });
    return marker;
    }
});

citiesLayer = geojsonLayer;
map.addLayer(geojsonLayer);

}

What I want to do is to have layers for rivers and cities always on the top of other layers (user should be able to turn them on or off), no matter which function is called the first. But they're always rendered at the bottom.

I thought that citiesLayer.bringToFront() after adding other layers should work. But after testing it in the console it does nothing. So what am I doing wrong, or is there a better way to do this ?

enter image description here

2 Answers 2

4

EDIT following question edits 2 and 3:

Unfortunately L.Marker's behave totally differently from vector layers. Their zIndex property (which control their stack up order) is automatically adjusted by Leaflet so that South-most markers (i.e. bottom-most) appear above North markers. See for example in Dortmund: you have a yellow circle above a red one, which is above another yellow one…

Additionally, there is no bringToFront() or bringToBack() method for markers, since you do not have control on how they stack up.

Now if you display your cities as circle-like markers, why not simply using L.circleMarker instead? That way, they will behave like other vector layers, and you will be able to use bringToFront() with them.

Updated demo: https://jsfiddle.net/ve2huzxw/284/


Original answer

Since you are using mapbox, you have Leaflet version 0.7.7 under the hood.

As such, unfortunately you cannot use the custom map panes introduced with Leaflet 1.0.

However you should have been able to use bringToFront() and bringToBack() on your Feature Groups / GeoJSON groups, which in fact just call the same method on their child vector layers.

Note that markers will always be rendered on top of all vector layers, no matter what you do.

Demo: https://jsfiddle.net/ve2huzxw/283/

Would you be able to reproduce your issue online?

You do not show how you assign your citiesLayer.

3
  • I'm using two base layers, one for rivers and one for cities. Cities are markers styled with css to look like a circles. One layer with linestrings (rivers). And then in another layer I use markers again styled as circles but with different colors. I'd like to have at least main cities visible over minor ones in another layer, because at low zoom level they're shown above them. Commented Jul 30, 2016 at 12:32
  • Ok, this is the correct answer. I just used L.Marker because I thought that I'll be able able to style it better with different fill and line colours, plus text underneath it. Commented Jul 30, 2016 at 13:18
  • This helped me a lot. simply changing from a L.LayerGroup to a L.FeatureGroup allowed me to use the bringToFront and bringToBack methods on those groups e.g. myLayer.bringToBack(); Commented Jan 5, 2017 at 16:50
0

EDIT: Just reread above answer by ghybs and noticed the bit about markers always loading on top of vector layers, rendering my answer below irrelevant for this particular case. Mind you I just learned something new.

I was having a similar issues with the ordering of my stacked Leaf markers (OMS Spiderfy plugin) which I overcame with the help of my own bring to front function based on setZIndexOffset() (credit: ghybs) due to the lack of bringToFront() or bringToBack() method for my L.markers

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

Please see my previous answer on here for more details gis.stackexchange.com/a/349221/157392

CREDIT: ghybs solution @ stackoverflow.com/a/37850189/11106279

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.