Maplibre加载Bing地图瓦片后,Marker与GeoJSON无法显示
问题描述
基于Maplibre构建React组件渲染Bing Maps卫星栅格瓦片,地图本身渲染正常,但添加的Marker和GeoJSON图层完全不显示。怀疑是自定义地图样式过于简化导致覆盖了其他图层,但找不到适合简单栅格地图的样式示例。
相关代码
App.jsx
return ( <> <ToolBar reqParams={requestParams} setReqParams={setRequestParams} /> <BingMap initialViewState={{ longitude: -75.20814109999999, latitude: 42.5264569, zoom: 18, }} style={{ width: "100vw", height: "100vh" }} > <Markers trackerPositions={trackerPositions} /> <LineOverlay trackerPositions={trackerPositions} /> <PolygonsFeature /> </BingMap> </> );
BingMap.jsx
import { useState, useEffect, useRef} from "react"; import { Source, Layer } from 'react-map-gl'; import { Map } from 'react-map-gl/maplibre'; import "./bingMaps.css" import 'maplibre-gl/dist/maplibre-gl.css'; import maplibregl from 'maplibre-gl'; import MYSTYLE from './layertest.json' export default function BingMap ({initialViewState, style}) { const [mapStyle, setMapStyle] = useState(null) const map = useRef(null); var BingMapsKey = 'MUMBLYMUMBLY'; var BingMapsImagerySet = 'AerialWithLabelsOnDemand'; //可替换为'AerialWithLabelsOnDemand'显示地图标签 var BingMapsImageryMetadataUrl = `https://dev.virtualearth.net/REST/V1/Imagery/Metadata/${BingMapsImagerySet}?output=json&include=ImageryProviders&key=${BingMapsKey}`; useEffect(() => { async function fetchData() { if (mapStyle) return; const response = await fetch(BingMapsImageryMetadataUrl); const r = await response.json(); var tileInfo = r.resourceSets[0].resources[0]; //为每个子域名生成瓦片URL,提升加载速度 var tileUrls = []; tileInfo.imageUrlSubdomains.forEach(sub => { tileUrls.push(tileInfo.imageUrl.replace('{subdomain}', sub)); }); //生成版权声明 var attributions = tileInfo.imageryProviders.map(p => { return p.attribution; }).join(', '); //构建包含Bing栅格瓦片的地图样式 var ss = { 'version': 8, 'sources': { 'bing-maps-raster-tiles': { 'type': 'raster', 'tiles': tileUrls, 'tileSize': tileInfo.imageWidth, 'attribution': attributions, //Bing瓦片为256px,MapLibre默认512px,因此调整缩放范围 'minzoom': 1, 'maxzoom': 20 } }, 'layers': [ { 'id': 'bing-maps-tiles', 'type': 'raster', 'source': 'bing-maps-raster-tiles', 'minzoom': 0, 'maxzoom': 23 //允许瓦片超缩放以支持更高层级 } ] }; setMapStyle(ss); }; fetchData(); },[]); return (mapStyle ? <> <Map initialViewState={initialViewState} style={style} mapStyle={mapStyle} /> </> : <h1> loading </h1> ); }
解决方案
问题核心是BingMap组件没有将传入的子元素传递给内部的Map组件,导致你在App中添加的<Markers>、<LineOverlay>等组件根本没有挂载到地图实例上,因此无法显示。
只需修改BingMap组件的两处:
- 在组件参数中接收
children - 将
children作为<Map>的子元素渲染
修改后的BingMap.jsx关键代码:
// 1. 接收children参数 export default function BingMap ({initialViewState, style, children}) { // ... 原有逻辑保持不变 ... return (mapStyle ? <> <Map initialViewState={initialViewState} style={style} mapStyle={mapStyle} > {/* 2. 渲染子组件 */} {children} </Map> </> : <h1> loading </h1> ); }
修改完成后,所有传入BingMap的子组件都会被正确挂载到Maplibre地图实例上,Marker和GeoJSON图层即可正常显示。
内容的提问来源于stack exchange,提问作者wdawson
相关产品推荐
相关产品推荐

