Search code examples
javascriptthree.jsmapboxmapbox-gl-jsmapbox-marker

Offset a marker on Mapbox


My map markers look like this:

map

As you can see, the center of the blue markers is what is actually on my desired coordinates, is there a way to offset the markers just a bit up so the tip of the marker sits on my exact point, instead of being centered?

My code for the markers is pretty standard, like on the mapbox documentation. Looks like this:

await nodeList.map((node) => {
    map.addSource(node.name, {
        'type': 'geojson',
        'data': {
            'type': 'FeatureCollection',
            'features': [{
                'type': 'Feature',
                'geometry': {
                    'type': 'Point',
                    'coordinates': [node.longitude, node.latitude]
                },
                'properties': {}
            }]
        }
    });
    map.addLayer({
        'id': node.name,
        'type': 'symbol',
        'source': node.name,
        'layout': {
            'icon-image': 'custom-marker',
            'text-offset': [0, 1.25],
            'text-anchor': 'top'
        }
    });
});


Solution

  • If you check the documentation of symbol layers, you’ll find there’s an option to define an icon-anchor attribute as a string indicating the part of the Marker that should be positioned closest to the coordinate set. Options are 'center' , 'top' , 'bottom' , 'left' , 'right' , 'top-left' , 'top-right' , 'bottom-left' , and 'bottom-right'

    The default value is 'center', so if you use icon-anchor: bottom in the options of your anchor it will position correctly.

    await nodeList.map((node) => {
        map.addSource(node.name, {
            'type': 'geojson',
            'data': {
                'type': 'FeatureCollection',
                'features': [{
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Point',
                        'coordinates': [node.longitude, node.latitude]
                    },
                    'properties': {}
                }]
            }
        });
        map.addLayer({
            'id': node.name,
            'type': 'symbol',
            'source': node.name,
            'layout': {
                'icon-image': 'custom-marker',
                'icon-anchor': 'bottom',
                'text-offset': [0, 1.25],
                'text-anchor': 'top'
            }
        });
    });