Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MapBox GL JS marker offset

I'm using MapBox GL JS to create a map with a custom marker:

var marker = new mapboxgl.Marker(container)
    .setLngLat([
        datacenters[country][city].coordinates.lng,
        datacenters[country][city].coordinates.lat
    ])
    .addTo(map);

However, I seem to have some kind of offset problem with the marker. The thing is: when zoomed out a bit, the bottom of the marker is not really pointing to the exact location:

Marker when zoomed out a bit

When I'm zooming in a bit further it reaches its destination and it's pointing to the exact spot.

Marker when zoomed in

I really love MapBox GL, but this particular problem is bugging me and I'd love to know how to solve it. When this is fixed my implementation is far more superior to the original mapping software I was using.

like image 728
Dani Avatar asked Aug 04 '16 13:08

Dani


4 Answers

New solution for mapbox-gl.js v1.0.0 - Marker objects now have an anchor option to set the position to align to the marker's Lat/Lng: https://docs.mapbox.com/mapbox-gl-js/api/#marker

var marker = new mapboxgl.Marker(container, {anchor: 'bottom');

This should cover most cases and is more reliable than a pixel offset in my experience.

like image 50
Ben Hull Avatar answered Oct 19 '22 13:10

Ben Hull


Mapbox Marker now has an element option see this link Mapbox Marker. So instead of appending the icon HTML to the Div element you can simply add into the options when creating a marker. I found this also gets rid of the offset problem. So using the code above you can do this....

var icon = document.createElement('i');
icon.classList.add('fas', 'fa-map-marker-alt');
icon.style.color = 'blue';
new mapboxgl.Marker(container, {anchor: 'center', offset: [0, 0], element: icon})

Also the CSS for the marker can be updated to allow a pointer

.mapboxgl-marker {
    border: none;
    cursor: pointer;
}
like image 32
michael Avatar answered Oct 19 '22 14:10

michael


From Mapbox GL JS 0.22.0 you're able to set an offset option to the marker. https://www.mapbox.com/mapbox-gl-js/api/#Marker

For example to offset the marker so that it's anchor is the middle bottom (for your pin marker) you would use:

var marker = new mapboxgl.Marker(container, {
        offset: [-width / 2, -height]
    })
    .setLngLat([
        datacenters[country][city].coordinates.lng,
        datacenters[country][city].coordinates.lat
    ])
    .addTo(map);
like image 16
AndrewHarvey Avatar answered Oct 19 '22 15:10

AndrewHarvey


I've found an solution to my problem. It might be somewhat hacky, but it solves the positioning problem of the marker: I'm using a Popup fill it with a font awesome map marker icon and remove it's "tooltip styled" borders:

Javascript:

map.on('load', function() {
    var container = document.createElement('div');
    var icon = document.createElement('i');
    icon.dataset.city = city;

    icon.addEventListener('click', function(e) {
        var city = e.target.dataset.city;
        var country = e.target.dataset.country
        flyTo(datacenters[country][city].coordinates);
    });

    icon.classList.add('fa', 'fa-map-marker', 'fa-2x');
    container.appendChild(icon);

    var popup = new mapboxgl.Popup({
            closeButton: false,
            closeOnClick: false
        })
        .setLngLat([
            datacenters[country][city].coordinates.lng,
            datacenters[country][city].coordinates.lat
        ])
        .setDOMContent(container)
        .addTo(map);
});

CSS:

.map div.mapboxgl-popup-content {
    background: none;
    padding: 0;
}

.map .mapboxgl-popup-tip {
    display: none;
}

I just hope someone comes up with a real solution, because this feels kinda dirty to me. But hey: it does the job just fine!

like image 2
Dani Avatar answered Oct 19 '22 15:10

Dani