In a lot of cases, not every marker is the same. Sometimes we have a restaurant, but other times we might have a museum, so we should be able to visually represent that type of location to make our map easier to use.
We'll learn how to create custom markers by using a new configuration option with our Leaflet GeoJSON instance.
Instructor: [0:00] Hey, mappers. Welcome to lesson nine. One of the great things about Leaflet is there's a ton of options to customize our map. One of those options are configuring custom images for our markers. This can be super helpful if you want to provide context clues for what each location represents.
[0:13] For exercise one, we're going to recreate adding all of our markers with a custom GeoJSON configuration. In order to add our customization, we need to use a custom property. That custom property requires us to manually set up our markers for those locations.
[0:26] At this point, nothing should change visually on the map. Once we've done that, we'll be ready to add our custom images. Now that we have our custom property, we're going to set up our custom marker images in exercise two.
[0:36] The default marker image is pretty simple. It's a blue marker and that's about it. A lot of cases that's OK because that's all you need. What if you're trying to show something like a restaurant versus a hotel or a gas station?
[0:46] Here, we'll update our marker to use a custom image that we already have available for us in the code repo. Once we add our custom image, we'll notice an issue with our custom markers. They're all missing shadows.
[0:56] In exercise three, we'll learn how to add back our shadows by setting up the marker configuration. We'll be able to import the exact same images that the original markers use right from Leaflet. While we can also customize those as we want, we'll use the default Leaflet shadows as they work for our use case.
[1:11] For some extra credit, how about some advanced markers? Using custom images is relatively simple way to add a new look to our marker, but images are very dynamic. They require being loaded and depending on how big you make them, can get fuzzy if enlarged.
[1:23] For some extra credit, try to use Leaflet's documentation to add a custom marker using HTML and CSS. Leaflet provides a div icon that allows us to inject custom HTML, which at that point, we can style it however we'd like.
[1:36] Adding custom marker images is mostly about adding context. While it can definitely be fun to add a custom image, normally, we'll want to provide those images to help people more easily identify locations.
[1:45] Ready to build out your custom markers? Let's dig in.
Thanks Alex :) great question!
I haven't done clustering in practice, but I know there's a Leaflet plugin for it: https://github.com/Leaflet/Leaflet.markercluster
You could probably figure out a way to also do this manually if you'd prefer. For instance, with all of your locations, you can show different levels of clustering based on zoom level, which would trigger the changes when someone zooms in / out.
Once that event triggers, you can run calculations on the dataset to determine which locations are close to each other, then using a library like Turf's Centroid function https://turfjs.org/docs/#centroid to find the center of those close locations
Depending on how comfortable you are with digging through source code, you could take those ideas and see how the Leaflet plugin is handling it
While looking I also found this which is a React wrapper around the plugin above, again, haven't used it though: https://github.com/yuzhva/react-leaflet-markercluster
I wanted to contribute for this excellent course! Just few lines of code will do the trick!
In App.js:
import "leaflet.markercluster/dist/MarkerCluster.Default.css"; import "leaflet.markercluster/dist/MarkerCluster.css"; import "leaflet.markercluster";
useEffect(() => { const { current = {} } = mapRef; const { leafletElement: map } = current; ....... ...... const markers = L.markerClusterGroup(); const geoJson = new L.GeoJSON(locations, { ....... markers.addLayer(geoJson); //geoJson.addTo(map); markers.addTo(map); }, [mapRef]);
And don't forget to put the maxZoom in <Map>:
<Map ref={mapRef} center={[38.909419, -77.042614]} zoom={12} maxZoom={18}>
Please feel free to add this important feature if you want!
Cheers
awesome, glad to see it worked out!
Hey,Colby! Very nice course! Thank you for your effort! The only thing I miss is the clustering. How can I implement it?
Thank you