1

I'm trying to add a layer of place labels above a GeoJSON layer, so that these labels remain visible. However when I add the layer per the code below, the tileLayer remains below the GeoJSON layer.

    var CartoDB_PositronOnlyLabels = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
        subdomains: 'abcd',
        maxZoom: 19,
        zIndex: 3
    });
    CartoDB_PositronOnlyLabels.addTo(map);

Adding a few more things that don't work for the future reader:

  1. According to this leaflet PR you could add a pane: 'overlayPane' option upon layer creation.
  2. The hack appearing here and here only works if the tileLayer you're adding is of tileJSON format

    var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane);  
    var topLayer = L.mapbox.tileLayer('lxbarth.map-vtt23b1i').addTo(map);  
    topPane.appendChild(topLayer.getContainer());  
    topLayer.setZIndex(9);  
    
raphael
  • 3,407
  • 23
  • 61
  • 1
    http://gis.stackexchange.com/questions/20331/how-to-change-leaflet-map-panes-layering-order-z-index See this question. You have to alter the z-index. – Stella Jan 28 '16 at 21:14
  • Nice try, but z-index only alters draw order within a pane, it won't make the tilelayer pane render above the overlay pane – raphael Jan 28 '16 at 21:41

2 Answers2

3

Panes might help your cause. The idea being you can control what layers draw in what panes and then control the pane order. Here is the original GIT discusson on it.

There is also a similar SO question regarding overlay layers and tile layers and how they are implemented on custom panes.

Barrett
  • 3,069
  • 1
  • 17
  • 31
2

Barrett's answer set me down the right path, but I ended up in such a number of rabbit holes that I decided that posting my resulting code and explanation of some of my discoveries in the hopes this might help the community.

The resulting code that worked is as below.

var CartoDB_PositronOnlyLabels = {
    "tilejson": "2.0.1",
    "tiles":['http://c.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png'], 
    "attribution": '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; 
         <a href="http://cartodb.com/attributions">CartoDB</a>',
    "maxzoom": 19,
    "minzoom": 13       
};

var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane);
var topLayer = L.mapbox.tileLayer(CartoDB_PositronOnlyLabels).addTo(map);
topPane.appendChild(topLayer.getContainer());
topLayer.setZIndex(9);

The second half of that code is based on this answer. I had to modify it because the L.mapbox.tileLayer doesn't work the same way as L.tileLayer, it requires a tileJSON as input (spec), which is what that first section of code defines.

You'll notice a difference from the parameters provided in tileLayer code examples like the handy Leaflet Providers: the absence of the subdomain {s} in the url. This is because, well, this. Fortunately, cartoDB explicitly lists those subdomains (abcd) so I picked c and added that to the start of the tile URLs and it worked!

raphael
  • 3,407
  • 23
  • 61