Friday 22 May 2015

geojson - Using custom icons for Leaflet Layer groups?


I have searched posts and tutorials and could not find the answer to my specific application of this feature


Almost all the examples use L.marker to simply place a marker on the map using various custom icons. This would be fine except I am not just placing markers but rather adding all the geoJson data to layers, then adding those layergroups to the control and then to the map. - I.E. I want all the layer routeca1 to use a red icon. I think I have narrowed this to needing to use the point to layer function:


pointToLayer: function (feature, latlng) {

return L.marker(latlng, {icon: redIcon});
}

I am not using the onEachFeature function, as I have seen an example on how to do this using that function but cant make that work for what I am doing here.


The map works great without trying to do a different color icon. I have all my points and polygons appearing and controlable by the layercontrol, but when I try to add the point to layer I just get a white map or the same map with no changes depending on where I try to add it in.


I added the icon sections below based off of the Leaflet Tutorial -


 var routeca1 = L.layerGroup();

var geojsonFeature1 = [{***random geojson data points here****} ];


L.geoJSON(geojsonFeature1)
.bindPopup(function (layer) {
return ''+'Location ID: '+ layer.feature.properties.locationid +'' + '
' + '
'+ layer.feature.properties.Description + '
' + layer.feature.properties.model + '
' + '
'+ layer.feature.properties.addresscomponents;
}).addTo(routeca1);

var streets = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '© OpenStreetMap', maxZoom: 17, minZoom: 6});

var map = L.map('map', {
center: [34.068, -118.248],
zoom: 10,

layers: [streets, routeca1]
});

var baseLayers = {
"Streets": streets
};

var overlays = {
"CA1": routeca1
};


var MarkerIcon = L.Icon.extend({
options: {
shadowUrl: './leaflet/images/marker-shadow.png',
iconSize: [38, 95],
shadowSize: [50, 64],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}

});

var greenIcon = new MarkerIcon({iconUrl: './leaflet/images/marker-icon-green.png'}),
redIcon = new MarkerIcon({iconUrl: './leaflet/images/marker-icon-red.png'}),
blueIcon = new MarkerIcon({iconUrl: './leaflet/images/marker-blue.png'});

L.icon = function (options) {
return new L.Icon(options);
};


L.control.layers(baseLayers, overlays).addTo(map);

Answer



I edited your code just using the red leaf from this example. The key changes I made to your code are:



  1. declaring the icon variable(s) before you turn your geoJSON data into a leaflet layer. That way, you can refer to the icon variable during the layer's construction.

  2. adding the "point to layer" code to the L.geoJSON layer's construction

  3. giving the leaflet layer a variable name (myLayer) so that I can set the icon and bind the popup separately.




//I start by setting up my icon here

var MarkerIcon = L.Icon.extend({
options: {
shadowUrl: 'leaf-shadow.png',
iconSize: [38, 95],
shadowSize: [50, 64],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}
});


//be sure the png files exist in your file directory and are pathed correctly
var greenIcon = new MarkerIcon({iconUrl: 'leaf-green.png'}),
redIcon = new MarkerIcon({iconUrl: 'leaf-red.png'}),
orangeIcon = new MarkerIcon({iconUrl: 'leaf-orange.png'});

L.icon = function (options) {
return new L.Icon(options);
};


// I create an empty layer group
var routeca1 = L.layerGroup();

//var geojsonFeature1 = [{***random geojson data points here****} ];
//I made up some points which work in your set-up. Though most of the attributes for the pop-up are missing
var geojsonFeature1 = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",

"properties": {
"Description": "A"
},
"geometry": {
"type": "Point",
"coordinates": [
-118.24207305908203,
34.084369762367984
]
}

},
{
"type": "Feature",
"properties": {
"Description": "B"
},
"geometry": {
"type": "Point",
"coordinates": [
-118.23057174682616,

34.07356398381666
]
}
}
]
};

// L.geoJSON(geojsonFeature1); //removed this line
//and added the following instead, which sets the icon based on the variable created above and adds each marker to the layer group. Note "redIcon" must be created above this, or it is not going to work:
myLayer = L.geoJSON(geojsonFeature1, {

pointToLayer: function (feature, latlng){
return L.marker(latlng, {icon: redIcon});
}
}).addTo(routeca1);

//I then bind the popup to the layer here:
myLayer.bindPopup(function (layer) {
return ''+'Location ID: '+ layer.feature.properties.locationid +'' + '
' + '
'+ layer.feature.properties.Description + '
' + layer.feature.properties.model + '
' + '
'+ layer.feature.properties.addresscomponents;
});


// now I create my map and other layers
var streets = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '© OpenStreetMap', maxZoom: 17, minZoom: 6});

var map = L.map('map', {
center: [34.068, -118.248],
zoom: 10,
layers: [streets]
});

var baseLayers = {

"Streets": streets
};

var overlays = {
"CA1": routeca1,

};

//lastly add the layers to the map!
L.control.layers(baseLayers, overlays).addTo(map);


I hope this helps!


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...