For quite some time, I have been looking for a free and open-source alternative to Google map, because it started showing me the following issues:
Troubleshooters:
Then I came across Leaflet,
Leaflet is an open-source JavaScript library for creating mobile-friendly interactive maps, small and easy-to-use, in general, an amazing alternative to react-google-maps.
The level of control over Leaflet is unmatched, with an ever-growing collection of plugins and constantly updated, developer-driven API.
Reasons for selecting Leaflet:
- Easy to implement with few dependencies.
- Large community.
- customizable.
Steps for development
I would like to show you a simple and easy app using Create React App. (For instructions on how to get started, use the Quick Guide) and react-leaflet in just 3 steps. Leaflet tutorials are also available at egghead.io.
1. let’s install leaflet and react-leaflet. In the project directory, run:
npm install leaflet react-leaflet # for npm
yarn add leaflet react-leaflet # for yarn
2. Now, install esri-leaflet-geocoder to add search functionality in your map:
npm install esri-leaflet-geocoder # for npm yarn add esri-leaflet-geocoder # for yarn
3. Create a Map component
/** @format */
import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import React, { useEffect, useState, useRef } from "react";
import { geosearch } from "esri-leaflet-geocoder";
import "leaflet/dist/leaflet.css";
import "esri-leaflet-geocoder/dist/esri-leaflet-geocoder.css";
import L from "leaflet";
function MapView(props) {
const mapRef = useRef();
const [position, setPosition] = useState([50, 10]);
const [icon, setIcon] = useState();
useEffect(() => {
const { current = {} } = mapRef;
const { leafletElement: map } = current;
if (!map) return;
const control = geosearch();
control.addTo(map);
control.on("results", handleOnSearchResuts);
let greenIcon = L.icon({
iconUrl:
"https://upload.wikimedia.org/wikipedia/commons/c/c9/Font_Awesome_5_solid_map-marker-alt.svg",
shadowUrl:
"https://upload.wikimedia.org/wikipedia/commons/c/c9/Font_Awesome_5_solid_map-marker-alt.svg",
iconSize: [20, 30],
// iconAnchor: [22, 94],
// popupAnchor: [-3, -76],
shadowSize: [20, 30],
// shadowAnchor: [22, 94],
});
setIcon(greenIcon);
return () => {
control.off("results", handleOnSearchResuts);
};
}, []);
/**
* handleOnSearchResuts
* @param {object} data Results object from esri-leaflet-geocoder
*/
const handleOnSearchResuts = (data) => {
console.log("Search results", data);
setPosition([data.latlng.lat, data.latlng.lng]);
}
return (
<Map
ref={mapRef}
center={position}
zoom={6}
style={{ width: "400px", height: "400px" }}
>
<TileLayer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png" />
<Marker position={position} icon={icon}>
<Popup>Popup for any custom information.</Popup>
</Marker>
</Map>
);
}
export default MapView;
Tadaa… Our Map is all set to work
Have I missed something? Please feel free to post in the comments.