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)
https://gist.github.com/sureshgadupu/6cb89528f0fdffd7cca9525b7f17dc9e

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)
https://gist.github.com/sureshgadupu/10c71a9942e6e34877640a7d9cfb78e4

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)
https://gist.github.com/sureshgadupu/b292555e9ec675ae11476725c34175f6

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)
https://gist.github.com/sureshgadupu/a43e77a736514f9b24d7fdcba5a9276e
geo-maaping markers

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)
https://gist.github.com/sureshgadupu/13d509ffa80be94be618699e11650d5e

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)
https://gist.github.com/sureshgadupu/ebec4ee2a931020cfe588fd2243b9d8c

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)
https://gist.github.com/sureshgadupu/51b1e2d1614f1008c153346fe4b5ebe5
popup

Complete source code for this blog post can be downloaded from GitHub.

Similar Posts