Skip to content

Add a Image as a Marker

Prerequisites

Before you begin, ensure you have:

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css"
      rel="stylesheet"
    />
   
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }
      #map {
        min-height: 500px;
        height: 100%;
        width: 100%;
      }

    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
            const geojson = {
        'type': 'FeatureCollection',
        'features': [
            {
                'type': 'Feature',
                'properties': {
                    'message': 'Foo',
                    'iconSize': [60, 60]
                },
                'geometry': {
                    'type': 'Point',
                    'coordinates': [-66.324462890625, -16.024695711685304]
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'message': 'Bar',
                    'iconSize': [50, 50]
                },
                'geometry': {
                    'type': 'Point',
                    'coordinates': [-61.2158203125, -15.97189158092897]
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'message': 'Baz',
                    'iconSize': [40, 40]
                },
                'geometry': {
                    'type': 'Point',
                    'coordinates': [-63.29223632812499, -18.28151823530889]
                }
            }
        ]
    };
      // Don't forget to replace <YOUR_ACCESS_TOKEN> by your own access token
      const accessToken = "<YOUR_ACCESS_TOKEN>";
 
      const map = new mapmetricsgl.Map({
        container: "map",
        style: `${accessToken}`,
        zoom: 11,
        center: [2.349902, 48.852966],
      }).addControl(new mapmetricsgl.NavigationControl(), "top-right");
      // This plugin is used for right to left languages
      mapmetricsgl.setRTLTextPlugin(
        "https://cdn.mapmetrics-atlas.net/basemaps-assets/js/mapmetrics-gl-rtl-text.min.js"
      );

      // Add a marker with the default icon
         geojson.features.forEach((marker) => {
        // create a DOM element for the marker
        const el = document.createElement('div');
        el.className = 'marker';
        el.style.backgroundImage =
            `url(https://picsum.photos/${
                marker.properties.iconSize.join('/')
            }/)`;
        el.style.width = `${marker.properties.iconSize[0]}px`;
        el.style.height = `${marker.properties.iconSize[1]}px`;

        el.addEventListener('click', () => {
            window.alert(marker.properties.message);
        });

        // add marker to map
        new mapmetricsgl.Marker({element: el})
            .setLngLat(marker.geometry.coordinates)
            .addTo(map);
    });
    

    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const AddImageMarker = () => {
  const mapContainerRef = useRef(null);
  const mapRef = useRef(null);

  useEffect(() => {
    if (!mapContainerRef.current || mapRef.current) return;

    const accessToken = "<YOUR_ACCESS_TOKEN>";

    const geojson = {
      'type': 'FeatureCollection',
      'features': [
          {
              'type': 'Feature',
              'properties': {
                  'message': 'Foo',
                  'iconSize': [60, 60]
              },
              'geometry': {
                  'type': 'Point',
                  'coordinates': [-66.324462890625, -16.024695711685304]
              }
          },
          {
              'type': 'Feature',
              'properties': {
                  'message': 'Bar',
                  'iconSize': [50, 50]
              },
              'geometry': {
                  'type': 'Point',
                  'coordinates': [-61.2158203125, -15.97189158092897]
              }
          },
          {
              'type': 'Feature',
              'properties': {
                  'message': 'Baz',
                  'iconSize': [40, 40]
              },
              'geometry': {
                  'type': 'Point',
                  'coordinates': [-63.29223632812499, -18.28151823530889]
              }
          }
      ]
    };

    const map = new mapmetricsgl.Map({
      container: mapContainerRef.current,
      style: `${accessToken}`,
      center: [-65.017, -16.457],
      zoom: 5,
    });

    map.addControl(new mapmetricsgl.NavigationControl(), "top-right");

    mapmetricsgl.setRTLTextPlugin(
      "https://cdn.mapmetrics-atlas.net/basemaps-assets/js/mapmetrics-gl-rtl-text.min.js"
    );

    // Add markers with custom images
    geojson.features.forEach((markerData) => {
      const el = document.createElement('div');
      el.className = 'marker';

      // Apply styles using an object for cleaner code
      Object.assign(el.style, {
        backgroundImage: `url(https://picsum.photos/${markerData.properties.iconSize.join('/')}/)`,
        width: `${markerData.properties.iconSize[0]}px`,
        height: `${markerData.properties.iconSize[1]}px`,
        backgroundSize: 'cover',
        borderRadius: '50%',
        cursor: 'pointer'
      });

      el.addEventListener('click', () => {
        window.alert(markerData.properties.message);
      });

      new mapmetricsgl.Marker({ element: el })
        .setLngLat(markerData.geometry.coordinates)
        .addTo(map);
    });

    mapRef.current = map;

    return () => {
      map.remove();
      mapRef.current = null;
    };
  }, []);

  return (
    <div
      ref={mapContainerRef}
      style={{
        minHeight: '500px',
        height: '500px',
        width: '100%'
      }}
    />
  );
};

export default AddImageMarker;