单击时从 Mapbox 地图上的单个 geoJSON 源更新单个要素的样式
Update style of individual feature from single geoJSON source on Mapbox map, when clicked
我正在使用 Mapbox GL JS 以 external geoJSON example 作为起点在地图上绘制 geoJSON 数据。 geoJSON 文件包含许多特征,这些特征在同一层上绘制为单独的标记。我想通过将其颜色从红色更改为蓝色来突出显示单击的标记。我已经修改了示例以在单击时显示带有点 id 的弹出窗口(作为概念证明,即标记可以在单击时触发事件),但是,我正在努力寻找一种方法来更改样式个人点击标记。
目前代码如下:
mapboxgl.accessToken = 'pk.eyJ1IjoiZGFuYnJhbWFsbCIsImEiOiJjbDB3ODFveHYxOG5rM2pubWpwZ2R1Y2xuIn0.yatzJHqBTjQ6F3DHASlriw';
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/satellite-v9', // style URL
zoom: 7, // starting zoom
center: [138.043, 35.201] // starting center
});
map.on('load', () => {
map.addSource('earthquakes', {
type: 'geojson',
data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson'
});
map.addLayer({
'id': 'earthquakes-layer',
'type': 'circle',
'source': 'earthquakes',
'paint': {
'circle-radius': 8,
'circle-stroke-width': 2,
'circle-color': 'red',
'circle-stroke-color': 'white'
}
});
});
map.on('click', 'earthquakes-layer', (e) => {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML('Id: ' + e.features[0].properties.id)
.addTo(map);
});
这是一个代码笔:https://codepen.io/danb1/pen/BaYjOyx
是否实际上无法使用这种方法,而是需要将 geoJSON 文件中的每个要素绘制为单独的图层?我正在努力寻找这方面的任何示例并且无法修改 geoJSON 源 - 它必须来自一个文件(而不是在不同的层上分别加载多个 geoJSON 文件)。
这可以使用 feature-state。首先要做的是确保图层数据包含每个要素的 ID(在示例中,源数据没有,因此我们需要将 generateId: true
添加到 map.addSource
方法)。
然后我们需要向地图添加 mousemove 和 mouseleave 事件以存储 moused-over 特征 ID(如果有的话,即如果鼠标悬停在某个特征上):
let hoveredEarthquakeId = null;
map.on('mousemove', 'earthquakes-layer', (e) => {
map.getCanvas().style.cursor = 'pointer';
if (e.features.length > 0) {
map.setFeatureState(
{ source: 'earthquakes', id: e.features[0].id },
{ hover: true }
);
hoveredEarthquakeId = e.features[0].id;
}
});
map.on('mouseleave', 'earthquakes-layer', () => {
map.getCanvas().style.cursor = '';
if (hoveredEarthquakeId !== null) {
map.setFeatureState(
{ source: 'earthquakes', id: hoveredEarthquakeId },
{ hover: false }
);
}
hoveredEarthquakeId = null;
});
最后,在图层属性中,需要更新圆的颜色设置以反映针对特征存储的悬停值:
'circle-color': [
'case',
['boolean', ['feature-state', 'hover'], false],
'#00f',
'#f00'
],
最后的东西可以看modified pen. There is also a MapBox tutorial covering this kind of thing in a slightly more complicated way, which I hadn't come across until now: https://docs.mapbox.com/help/tutorials/create-interactive-hover-effects-with-mapbox-gl-js/.
我正在使用 Mapbox GL JS 以 external geoJSON example 作为起点在地图上绘制 geoJSON 数据。 geoJSON 文件包含许多特征,这些特征在同一层上绘制为单独的标记。我想通过将其颜色从红色更改为蓝色来突出显示单击的标记。我已经修改了示例以在单击时显示带有点 id 的弹出窗口(作为概念证明,即标记可以在单击时触发事件),但是,我正在努力寻找一种方法来更改样式个人点击标记。
目前代码如下:
mapboxgl.accessToken = 'pk.eyJ1IjoiZGFuYnJhbWFsbCIsImEiOiJjbDB3ODFveHYxOG5rM2pubWpwZ2R1Y2xuIn0.yatzJHqBTjQ6F3DHASlriw';
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/satellite-v9', // style URL
zoom: 7, // starting zoom
center: [138.043, 35.201] // starting center
});
map.on('load', () => {
map.addSource('earthquakes', {
type: 'geojson',
data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson'
});
map.addLayer({
'id': 'earthquakes-layer',
'type': 'circle',
'source': 'earthquakes',
'paint': {
'circle-radius': 8,
'circle-stroke-width': 2,
'circle-color': 'red',
'circle-stroke-color': 'white'
}
});
});
map.on('click', 'earthquakes-layer', (e) => {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML('Id: ' + e.features[0].properties.id)
.addTo(map);
});
这是一个代码笔:https://codepen.io/danb1/pen/BaYjOyx
是否实际上无法使用这种方法,而是需要将 geoJSON 文件中的每个要素绘制为单独的图层?我正在努力寻找这方面的任何示例并且无法修改 geoJSON 源 - 它必须来自一个文件(而不是在不同的层上分别加载多个 geoJSON 文件)。
这可以使用 feature-state。首先要做的是确保图层数据包含每个要素的 ID(在示例中,源数据没有,因此我们需要将 generateId: true
添加到 map.addSource
方法)。
然后我们需要向地图添加 mousemove 和 mouseleave 事件以存储 moused-over 特征 ID(如果有的话,即如果鼠标悬停在某个特征上):
let hoveredEarthquakeId = null;
map.on('mousemove', 'earthquakes-layer', (e) => {
map.getCanvas().style.cursor = 'pointer';
if (e.features.length > 0) {
map.setFeatureState(
{ source: 'earthquakes', id: e.features[0].id },
{ hover: true }
);
hoveredEarthquakeId = e.features[0].id;
}
});
map.on('mouseleave', 'earthquakes-layer', () => {
map.getCanvas().style.cursor = '';
if (hoveredEarthquakeId !== null) {
map.setFeatureState(
{ source: 'earthquakes', id: hoveredEarthquakeId },
{ hover: false }
);
}
hoveredEarthquakeId = null;
});
最后,在图层属性中,需要更新圆的颜色设置以反映针对特征存储的悬停值:
'circle-color': [
'case',
['boolean', ['feature-state', 'hover'], false],
'#00f',
'#f00'
],
最后的东西可以看modified pen. There is also a MapBox tutorial covering this kind of thing in a slightly more complicated way, which I hadn't come across until now: https://docs.mapbox.com/help/tutorials/create-interactive-hover-effects-with-mapbox-gl-js/.