2

i want to add custom marker to my map. Im using react-map-gl library and components Layer and Source. My code is:

import pin from "../images/pin.svg";

. . . .

const geojson: GeoJSON.Feature<GeoJSON.Geometry>  = {
            type: 'Feature' ,
            geometry:{
                type: 'Point' as 'Point', 
                coordinates:[21.300465619950796 , 48.70795452044564],
            },
            properties: {
                name: "Marker",

              }
          };
          const layerStyle = {
            id: 'point',
            type: 'symbol' as 'symbol',
            source: 'Marker',
            layout: {
                'icon-image': 'pin',
                'icon-size': 1
            },
            paint: {
              'icon-color': '#78546'
    
            },
          }; 

. . . .

<Source id="my-data" type="geojson" data={geojson}>
   <Layer {...layerStyle} />
</Source> 

But my icon doesnt appear. Can you help me please?

drot
  • 95
  • 1
  • 5

2 Answers2

0

Basically mapbox needs to have a reference of the image already stored before it can assigned it to a pin/marker in a layer symbol.

Here is what I did, and hope it helps you

  1. First create a onLoad function that will be called when the map loads
<Map
  ...
  ref={mapRef} // need a ref to reference it later if you don't have it already
  onLoad={onLoad}
/>
  1. In the onLoad function create a new image and load its content
const onLoad = (e) => {
  if (mapRef.current) {
    const pinImage = new Image();
    pinImage.onload = () => {
      if (!mapRef.current.hasImage('pin')) {
        mapRef.current.addImage('pin', pinImage, { sdf: true });
      }
    }
    pinImage.src = pin; // pin is your svg import
  }
}

It should now work with your current layer attributes, please note that the name given in the addImage call (the first argument 'pin') must match the image-icon in the layer settings.

Note: Also make sure the layer style source attribute matches that of its source id.

Ricardo Sanchez
  • 4,935
  • 11
  • 56
  • 86
-2

Something like this:

import ReactMapGL, {Marker} from 'react-map-gl';

<ReactMapGL width="100vw" height="100vh">
  <Marker longitude={longitude} latitude={latitude} >
    <img src={pin} />
  </Marker>
</ReactMapGL>
davood Sandoghsaz
  • 674
  • 1
  • 4
  • 13
  • 1
    this dont work for me because then marker image is not on the correct position. Thats why i want to use the Layer component and symbol. – drot Dec 26 '21 at 20:13
  • You should add offset to marker ```offsetLeft={-markerSize / 2} offsetTop={-markerSize}``` – SchemeSonic May 05 '22 at 13:09
  • @SchemeSonic No this is not what the OP asked for nor the solution to its problem, the maker(s) need to be in contained in a layer not on its own. – Ricardo Sanchez Oct 06 '22 at 03:14
  • @RicardoSanchez I think you are confused between mapboxgl and react-map-gl. He does not need an extra layer to display custom markers. There is already existing Marker component in react-map-gl. Check out https://github.com/visgl/react-map-gl/blob/7.0-release/examples/controls/src/app.tsx – SchemeSonic Oct 09 '22 at 18:28
  • @SchemeSonic the OP is clearly stating the use of `Source` & `Layers` with `react-map-gl`, not a `Marker` component on its own. – Ricardo Sanchez Oct 10 '22 at 04:34