5

I would like to customize a marker to add an id (number) on top of it, this id is coming from an attribute of the geojson ("id" in the following example)

{
"type":"FeatureCollection",
"features":[
    {
      "type":"Feature",
      "geometry":{
        "type":"Point",
        "id":1,
        "destination":"Police station",
        "coordinates":[
          "4.3520735404177699","50.846502697562201"
        ]
      },
    {
      "type":"Feature",
      "geometry":{
        "type":"Point",
        "id":2,
        "destination":"Museum",
        "coordinates":[
          "4.347903728485107","50.846658450225334"
        ]
      },
...

I'm stuck with L.ExtraMarkers :

var json = L.ExtraMarkers.icon({
            icon: 'fa-number',
            number: 'x',
            iconColor: 'white',
            markerColor: 'black',
            shape: 'circle',
            prefix: 'fa'
            });

    var geojsonLayer = new L.GeoJSON.AJAX("query_json.php?&do=DCT1",{pointToLayer: function (feature, latlng) {
                return L.marker(latlng, {icon: json});    
    },

    onEachFeature: function (feature,layer) {
        var popup = [];
        for (var prop in feature.properties) {
            popup.push(prop + ": " + feature.properties[prop]);
        }
        layer.bindPopup(popup.join("<br />"));
    }}).addTo(map);

number: 'x', should be the variable "id" coming from the geojson.

I'm also stuck with L.circleMarker :

var stylegeojson = {color:'white', fillColor:'blue', radius:10, opacity:1.0, fillOpacity:1.0, weight:2};

var geojsonLayer = new L.GeoJSON.AJAX("query_json.php?&do=DCT1", {pointToLayer: function (feature, latlng) {
                return L.circleMarker(latlng, stylegeojson);
                // what should I add here to print "id" value on top of it ?
    },
    }).addTo(map);

I think I have to add an

onEachFeature: function(feature, id) {

but I don't know to write it.

Ideally I'd also like to have a different marker color per "destination"

I am wondering if someone already did this before or has an idea how to do this?

1 Answer 1

8

First, your GeoJSON is invalid. Each feature should have a geometry and a properties property. i.e. the following is wrong:

var feature = {
  "type":"Feature",
  "geometry":{
    "type":"Point",
    "coordinates":[ "4.347903728485107","50.846658450225334" ],
    "id":2,
    "destination":"Museum"
  }
}

And the following is right:

var feature = {
  "type":"Feature",
  "geometry":{
    "type":"Point",
    "coordinates":[ "4.347903728485107","50.846658450225334" ]
  }, 
  "properties": {
    "id":2,
    "destination":"Museum"
  }
}

Use GeoJSONLint to check validity of your GeoJSON.

Second: the pointToLayer function should refer to the value of the id property of the feature if you want to use it.

This is wrong:

var icon= L.icon.glyph({
  prefix: '',
  glyph: feature.properties.id,
  // Any other icon options here
});

var geoJsonLayer = L.geoJSON(featureCollection, {
  pointToLayer: function(feature, latlng) {
    return L.marker(latlng, {icon: icon})
  }
});

And this is right (note the variable scope for feature and thus feature.properties.id:

var geoJsonLayer = L.geoJSON(featureCollection, {
  pointToLayer: function(feature, latlng) {
    return L.marker(latlng, {
      icon: L.icon.glyph({
        prefix: '',
        glyph: feature.properties.id
      })
    })
  }
})

See a working example using Leaflet.Icon.Glyph.

I think I have to add an onEachFeature: function(feature, id) {

No, you don't. If you want to create a different marker for each GeoJSON point feature, do so in the pointToLayer callback option. Use onEachFeature for stuff you want to get done after the leaflet layers (markers/lines/polygons) have been instantiated.

2
  • Thank you for this pedagogic answer, it worked directly. Solved for me !
    – mmeinert
    Commented Oct 24, 2016 at 14:15
  • The 'id' property should be a top-level property on Feature, rather than a member of 'properties'.
    – Zephyr
    Commented Oct 16, 2017 at 14:30

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.