Referring to CSV / GeoJSON marker properties individually and custom marker URLs from properties

582 views
Skip to first unread message

Andy Megalithic

unread,
May 26, 2015, 12:28:51 PM5/26/15
to leafl...@googlegroups.com

Hello,
I run a non-profit online resource called the Megalithic Portal. I have used OpenLayers in the past but I would like to convert to Leaflet. I have created a map that uses Leaflet.geoCSV to load in points from a CSV file using github.com/joker-x/Leaflet.geoCSV

To see ultimately what I'm hoping to create, I've made a map with several thousand megalithic sites, based on data from the Megalithic Portal

http://www.megalithic.co.uk/leaflet_megalith_map-old.html

So far so good but I'm struggling with the feature.properties syntax to get any further

I've created a simpler test map here for debugging purposes:

http://www.megalithic.co.uk/leaflet_megalith_map.html

I can load in the CSV points, and loop around the marker properties as in the code below (var clave) which outputs the CSV data in the marker popups.

What I'm struggling with is how do I refer to the properties individually , eg

popup += 'Colour=' + feature.properties.Colour;

(which is wrong as it shows as 'undefined' in the popup)

I think the CSV loads in as an extension of the GeoJSON format http://leafletjs.com/examples/geojson.html

var bankias = L.geoCsv(null, {
    onEachFeature
: function (feature, layer) {
       
var popup = 'SID='+ feature.properties['SID'] +'<br />'; // doesn't work
        popup
+= 'Colour='+ feature.properties.Colour +'<br />'; // doesn't work
       
for (var clave in feature.properties) {
           
var title = bankias.getPropertyTitle(clave);
           
var csvtext = feature.properties[clave];
           
//if (title != 'SID' && title != 'Colour' && title != 'Icon' && title != 'CatID' && title != 'TypeID') {
                popup
+= '<b>'+title+':</b> '+csvtext+'<br />';
           
//}
       
}
        layer
.bindPopup(popup);
   
},
    pointToLayer
: function (feature, latlng) {
       
return L.marker(latlng, {
            icon
:L.icon({
               
//iconUrl: 'images/mapic/' + feature.properties.Icon + '.gif', // WRONG
                iconUrl
: 'leaflet/images/marcador-bankia.png',
                shadowUrl
: 'leaflet/images/marker-shadow.png',
                iconSize
: [25,41],
                shadowSize
:   [41, 41],
                shadowAnchor
: [13, 20]
           
})
       
});
   
},
    firstLineTitles
: true
});

The second thing I'd like to do is to display custom markers set by a column in the CSV.

In the properties I have imported a field into the feature.properties called Icon

Icon: tp6 Icon: tg60 etc

I would like to create a different marker for each point based on this property - do I need to do this as part of the onEachFeature and loop around all the markers to set the iconUrl property?

I've tried the following but it doesn't work so I must have the syntax wrong:

iconUrl: 'images/mapic/' + feature.properties.Icon + '.gif'

eg should generate http://www.megalithic.co.uk/images/mapic/tg60.gif http://www.megalithic.co.uk/images/mapic/tg6.gif etc

Does someone have an example of something similar please -
Many thanks if you can help to improve our map resource.

Andy

http://www.megalithic.co.uk/index.php



Andy Megalithic

unread,
May 28, 2015, 4:22:42 PM5/28/15
to leafl...@googlegroups.com
I have a 'cut down' version of my Leaflet map working here with just 6 points defined locally and loaded in as a GeoJSON layer

http://jsfiddle.net/megalithic/zuz4urb7/

The popup text is defined in line 160

     onEachFeature: function (feature, layer) {
         layer.bindPopup(feature.properties.Name);
     },

but if I replace this with the loop from the CSV version it stops working

     onEachFeature: function (feature, layer) {

         for (var clave in feature.properties) {
            var csvtext = feature.properties[clave];
                popup += ''+csvtext+'<br />';
        }
        layer.bindPopup(popup);

Line 166 to set the icon GIFs 'just works' on the JSfiddle version but it doesn't in my CSV version (line 126 of that)

http://www.megalithic.co.uk/leaflet_megalith_map.html

The CSV loader seems to be loading in the feature.properties in a subtly different way to the GeoJSON.
Can anyone help?
Andy

Iván Sánchez Ortega

unread,
May 29, 2015, 3:52:35 AM5/29/15
to leafl...@googlegroups.com
On Thursday, 28 May 2015 22:22:42 UTC+2, Andy Megalithic wrote:
Line 166 to set the icon GIFs 'just works' on the JSfiddle version but it doesn't in my CSV version (line 126 of that)



 Object properties in Javascript are case-sensitive, so
feature.properties.icon
is different from
features.properties.Icon


 

Andy Megalithic

unread,
May 29, 2015, 3:31:39 PM5/29/15
to leafl...@googlegroups.com

Hello, thanks for the reply. I think the case is correct: Icon, Colour and SID, here's the source of the data

http://www.megalithic.co.uk/cache/csvmap_country59.csv

I checked it by importing into http://geojson.io/ and put the GeoJSON in JSFiddle, where it works

extract:

    {
     
"type": "Feature",
     
"properties": {
       
"SID": 12870,
       
"Name": "Beisenerbierg Menhir",
       
"Type": "Standing Stone (Menhir)",
       
"Colour": "Our Photo Page",
       
"Accuracy": 5,
       
"Condition": 5,
       
"Ambience": 4,
       
"Access": 2,
       
"TypeID": 21,
       
"CatID": 1,
       
"Icon": "tr21"
     
},
     
"geometry": {
       
"type": "Point",
       
"coordinates": [
         
6.07602,
         
49.7592
       
]
     
}
   
},

from http://jsfiddle.net/megalithic/zuz4urb7/

Andy

On Tuesday, 26 May 2015 17:28:51 UTC+1, Andy Megalithic wrote:

Tom Chadwin

unread,
Jun 2, 2015, 8:27:51 AM6/2/15
to leafl...@googlegroups.com
Have you missed out the getPropertyTitle() call?

var title = bankias.getPropertyTitle(clave)

Tom

Andy Megalithic

unread,
Jun 3, 2015, 4:49:11 PM6/3/15
to leafl...@googlegroups.com
Hello - Ivan was right - it was just the case - for geoJson you use mixed case as in my JSFiddle example which worked, but the CSV plugin lowers the case of all the variables - Aaaargh - how to embarrass yourself to hundreds of Leaflet users - but by no means obvious so I thought I should follow up with the working code - CSV users be aware!

Working map
http://www.megalithic.co.uk/leaflet_megalith_map.html

working code


    var bankias = L.geoCsv(null, {
    onEachFeature: function (feature, layer) {
    var popup = '';
    popup += feature.properties.name +'<br>'+feature.properties.type + '<br>' + feature.properties.colour + '<br>';
    if (feature.properties.condition == -1) {popup += 'Condition:Destroyed<br>';}
    if (feature.properties.condition > 0) {popup += 'Condition:'+feature.properties.condition +'<br>';}
    if (feature.properties.ambience > 0) {popup += 'Ambience:'+feature.properties.ambience +'<br>';}
    if (feature.properties.access > 0) {popup += 'Access:'+feature.properties.access +'<br>';}
    if (feature.properties.accuracy > 0) {popup += 'Accuracy:'+feature.properties.accuracy +'<br>';}
        popup += '<a target="_blank" href="article.php?sid='+feature.properties.sid+'">Link to site</a>';

        layer.bindPopup(popup);
    },
    pointToLayer: function (feature, latlng) {
        return L.marker(latlng, {
            icon:L.icon({
                // modify icon
                iconUrl: 'images/mapic/'+feature.properties.icon+'.gif',
                iconSize: [20,20],

                })
            });
        },
        firstLineTitles: true
    });

Reply all
Reply to author
Forward
0 new messages