【问题标题】:MapBox GL JS marker offsetMapBox GL JS 标记偏移
【发布时间】:2016-12-10 15:09:45
【问题描述】:

我正在使用MapBox GL JS 创建带有自定义标记的地图:

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

但是,我的标记似乎存在某种偏移问题。问题是:当缩小一点时,标记的底部并没有真正指向确切的位置:

当我再放大一点时,它会到达目的地并指向确切的位置。

我真的很喜欢 MapBox GL,但是这个特殊的问题困扰着我,我很想知道如何解决它。修复此问题后,我的实现比我使用的原始地图软件要好得多。

【问题讨论】:

  • 出于兴趣,@egidius,您是否计划对这些标记进行聚类,如果您已经完成了,能否告诉我如何操作?

标签: javascript mapbox mapbox-gl mapbox-gl-js


【解决方案1】:

Mapbox Marker 现在有一个元素选项,请参阅此链接Mapbox Marker。因此,您可以在创建标记时简单地添加到选项中,而不是将图标 HTML 附加到 Div 元素。我发现这也摆脱了偏移问题。所以使用上面的代码你可以做到这一点......

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})

还可以更新标记的 CSS 以允许指针

.mapboxgl-marker {
    border: none;
    cursor: pointer;
}

【讨论】:

    【解决方案2】:

    mapbox-gl.js v1.0.0 的新解决方案 - 标记对象现在有一个 anchor 选项来设置与标记的纬度/经度对齐的位置:https://docs.mapbox.com/mapbox-gl-js/api/#marker

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

    这应该涵盖大多数情况,并且根据我的经验比像素偏移更可靠。

    【讨论】:

    • 这对我有用,使用与提问者类似的标记,无需设置offset
    【解决方案3】:

    从 Mapbox GL JS 0.22.0 开始,您可以为标记设置偏移选项。 https://www.mapbox.com/mapbox-gl-js/api/#Marker

    例如,要偏移标记,使其锚点位于中间底部(用于您的大头针标记),您可以使用:

    var marker = new mapboxgl.Marker(container, {
            offset: [-width / 2, -height]
        })
        .setLngLat([
            datacenters[country][city].coordinates.lng,
            datacenters[country][city].coordinates.lat
        ])
        .addTo(map);
    

    【讨论】:

    • 酷!我使用的是 v0.21.0,所以我想我的 hack 在我的情况下仍然是合法的。太感谢了。我只需要等待 v 0.22.0 发布。
    • 太棒了!从来不需要等待这么短的时间来发布
    • 终于明白了....原来我的宽度需要为负宽度/2,高度为高度*2...
    • 在当前版本中,偏移量是相对于标记的中心,而不是左上角:docs.mapbox.com/mapbox-gl-js/api/#pointlike
    【解决方案4】:

    我找到了解决问题的方法。这可能有点 hacky,但它解决了标记的定位问题:我正在使用 Popup 用字体真棒地图标记图标填充它并删除它的“工具提示样式”边框:

    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;
    }
    

    我只是希望有人提出一个真正的解决方案,因为这对我来说有点肮脏。但是,嘿:它做得很好!

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      相关资源
      最近更新 更多