2

I am attempting to create my first leaflet map. I am using OpenStreetMap tiles and adding geojson features as overlay layers. I have been following tutorials with much success, until I started trying to add labels. I would simply like to add static labels to several features, and be able to toggle them on/off with the layer control. I have been using leaflet.label. Is this possible?

I have tried the following to give me labels with mixed results:

function onEachFeature(feature, layer) {
    if (feature.properties && feature.properties.name) {
          <!-- shows label only on mouseover -->
          //layer.bindLabel(feature.properties.name, { 'noHide': true});

          <!-- creates static labels, but remain when layers are turned off -->
          //var label = new L.Label();
          //label.setContent(feature.properties.name);
          //label.setLatLng(layer.getBounds().getCenter());
          //map.showLabel(label);
       }
   }

Here is my layer control:

var overlayMaps = {
    "Layer 1": L.geoJson(layer1geojson, {onEachFeature: onEachFeature}).addTo(map),
    "Layer 2": L.geoJson(layer2geojson, {onEachFeature: onEachFeature}).addTo(map),
    "Buildings": L.geoJson(buildingsGeojson, {onEachFeature: onEachFeature}).addTo(map)
  };
var legend = L.control.layers(baseMaps, overlayMaps, {collapsed:false});
legend.addTo(map);

UPDATE

I used the following technique proposed by ghybs to add labels to geojson features and have the ability to turn them off with the layer control.

var buildingGroup = L.layerGroup().addTo(map);
L.geoJson(buildings, {
    style: buildingStyle,
    onEachFeature: function(feature, layer) {
        var label = new L.Label();
        label.setContent(feature.properties.name);
        label.setLatLng(layer.getBounds().getCenter());
        buildingGroup.addLayer(layer);
        buildingGroup.addLayer(label);
    }
});
// Repeat for any additional layers with labels

// Add Group to overlays
var overlays = {
    "Layer1": layer1Group,
    "Layer2": layer2Group,
    "Buildings": buildingGroup
};

// Add layer control to map
L.control.layers(baseMaps, overlays, {collapsed:false}).addTo(map);
  • not sure on the toggle on/off but on label onhover is available jsfiddle.net/ve2huzxw/64 – Mapperz Dec 3 '15 at 16:40
  • @Mapperz Thanks, I tried that first (see my OnEachFeature function), but I would like static labels (i.e. always visible, and fixed). Here is what my labels look like now, but I'd like to hide them when their associated layer is turned off. – Barbarossa Dec 3 '15 at 17:06
1

You would simply need to create a "parent" Layer Group that contains your GeoJSON feature layer(s) and their associated label(s).

Labels can be added to a group instead of directly to the map, so that they are removed / added to the map together with their Group.

polygon.bindLabel('MultiPolygon dynamic label');

var label = new L.Label();
label.setContent("MultiPolygon static label");
label.setLatLng(polygon.getBounds().getCenter());
//map.showLabel(label);

// Create a Layer Group that will contain your GeoJSON feature layers
// and the static labels.
var polygonGroup = L.layerGroup().addTo(map);

polygonGroup.addLayer(polygon);
polygonGroup.addLayer(label);

L.control.layers(null, {
  "polygon": polygonGroup
}).addTo(map);

Of course you could do all that directly in your onEachFeature function.

Demo: http://jsfiddle.net/CrqkR/156/

  • I think this is the functionality I have been looking for. Could you possibly elaborate on how I would incorporate it into my onEachFeature function? – Barbarossa Dec 4 '15 at 16:52
  • I got it! I'll post an update. – Barbarossa Dec 4 '15 at 19:37
0

Just to share an alternative method to "toggle" static labels with the leaflet control. By listening for map control events, labels can be turned on/off with the controls. For example:

//Create 2 group layers - 1 for geometry, 1 for labels
var groupLayer = L.layerGroup().addTo(map);
var groupLabel = L.layerGroup();
L.geoJson(layer1GeoJson, {
    onEachFeature: function(feature, layer) {  
        if (feature.properties && feature.properties.name) { 
            var label = new L.Label();
            label.setContent(feature.properties.name);                
            label.setLatLng(layer.getBounds().getCenter());

            groupLayer.addLayer(layer);
            groupLabel.addLayer(label);
        }
    } 
});

// Overlays
var overlays = {
    "Layer 1": groupLayer,
    // Add other layers here
};

// Add layer control to map
L.control.layers(null, overlays).addTo(map);

// Event listener for layers added to map
map.on('overlayadd', function (layer) {
    if (layer.name == 'Layer 1') {
        map.addLayer(groupLabel);
    }
});

// Event listener for layers removed from map
map.on('overlayremove', function (layer) {
    if (layer.name == 'Layer 1') {
        map.removeLayer(groupLabel);
    }
});

For my application, I used this approach because it allows me to turn layers and/or labels on/off depending on zoom level.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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