Using marker icons defined in geojson feature point properties

10,985 views
Skip to first unread message

christina

unread,
Jun 5, 2012, 1:26:20 PM6/5/12
to leafl...@googlegroups.com

I noticed alot of people have had this question, however it is really hard to find the solution... 


I have a geojson file describing points, polygons and lines. I want each point to have it's own marker icon, so in the feature properties I describe the icon url I want.

I am working with this example: http://leaflet.cloudmade.com/examples/geojson.html

and have modified lightRailStop to be

var lightRailStop = {
"type": "FeatureCollection",
"features": [
{
    "type": "Feature",
    "properties": {
        "style": {
            externalGraphic: "../../icons/transportation_plane.png",
            graphicWith: 16,
            graphicHeight: 26,
            graphicYOffset: -26,
            fillColor:'#669933',
            fillOpacity:.8,
            strokeColor:'red',
            strokeWidth:6,
            pointRadius:8
        },
        "icon": "../../icons/transportation_plane.png",
        "popupContent": "This is my very special dynamic mrker I couldn't be more happy :D"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [ 24.065321502681, 35.533841657399]
    }
},{
    "type": "Feature",
    "properties": {
        "popupContent": "20th & Welton Light Rail Stop"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.98689115047453, 39.747924136466565]
    }
}
]};

and the leafletembed code to

lightRailGeojsonLayer.on("featureparse", function (e) {
    var popupContent = "<p>I started out as a GeoJSON " + e.geometryType + ", but now I'm a Leaflet vector!</p>";
    popupContent += "<p>This is the default look of a GeoJSON Point.</p>";

     if (e.properties && e.properties.icon && e.geometryType == "Point" ){
         e.layer.setIcon(L.Icon.extend(
         {iconUrl: e.properties.icon}
     ));
    }
    if (e.properties && e.properties.popupContent) {
        popupContent += e.properties.popupContent;
    }
    e.layer.bindPopup(popupContent);
});

I get the error ,
has no method 'createIcon'

What am I doing wrong? :S

I am using Leaflet 0.3.1 stable (February 14, 2012)


Posted the question on github as well, wasn't sure if anyone would see it though.. https://github.com/CloudMade/Leaflet/issues/311 

Brian Herbert

unread,
Jun 14, 2012, 5:56:19 AM6/14/12
to leafl...@googlegroups.com
Hey Christina,

I'm replying here as a "+1". I'm hunting around for the solution but have so far come up dry. I would like to share my geojson across services but maintain marker icons.

Christina Christodoulaki

unread,
Jun 14, 2012, 8:08:45 AM6/14/12
to leafl...@googlegroups.com
Hey Brian,

sorry, no luck. I can't believe there is no way to do this. I cant fugure out how to do it with OpenLayers either, even though I got  a really extensive answer in stackoverflow


hope you have better luck!
--
Christina Christodoulaki
Undergraduate Student
Dept. of Electronics and Computer Engineering
Technical University of Crete
Chania Crete
Greece

Message has been deleted

Brian Herbert

unread,
Jun 18, 2012, 5:46:31 AM6/18/12
to leafl...@googlegroups.com
The only method I can think of using now is grabbing the geojson, parsing it out into multiple geojson strings with the appropriate markers and drawing them as individual layers depending on the marker image.

b_b

unread,
Jun 23, 2012, 10:12:30 AM6/23/12
to leafl...@googlegroups.com
Hi,

You can do that this way :

jQuery.getJSON("url_of_your_geojson_file",
    function(data) {
        if (data){
            var geojson = new L.GeoJSON();
            geojson.on("featureparse", function(e){
                if (e.properties && e.properties.icon){
                    e.layer.setIcon(new L.Icon({
                        iconUrl: e.properties.icon,
                        iconSize: new L.Point( e.properties.icon_size[0], e.properties.icon_size[1] ),
                        iconAnchor: new L.Point( e.properties.icon_anchor[0], e.properties.icon_anchor[1] ),
                    }));
                }
                if (e.properties && e.properties.title){
                    e.layer.bindPopup(e.properties.title);
                }
            });
            map1.addLayer(geojson);
            geojson.addGeoJSON(data);
           
        }
    }
);

Demo page here :

http://labo.eliaz.fr/spip.php?page=carte

++
b_b

Christina Christodoulaki

unread,
Jun 23, 2012, 11:13:04 AM6/23/12
to leafl...@googlegroups.com
thanks a million!!! :D

monkut

unread,
Aug 15, 2012, 12:29:42 AM8/15/12
to leafl...@googlegroups.com



If you make this a layer you can pass the optional pointToLayer callback that renders the object to the layer:


function callback(feature, latlng){    
var myIcon = L.icon({ iconUrl: 'my-icon.png', // pull out values as desired from the feature feature.properties.style.externalGraphic. iconSize: [38, 95], iconAnchor: [22, 94], popupAnchor: [-3, -76], shadowUrl: 'my-icon-shadow.png', shadowSize: [68, 95], shadowAnchor: [22, 94] }); marker = L.marker([50.505, 30.57], {icon: myIcon});
    return marker; 
}  




var geojsonLayer = new L.GeoJSON(null, {pointToLayer: callback});

ast...@gmail.com

unread,
Jan 14, 2013, 3:30:24 PM1/14/13
to leafl...@googlegroups.com
Perfect, this did exactly what I needed as well.  Thanks so much!

Dariusz Ciesielski

unread,
Mar 5, 2013, 4:35:16 PM3/5/13
to leafl...@googlegroups.com
I did something like this

<code>
  LMap.geoJson(that.makeFeatureCollection(locals), {
                                onEachFeature: that.onEachFeature,
                                pointToLayer: function (feature, latlng) {
                                    var ii =  L.icon({ 
                                            iconUrl: 'resources/style/images/bar.png', // pull out values as desired from the feature feature.properties.style.externalGraphic.
                                            iconSize: [32, 37],
                                            iconAnchor: [22, 38],
                                            popupAnchor: [-3, -76],
                                            //shadowUrl: 'my-icon-shadow.png',
                                            //shadowSize: [68, 95],
                                           // shadowAnchor: [22, 94]
                                        });  
                                   return LMap.marker(latlng, {icon: ii});                                 

                                }
                            }).addTo(map);
</code>

Riccardo Klinger

unread,
Sep 18, 2013, 4:38:31 PM9/18/13
to leafl...@googlegroups.com, cchrist...@gmail.com
Hi folks,

my code fr this problem is like this:
var poi = new L.geoJson(poi, {
        //some options
        onEachFeature: onEachFeature,
        pointToLayer: function(feature, latlng) {
            var iconURL = feature.properties.img;
            return new L.Marker(new L.LatLng(feature.geometry.coordinates[1],feature.geometry.coordinates[0]),{
                    icon: L.icon({
                    //iconSize: [47,47],
                        iconAnchor: [0, 0],
                        popupAnchor: [0, 0],
                        iconUrl: iconURL
                    })
            });
        }
    }).addTo(map);


all the best,

Riccardo

Claudio Marin

unread,
Apr 7, 2014, 1:07:16 PM4/7/14
to leafl...@googlegroups.com, cchrist...@gmail.com
        function Pin(pin){
            var Pin = L.icon({
              iconUrl: "img/"+ pin,
              iconSize: [38, 53],
              popupAnchor: [1, -16],
              shadowUrl: "img/pin_fondo.png",
              shadowSize: [39, 53],
              className: "custom-icon-marker"
            });            
        return Pin;
        }



L.marker(latlng, {icon: Pin(feature.properties.pin)});

in json inside "properties":
"pin":"pin_sd.png"

Reply all
Reply to author
Forward
0 new messages