首页 > 解决方案 > 使用mapbox gl js在地图上显示侧面列表中所选项目的弹出窗口

问题描述

我按照本教程“在地图视图中过滤功能”并设法使其适应我的数据,这些数据是多边形而不是点。

但是,不会显示侧面菜单上的弹出窗口,当我将鼠标放在其中一个位置上时,弹出窗口不会出现在地图上,指示应有的位置。我认为的问题是因为它是一个多边形而不是一个点(一对坐标)代码无法显示位置,控制台中的错误是:

"Uncaught Error:` LngLatLike` argument must be specified as a LngLat instance, an object {lng: <lng>, lat: <lat>}, an object {lon: <lng>, lat: <lat>}, or an array of [<lng>, <lat>] "

在地图弹出窗口中,我将其从“ .setLngLat (feature.geometry.coordinates)”更改为“ .setLngLat (e.lngLat)”并且它有效,但不是在侧面菜单的弹出窗口中。我还在开始学习javascript,但找不到解决方案,我想过从多边形中提取质心,但我不知道该怎么做。

生成弹出窗口的代码:

var prop = feature.properties;
var item = document.createElement('a');
item.href = prop.wikipedia;
item.target = '_blank';
item.textContent = prop.NM_UF + ' (' + prop.SIGLA_UF + ')';
item.addEventListener('mouseover', function () {
    // Highlight corresponding feature on the map
    popup
        .setLngLat(feature.geometry.coordinates)
        .setText(
            feature.properties.NM_UF +
            ' (' +
            feature.properties.SIGLA_UF +
            ')'
        )
        .addTo(map);
});
listingEl.appendChild(item);
    });

这是一个类似于代码的代码笔: https ://codepen.io/hugonbgg/pen/PoNwWVj和调试:https ://codepen.io/hugonbgg/debug/PoNwWVj/

标签: javascriptmapboxmapbox-gl-js

解决方案


长话短说,您正在使用包含PolygonMultiPolygon特征的源,因此您选择的特征坐标有时是一个数组,有时是一个多维数组。

有不同的方法可以解决这个问题......

又快又脏

popup
    .setLngLat(feature.geometry.coordinates[0][0]) //just add [0][0]
    .setText(
        feature.properties.NM_UF +
        ' (' +
        feature.properties.SIGLA_UF +
        ')'
    )
    .addTo(map);

这只是有效,但将弹出提示定位在第一个多边形的第一个点上......绝对不是最好的,但它有效。

第二种方法是我会做的......

通过方法找到任何特征的中心

我已根据您的代码创建了此代码笔getFeatureCenter,并进行了此更改以包含一个方法。

function getFeatureCenter(feature) {
    let center = [];
    let latitude = 0;
    let longitude = 0;
    let height = 0;
    let coordinates = [];
    feature.geometry.coordinates.forEach(function (c) {
        let dupe = [];
        if (feature.geometry.type === "MultiPolygon")
            dupe.push(...c[0]); //deep clone to avoid modifying the original array
        else 
            dupe.push(...c); //deep clone to avoid modifying the original array
        dupe.splice(-1, 1); //features in mapbox repeat the first coordinates at the end. We remove it.
        coordinates = coordinates.concat(dupe);
    });
    if (feature.geometry.type === "Point") {
        center = coordinates[0];
    }
    else {
        coordinates.forEach(function (c) {
            latitude += c[0];
            longitude += c[1];
        });
        center = [latitude / coordinates.length, longitude / coordinates.length];
    }

    return center;
}

然后更改您对弹出窗口的调用

popup
    .setLngLat(getFeatureCenter(feature)) //call the new method and enjoy!
    .setText(
        feature.properties.NM_UF +
        ' (' +
        feature.properties.SIGLA_UF +
        ')'
    )
    .addTo(map);

如果它是,这将独立地找到特征中心PointPolygon或者MultiPolygon......

在此处输入图像描述

PS.-如果这个答案解决了您的问题,请将其标记为“答案已接受”,这样也将帮助其他用户知道这是正确的解决方案。


推荐阅读