基于Mapbox API
以及Mapbox-gl-draw
插件进行样式自定义变更
参考API
在使用 Mapbox GL JS 进行地图开发时,我们经常需要实现自定义的绘制样式和点位标记,并且需要动态更新这些样式。本文将详细介绍如何使用 mapbox-gl-draw 实现自定义样式,如何处理用户属性,以及如何实现动态更新。
DrawStyle 是一个样式配置数组,用于定义地图上各种绘制元素的样式。让我们详细分析其主要组成部分:
javascriptconst DrawStyle = [
// 1. 多边形填充样式(未激活)
{
id: "gl-draw-polygon-fill-inactive",
type: "fill",
filter: ["all",
["==", "active", "false"],
["==", "$type", "Polygon"],
["!=", "mode", "static"]
],
paint: {
"fill-color": "#01BE10",
"fill-outline-color": "#01BE10",
"fill-opacity": 0.1
}
},
// 2. 多边形顶点样式
{
id: "gl-draw-polygon-and-line-vertex-halo-inactive",
type: "circle",
filter: [
"all",
["==", "meta", "vertex"],
["==", "$type", "Point"],
["!=", "active", "true"]
],
paint: {
"circle-radius": 10,
"circle-color": "#01BE10"
}
},
// 其他样式配置...
]
多边形样式
gl-draw-polygon-fill-inactive
: 未激活状态的填充样式gl-draw-polygon-fill-active
: 激活状态的填充样式gl-draw-polygon-stroke-inactive
: 未激活状态的边框样式gl-draw-polygon-stroke-active
: 激活状态的边框样式线条样式
gl-draw-line-inactive
: 未激活状态的线条样式gl-draw-line-active
: 激活状态的线条样式点样式
gl-draw-point-point-stroke-inactive
: 未激活状态的点边框样式gl-draw-point-inactive
: 未激活状态的点填充样式gl-draw-point-active
: 激活状态的点样式在初始化 MapboxDraw 时,需要启用 userProperties:
javascriptconst draw = new MapboxDraw({
displayControlsDefault: false,
userProperties: true,
styles: DrawStyle
});
可以在创建或更新要素时添加自定义属性:
javascriptconst feature = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [longitude, latitude]
},
properties: {
id: `${item.id}-${index}`,
visible: true,
color: '#01BE10',
// 其他自定义属性...
}
};
typescriptconst updateSerialNumberCalculation = (
map: mapboxgl.Map,
_taskDeta?: TaskMeta,
_waypointId?: string
) => {
// 参数处理
const __taskData = _taskDeta || taskData;
const __waypointId = _waypointId || waypointId;
if(!map || !__taskData) return;
// 获取数据源
const source = map.getSource(
`${__taskData.id}-source`
) as mapboxgl.GeoJSONSource;
// 更新 GeoJSON 数据
let _geojson = __taskData.geojson;
_geojson.features = _geojson.features.map((feature, index) => {
if (feature.properties.id === `${__waypointId}-${index}`) {
feature.properties.visible = false;
} else {
feature.properties.visible = true;
}
return feature;
});
// 更新数据源
source.setData(_geojson);
};
要实现样式的动态更新,需要在图层配置中使用表达式:
javascriptmap.addLayer({
id: `${layerId}-background`,
type: "circle",
source: sourceId,
paint: {
'circle-radius': 9,
'circle-color': [
"case",
["==", ["get", "visible"], false],
'#01BE10',
'#fff'
],
'circle-stroke-color': [
"case",
["==", ["get", "visible"], false],
'#fff',
'#01BE10'
],
'circle-stroke-width': 2,
},
});
路径点状态更新:
批量更新:
javascript// 推荐做法:批量收集更新
let updatedFeatures = features.map(feature => {
// 更新逻辑
return feature;
});
source.setData({
type: 'FeatureCollection',
features: updatedFeatures
});
javascript// 只在必要时更新
if (hasChanged) {
source.setData(newGeojson);
}
typescriptconst updateSerialNumberCalculation = (
map: mapboxgl.Map,
_taskDeta?: TaskMeta,
_waypointId?: string
) => {
try {
if(!map || !_taskDeta) {
console.warn('Missing required parameters');
return;
}
const source = map.getSource(`${_taskDeta.id}-source`);
if (!source) {
console.error('Source not found');
return;
}
// 更新逻辑...
} catch (error) {
console.error('Error updating serial number:', error);
}
};
通过合理使用 DrawStyle 配置、userProperties 和动态更新机制,我们可以实现:
在实际应用中,需要注意:
通过这些机制的组合使用,可以构建出功能强大且性能优良的地图应用。
claude.ai
生成,结合解决思路与相关API,实现代码使用AI润色生成.感觉我写的属于盗版内容,以下解决案例属于官方给出的解决思路
在mapbox-gl-draw
提供的API中只有简单一句话概述
userProperties, boolean (default: false): properties of a feature will also be available for styling and prefixed with user_, e.g., ['==', 'user_custom_label', 'Example']
翻译过来就是,你可以在styles中提前设置好key
,以及value
,进行控制颜色
json'paint': {
'fill-color': [
"case", ['==', ['get', "user_class_id"], 1], "#00ff00", ['==', ['get', "user_class_id"], 2], "#0000ff",
'#ff0000'
],
'fill-outline-color': '#3bb2d0',
'fill-opacity': 0.5
}
必须已user_
开头
key
:user_class_id
value
:1
color
:#00ff00
详细解释
在需要设置的
styles
对象中如:要变更fill-color
的颜色
需要以数组的形式设置如下
case
条件['==', ['get', 'user_class_id'], 1]
满足条条件后设置颜色:#00ff00
整合起来如下
['==', ['get', "user_class_id"], 1], "#00ff00",['==', ['get', "user_class_id"], 2], "#0000ff",
数组最后一个#ff0000
应当为默认颜色
当你使用mapbox-gl-draw
绘制时会触发draw.create
,draw.update
, 只需要监听就能获取到地图上绘制的features
,
取出features
,设置其中的properties
内容如下:
TypeScript{
"type": "Feature",
"properties": {
"class_id": 1
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
79.30961608886719,
61.57192958204744
],
[
79.34309005737303,
61.57192958204744
],
[
79.34309005737303,
61.57871162332267
],
[
79.30961608886719,
61.57871162332267
],
[
79.30961608886719,
61.57192958204744
]
]
]
}
}
最后只需要将更新后的
Feature
重新使用draw.add
添加到地图上
注意: 切勿更改自带的任务id, 不然不会更新而是添加新的到地图上
本文作者:还是夸张一点
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!