Flutter mapbox_gl如何将polyline绘制在symbol图层下方
问题核心原因
Mapbox GL 渲染图层严格遵循后添加的图层在上的规则,你调用addLineLayer时没有指定插入位置,SDK默认会把新创建的线图层插到所有现有图层的最顶端,自然会盖住已经存在的symbol标记。
另外mapbox_gl封装的addSymbol方法不开放图层指定参数,所有通过这个方法添加的标记,默认都会被放到SDK内置的、固定id为com.mapbox.annotations.symbol的公共symbol图层里。
解决方案
方案1:最小改动方案(无需修改现有symbol添加逻辑)
不需要单独创建自定义symbol图层,只需要在添加线图层时,通过belowLayerId参数显式指定把线层插到内置symbol图层的下方即可。
直接修改你updatePolyLines方法中的addLineLayer调用,新增一行参数:
await _mbController!.addLineLayer( "fills", "lines", const LineLayerProperties( lineColor: '#007AFF', lineCap: "round", lineJoin: "round", lineWidth: 4, ), // 新增参数:指定线层插入到内置标记图层下方 belowLayerId: "com.mapbox.annotations.symbol", );
注意:必须等地图完全加载完成、内置标注图层初始化完毕后再调用图层添加逻辑,否则会抛出找不到对应layerId的错误,建议把路线更新的调用逻辑放在
onMapLoaded回调触发之后执行。
方案2:全自定义图层方案(适合多图层复杂场景)
如果后续需要加更多不同层级的标注、路线、面图层,不建议用封装好的addSymbol方法,完全自己控制所有图层的添加顺序即可:
- 按从下到上的渲染顺序添加图层:最先加最底层的底图相关层,然后加线层、面状层,最后加最上层的标记层
- 标记不要用
addSymbol添加,而是和路线一样自己创建GeoJson数据源,再调用addSymbolLayer创建专属的标记图层
示例代码:
// 1. 先添加路线图层(下层) await _mbController!.removeLayer("lines"); await _mbController!.removeSource("fills"); await _mbController!.addSource("fills", GeojsonSourceProperties(data: _fills)); await _mbController!.addLineLayer( "fills", "lines", const LineLayerProperties( lineColor: '#007AFF', lineCap: "round", lineJoin: "round", lineWidth: 4, )); // 2. 后添加车辆标记图层(上层) final vehicleMarkerSource = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [vehicle['position']['lon'], vehicle['position']['lat']] } } ] }; await _mbController!.removeLayer("vehicleMarkerLayer"); await _mbController!.removeSource("vehicleMarkers"); await _mbController!.addSource("vehicleMarkers", GeojsonSourceProperties(data: vehicleMarkerSource)); await _mbController!.addSymbolLayer( "vehicleMarkers", "vehicleMarkerLayer", const SymbolLayerProperties( iconImage: "vehicle", iconAllowOverlap: true, // 开启允许重叠,避免标记被自动隐藏 iconSize: 1, ) );
如果后续需要调整层级,也可以通过belowLayerId、aboveLayerId参数指定新图层插入到任意现有图层的上方或下方,不需要严格按顺序添加。
常见踩坑点
- 不要试图用「先加线、后加symbol」的方式固定层级,只要你后续更新路线时重新调用
addLineLayer,新创建的线层默认还是会跑到所有图层最顶部,必须显式指定插入位置 - 自定义symbol图层如果不显示,优先检查是否设置了
iconAllowOverlap: true,默认配置下如果标记和其他图层元素重叠,会被自动隐藏 - 如果调用时提示找不到图层id,先检查对应图层是否已经创建完成,不要在地图未加载完成时操作图层
内容的提问来源于stack exchange,提问作者Anteino
相关产品推荐
相关产品推荐

