[Mapbox] Displaying MUI icons as markers on a map.

The react-map-gl Marker is used to display MUI icons on a map.

Here, it is implemented so that the icon to be displayed changes depending on the topic_category_key of the mapMarkers object.

目次

Implement MarkerIcon component.

Define the MUI icons you want to display on the Mapbox map.

Import the MUI icons at the top.
The code is copied from the Material Icons website.

Receive the topic_category_key in Props, specify the Icon to return according to its value and return.
You can add any CSS using the sx property in the MUI writeup.
The MUI Icon is an svg, so it uses the stroke property and other properties that can be used with svg.

import HolidayVillageIcon from '@mui/icons-material/HolidayVillage'
import StorefrontIcon from '@mui/icons-material/Storefront'
import LocationOnIcon from '@mui/icons-material/LocationOn'
import styled from 'styled-components'
import React from 'react'

interface Props {
  topic_category_key: number
}

export default React.memo(function MarkerIcon(props: Props) {
  switch (props.topic_category_key) {
    case 1:
      return (
        <MarkerIconWrapper>
          <HolidayVillageIcon
            sx={{ color: '#386E7C', fontSize: 40, strokeWidth: '4px', stroke: '#fff', paintOrder: 'stroke' }}
          />
        </MarkerIconWrapper>
      )
    case 2:
      return (
        <MarkerIconWrapper>
          <StorefrontIcon
            sx={{ color: '#EDA83D', fontSize: 40, strokeWidth: '6px', stroke: '#fff', paintOrder: 'stroke' }}
          />
        </MarkerIconWrapper>
      )
    default:
      return (
        <MarkerIconWrapper>
          <LocationOnIcon
            sx={{ color: '#CEDBD0', fontSize: 40, strokeWidth: '4px', stroke: '#fff', paintOrder: 'stroke' }}
          />
        </MarkerIconWrapper>
      )
  }
})

const MarkerIconWrapper = styled.div`
  svg {
    transition: 0.3s all;
  }
`

I created a MarkerIconWrapper with styled-components because I wanted the Icon to transition when hovered over.
The relevant components are not written in this article.

Define mapMarkers objects.

Define a mapMarkers object.
Set the latitude and longitude and the topic_category_key you want to display in the MarkerIcon component.

In practice, you will probably get this from the API and set it dynamically.

const mapMarkers = [
  {
    "id": "marker1",
    "lng": -0.1257,
    "lat": 51.508,
    "topic_category_key": 1
  },
  {
    "id": "marker2",
    "lng": -0.1275,
    "lat": 51.507,
    "topic_category_key": 2
  },
  {
    "id": "marker3",
    "lng": -0.1425,
    "lat": 51.500,
    "topic_category_key": 3
  },
]

Drawing Icon on Map.

Draw a Marker by passing it to the children of the Map component of react-map-gl.

Turn the mapMarkers object in a map to create a MapMarker component.
Call MarkerIcon in the MapMarker to display the MUI Icon

<Map
      id='map'
      initialViewState={{
        zoom: 17
      }}
      reuseMaps
      mapStyle={'mapbox://styles/mapbox/streets-v11'}
      mapboxAccessToken={process.env.NEXT_PUBLIC_MAP_BOX_TOKEN}
    >
      <NavigationControl />
      {mapMarkers.map(m => {
        return (
          <MapMarker
            key={m.id}
            longitude={m.lng}
            latitude={m.lat}
            anchor='center'
            style={{ cursor: 'pointer' }}
          >
            <MarkerIcon topic_category_key={m.topic_category_key} />
          </MapMarker>
        )
      })}
    </Map>

It appears like this.

Summary

The Mapbox API is easy to understand and call.

You can load an arbitrary svg file, but if you don’t have time to create one, you can use the MUI Icon instead.

よかったらシェアしてね!
目次