React-Map-GL – Geo mapping earthquakes using markers
In the previous blog post we have seen how to render the map on browser using react-map-gl framework.
Today I will show you how to geomap the earthquakes on the map using react-map-gl framework. I will use <Marker> and <Popup> components from react-map-gl framework visualize and show the information of the earthquakes.
Marker component is used to show the earthquake on the map at given longitude and latitude.
Popup component used for showing the earthquake information when user clicks on the marker icon.
For getting earthquake information I will use the URL used in one of my previous blog post
In this post I will skip the initial application setup steps and proceed with next steps. You can read my previous blog post for initial setup process
First declare the state variable to hold the earthquake information
//declare a state varibale to hold the data
const [eqData, seEqtData] = useState([]);
Code language: JavaScript (javascript)
Next get the earthquake information using the axios
package in useEffect hook
useEffect(() => {
const prevWeekDate = getPreviousWeekdateInISOFormat();
axios
.get(
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&minmagnitude=2&starttime=" +
prevWeekDate
)
.then((response) => {
const eqDataArray = extractEqDataFromGeoJsonResponse(response.data);
seEqtData((eqData) => [...eqData, ...eqDataArray]);
});
}, []);
Code language: JavaScript (javascript)
The response from URL is in the form of GeoJson. So we will extract latitude, longitude, magnitude, place information of each earthquake and store the data in eqData state variable
const extractEqDataFromGeoJsonResponse = (eqResponseData) => {
const eqInfoObjectAarray = [];
const { features } = eqResponseData;
//extract interest data and build objects
features.forEach((feature) => {
const { mag, place } = feature.properties;
const lat = feature.geometry.coordinates[0];
const lng = feature.geometry.coordinates[1];
eqInfoObjectAarray.push({
mag: mag,
place: place,
longitude: lat,
latitude: lng,
});
});
return eqInfoObjectAarray;
};
Code language: JavaScript (javascript)
We iterate over each earthquake object and pass the longitude and latitude information to Marker component. We will show SVG icon on the map for each earthquake.
I have extracted Marker component to separate file. Since marker positions never change, to avoid rendering the markers for every port change I am using useMemo
hook
export const Pins = ({ data, onClick }) => {
return useMemo(() => {
return data.map((earthquake, index) => (
<Marker
key={`marker-${index}`}
longitude={earthquake.longitude}
latitude={earthquake.latitude}
>
<svg
height={SIZE}
viewBox="0 0 24 24"
style={{
cursor: "pointer",
fill: "#d00",
stroke: "none",
transform: `translate(${-SIZE / 2}px,${-SIZE}px)`,
}}
>
<path d={ICON} />
</svg>
</Marker>
));
}, [data, onClick]);
};
Code language: JavaScript (javascript)
Next we will try to show the pop-up with earthquake info when the user clicks on the marker icon. We will use react-map-gl Popup
component
We add the onClick
event to SVG icon and pass the earthquake object to it.
<svg
height={SIZE}
viewBox="0 0 24 24"
style={{
cursor: "pointer",
fill: "#d00",
stroke: "none",
transform: `translate(${-SIZE / 2}px,${-SIZE}px)`,
}}
onClick={() => onClick(earthquake)}
>
Code language: JavaScript (javascript)
Next we hold the earthquake object in a state variable and pass that information to Popup
the component and invoke renderPopup method in render method.
const renderPopup = () => {
return (
popupInfo && (
<Popup
className="popupStyle"
tipSize={5}
anchor="top"
longitude={popupInfo.longitude}
latitude={popupInfo.latitude}
closeOnClick={false}
onClose={() => setPopUpInfo(null)}
dynamicPosition={false}
>
<EarthQuakeInfo earthquakeInfo={popupInfo} />
</Popup>
)
);
};
Code language: JavaScript (javascript)
return (
<div className="App">
<ReactMapGL
{...viewport}
mapboxApiAccessToken={accessToken}
mapStyle={"mapbox://styles/mapbox/dark-v10"}
onViewportChange={(viewport) => {
setViewport(viewport);
}}
>
{renderPopup()}
{<Pins data={eqData} onClick={onMarkerClick} />}
</ReactMapGL>
</div>
);
Code language: JavaScript (javascript)
Complete source code for this blog post can be downloaded from GitHub
.