MapBox 超级聚类(supercluster)位置错误

6
我正在使用Mapbox Supercluster制作一个聚类地图。我面临的问题是聚类点的位置不正确。例如,我只有荷兰的狗,但当缩小比例时它们也在法国。请注意,保留HTML标签。

enter image description here

当我进一步缩放时,聚类点慢慢地移动到荷兰。当我滚动地图时,聚类点也会移动。
问题可以在我的网站https://v2.sayhi.dog/?dog-map=true上看到。
我的代码如下(我使用vue.js):
<template>
    <div class="w-full h-full" id="map"></div>
</template>

<script>
    import mapboxgl from 'mapbox-gl'
    import Supercluster from 'supercluster';

    export default {
        props: ['locations'],

        data() {
            return {
                map: null,
                copyLocations: this.locations,
                clusters: [],
                markers: [],
                clustersGeojson: {},
                clusterIndex: null,
            }
        },

        mounted() {
            mapboxgl.accessToken = 'my-token';
            // init the map
            this.map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/sayhi/cjkp9e59x3m3y2rm1zbcc0c',
                zoom: 2,
            });

            this.addControls();
            this.map.on("load", () => { this.addMarkers() });
            this.map.addControl(new mapboxgl.NavigationControl());
        },

        methods: {
            addMarkers() {
                this.clusterIndex = new Supercluster({
                    radius: 40,
                    maxZoom: 10
                });

                this.clusterIndex.load(this.locations.features);
                this.map.on('moveend', () => { this.moveEnd(); });
                this.updateClusters();
            },

            updateClusters() {
                var bounds = this.map.getBounds(),
                    zoom = this.map.getZoom();

                this.clustersGeojson = this.clusterIndex.getClusters([
                    bounds.getWest(),
                    bounds.getSouth(),
                    bounds.getEast(),
                    bounds.getNorth()
                ], Math.floor(zoom));

                if (Object.keys(this.clusters).length) {
                    this.clusters.forEach(function(cluster) {
                        cluster.remove();
                    });
                }

                this.displayFeatures(this.clustersGeojson);
            },

            addControls() {
                this.map.addControl(new mapboxgl.NavigationControl(), "bottom-right");
                this.map.addControl(new mapboxgl.FullscreenControl(), "bottom-right");
            },

            moveEnd() {
                this.updateClusters();
            },

            displayFeatures(features) {
                if (this.markers.length) {
                    this.markers.forEach(function(marker) {
                        marker.remove();
                    });
                }

                features.forEach((feature) => {
                    var isCluster = (!!feature.properties.cluster) ? true : false,
                        $feature;

                    if (isCluster) {
                        var leaf = this.clusterIndex.getLeaves(feature.properties.cluster_id)[0];
                        $feature = document.createElement("div");
                        $feature.className = 'flex items-center justify-center w-12 h-12 rounded-full text-center text-white font-bold shadow bg-cover cursor-pointer bg-center';
                        $feature.style.backgroundImage = `url(${leaf.properties.image})`;

                        var $inner = document.createElement("div");
                        $inner.innerHTML = feature.properties.point_count_abbreviated;

                        $feature.appendChild($inner);
                        this.clusters[feature.properties.cluster_id] = new mapboxgl.Marker($feature).setLngLat(feature.geometry.coordinates).addTo(this.map);
                    } else {
                        $feature = document.createElement('div');
                        $feature.className = 'flex items-center justify-center w-12 h-12 rounded-full text-center text-white font-bold shadow bg-cover cursor-pointer bg-center';
                        $feature.style.backgroundImage = `url(${feature.properties.image})`;

                        this.markers.push(new mapboxgl.Marker($feature).setLngLat(feature.geometry.coordinates).addTo(this.map));
                    }
                });
            }
        }
    }
</script>

https://gist.github.com/larsjanssen6/ebb5d7e3887c885af4c65d294ca1fb77

这是一个非常令人沮丧的问题,我已经苦苦挣扎了几天,真的需要帮助。

--更新--

我创建了一个JSFiddle:

https://jsfiddle.net/obhstrvz/10/

希望有人能够帮助。

我无法在https://v2.sayhi.dog/?dog-map=true上看到任何集群标记。 - Leon
@Leon,他们现在回来了 :) 尝试了一些不起作用的东西。 - Jenssen
问题似乎归结于未能包含 mapbox-gl.css 文件。请参见我的答案 - Leon
2个回答

4
当页面加载时,开发者工具控制台显示以下警告:

此页面似乎缺少Mapbox GL JS的CSS声明,这可能导致地图显示不正确。请确保您的页面包含mapbox-gl.css,如https://www.mapbox.com/mapbox-gl-js/api/中所述。

尽管Mapbox GL JS API参考文档中没有涉及到mapbox-gl.css的说明,但您可以在示例中找到它的使用方式。通过在页面的<head>部分添加以下行,可以通过开发人员工具消除各种位置问题(除了标记,还表现为缺少地图控件):
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.0/mapbox-gl.css' rel='stylesheet' />

请注意,您可能需要使用另一个版本来匹配您的 mapbox-gl.js 文件的版本。

您是我的英雄 :) 非常感谢! - Jenssen

2
这个链接这里说您需要一个偏移量来使标记始终保持居中,快速浏览您的代码后,我认为您需要在这里使用它。"最初的回答"。
this.clusters[feature.properties.cluster_id] = new mapboxgl.Marker($feature,{ offset: 25 } ).setLngLat(feature.geometry.coordinates).addTo(this.map);

最初的回答

这里

this.markers.push(new mapboxgl.Marker($feature, { offset: 25 }).setLngLat(feature.geometry.coordinates).addTo(this.map));

嗨,谢谢你的帮助。但是偏移只会在有人点击标记时发生。我还没有这样做。所以不幸的是这可能不是问题的原因。 - Jenssen
不需要,你能否设置一个fiddle之类的东西,这样我可以进行更多的测试吗? - xplo4d
今晚会完成这个 :) - Jenssen
1
我已经制作了一个JS Fiddle https://jsfiddle.net/obhstrvz/10/,如果您需要其他任何东西,请告诉我。 - Jenssen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接