I have the following code (which works great):
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.js" type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 60%; height: 400px;"></div>
<script>
// Center the map
var map = L.map('map').setView([54.233669, -4.406027], 6);
// Attribution
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map © <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
id: 'mapbox.streets'
}).addTo(map);
// Icon properties
var LeafIcon = L.Icon.extend({
options: {
iconSize: [32, 37],
iconAnchor: [10, 32],
popupAnchor: [5, -30]
}
});
// Prepare some icons
var Icon1 = new LeafIcon({ iconUrl: 'images/pins/1.png' }),
Icon2 = new LeafIcon({ iconUrl: 'images/pins/2.png' }),
Icon3 = new LeafIcon({ iconUrl: 'images/pins/3.png' }),
Icon4 = new LeafIcon({ iconUrl: 'images/pins/4.png' }),
Icon5 = new LeafIcon({ iconUrl: 'images/pins/5.png' });
function forEachFeature(feature, layer) {
var popupContent = "<p> <b>" + feature.properties.Misc +
"</b><br />" + feature.properties.Street +
"<br />" + feature.properties.City +
",<br /> " + feature.properties.State +
", " + feature.properties.Zip + "</p>";
layer.bindPopup(popupContent);
}
$.getJSON("points.json", function (data) {
locations = L.geoJson(data, {
onEachFeature: forEachFeature,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, { icon: Icon4 })
}
});
map.fitBounds(locations.getBounds(), { padding: [25, 25] });
locations.addTo(map);
});
</script>
</body>
</html>
However, I wish each marker on the map to use a custom marker name that's specified in the GeoJSON file.
My points.json
file contains:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-3.216660, 54.456070] },
"properties": {
"Icon": "Icon1",
"Street": "street one",
"City": " city here",
"State": " state here",
"Zip": " ZIP 1",
"Misc": " some misc 1"
}
},
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-0.551140, 51.202747] },
"properties": {
"Icon": "Icon2",
"Street": "street TWO",
"City": " city here",
"State": " state here",
"Zip": " ZIP 2",
"Misc": " some misc 2"
}
}
]
}
Note the Icon
property.
In my HTML code, if I change this:
return L.marker(latlng, { icon: Icon4 })
To:
return L.marker(latlng, { icon: feature.properties.Icon })
I get the following error in the browser console and no marker is displayed:
TypeError: t.icon.createIcon is not a function
What am I doing wrong here and how do I correct this?
Best Answer
What's wrong is that you are defining markers on the basis of feature property
Icon
, which is string, instead of using corresponding icon object.On possible solution is to define all icons as object, where properties are names of icons and values are icon objects. Then it's easy to reference icon by it's name.
Relevant code would then look something like this: