当前位置: 首页 > news >正文

MapLibre GL JS第45课:加载显示远程SVG符号作为图标

📌 学习目标

  • 掌握显示远程SVG符号的实现方法
  • 理解相关API的使用
  • 能够独立完成类似功能开发

🎯 核心概念

加载显示远程SVG符号作为地图图标。

💻 完 整 代 码

代码示例

constmap=newmaplibregl.Map({container:'map',// 地图容器idstyle:'https://demotiles.maplibre.org/style.json',// 样式URLcenter:[0,0],// 中心点位置zoom:1,// 缩放maplibreLogo:true});map.on('load',()=>{constexistingImages={};map.on('styleimagemissing',async(e)=>{if(existingImages[e.id]){return;}existingImages[e.id]=true;constresponse=awaitfetch(e.id);constsvgText=awaitresponse.text();constsvg='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgText);constimage=newImage();constpromise=newPromise((resolve)=>{image.onload=resolve;});image.src=svg;awaitpromise;// 等待图像加载完成map.addImage(e.id,image);});map.addSource('point',{'type':'geojson','data':{'type':'FeatureCollection','features':[{'type':'Feature','geometry':{'type':'Point','coordinates':[0,0]},},]}});map.addLayer({'id':'svg-symbol','type':'symbol','source':'point','layout':{'icon-image':'https://maplibre.org/maplibre-gl-js/docs/assets/logo.svg','icon-overlap':'always','text-overlap':'always'}});});

代码示例

<!DOCTYPEhtml><htmllang="en"><head><title>Display a remote SVG symbol</title><metaproperty="og:description"content="使用 styleimagemissing 事件加载远程图像并使用它。"/><metaproperty="og:created"content="2025-07-10"/><metacharset='utf-8'><metaname="viewport"content="width=device-width, initial-scale=1"><linkrel='stylesheet'href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css'/><scriptsrc='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script><style>body{margin:0;padding:0;}html, body, #map{height:100%;}</style></head><body><divid="map"></div><script>constmap=newmaplibregl.Map({container:'map',// 容器IDstyle:'https://demotiles.maplibre.org/style.json',// 样式URLcenter:[0,0],// 初始位置 [经度, 纬度]zoom:1,// 初始缩放级别maplibreLogo:true});map.on('load',()=>{constexistingImages={};map.on('styleimagemissing',async(e)=>{if(existingImages[e.id]){return;}existingImages[e.id]=true;constresponse=awaitfetch(e.id);constsvgText=awaitresponse.text();constsvg='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgText);constimage=newImage();constpromise=newPromise((resolve)=>{image.onload=resolve;});image.src=svg;awaitpromise;// 等待图像加载map.addImage(e.id,image);});map.addSource('point',{'type':'geojson','data':{'type':'FeatureCollection','features':[{'type':'Feature','geometry':{'type':'Point','coordinates':[0,0]},},]}});map.addLayer({'id':'svg-symbol','type':'symbol','source':'point','layout':{'icon-image':'https://maplibre.org/maplibre-gl-js/docs/assets/logo.svg','icon-overlap':'always','text-overlap':'always'}});});</script></body></html>

🔍 代码解析

初始化地图

使用new maplibregl.Map()创建地图实例,配置基本参数。本示例的核心特色是展示如何通过styleimagemissing事件动态加载远程 SVG 符号。

关键配置项

  • container: 地图容器的 DOM 元素 ID
  • style: 使用 MapLibre 官方样式https://demotiles.maplibre.org/style.json
  • center: 地图初始中心点[0, 0]
  • zoom: 初始缩放级别为 1,显示全球视图

styleimagemissing 事件处理

map.on('styleimagemissing',async(e)=>{// 防止重复加载if(existingImages[e.id]){return;}existingImages[e.id]=true;// 异步获取远程 SVGconstresponse=awaitfetch(e.id);constsvgText=awaitresponse.text();// 转换为 data URLconstsvg='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgText);// 创建图像并等待加载constimage=newImage();constpromise=newPromise((resolve)=>{image.onload=resolve;});image.src=svg;awaitpromise;// 添加到地图map.addImage(e.id,image);});

动态引用远程 SVG

map.addLayer({'id':'svg-symbol','type':'symbol','source':'point','layout':{'icon-image':'https://maplibre.org/maplibre-gl-js/docs/assets/logo.svg','icon-overlap':'always','text-overlap':'always'}});

⚙️ 参数说明

参数类型必填默认值说明
containerstring-地图容器元素的 ID
stylestring/object-地图样式 URL 或内联样式对象
center[number, number][0, 0]初始中心点坐标
zoomnumber0初始缩放级别

icon-image 布局属性

属性类型必填说明
icon-imagestring图标 ID 或远程 SVG URL
icon-overlapstring是否允许图标重叠

🎨 效果说明

运行代码后,地图上会在坐标[0, 0]处显示一个远程加载的 SVG 图标:

  • SVG 加载: 通过styleimagemissing事件动态加载远程 SVG
  • 图像缓存: 使用existingImages对象防止重复加载
  • Data URL 转换: 将 SVG 文本转换为 Data URL 以便在 Image 对象中使用
  • 交互功能: 支持鼠标拖拽、滚轮缩放等标准交互

💡 常 见 问 题

Q1: 为什么使用 Data URL?
A:MapLibre 的addImage方法需要一个 Image 对象,直接使用远程 URL 创建 Image 对象可能遇到跨域问题。转换为 Data URL 可以避免这个问题。

Q2: 如何处理加载失败?
A:添加 try-catch 块处理网络错误,并提供备用图标:

try{constresponse=awaitfetch(e.id);// ...}catch(error){console.error('Failed to load SVG:',error);// 使用备用图标}

Q3: SVG 可以包含外部资源吗?
A:建议避免在 SVG 中引用外部资源(如外部图像、字体),可能导致加载失败或跨域问题。

Q4: 性能影响如何?
A:SVG 需要解析和渲染,复杂的 SVG 可能影响性能。建议使用简化的 SVG 图标。

📝 练习任务

  1. 基础练习:更换 SVG URL,使用其他远程 SVG 图标
  2. 进阶挑战:添加错误处理,当 SVG 加载失败时显示备用图标
  3. 拓展思考:如何实现 SVG 图标的动态颜色变化?

🌟 最佳实践

  1. 缓存机制: 使用对象或 Map 缓存已加载的图像,避免重复请求
  2. 错误处理: 添加 try-catch 和备用方案
  3. CORS 处理: 确保 SVG 服务器配置了正确的 CORS 头
  4. SVG 优化: 使用简化的 SVG,避免复杂的滤镜和渐变
  5. 性能监控: 监控 SVG 加载时间,优化慢加载的图标
  6. 安全考虑: 验证 SVG 来源,避免加载恶意内容

🔗 延伸阅读

  • Map API文档

  • MapLibre GL JS 官方文档

  • [下一课预告]:将继续学习地图图层的基础知识


本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏

http://www.jsqmd.com/news/991796/

相关文章:

  • 向量数据库过滤搜索:原理、性能与优化实践
  • NV110固态MT29F16T08EWLCHD8-QCES:C
  • 2026合肥全屋定制综合测评榜单发布 雅丽家领跑本土智造梯队 - 资讯焦点
  • 紫光国微19亿收购瑞能半导再进一步:股东大会审议通过,协同效应有望释放
  • 深入解析昇腾CANN开源项目atvoss(ATVOSS),基于Ascend C的Vector算子模板库,提供手把手实战教程与可视化分析指南
  • 手把手教你用Python加载清华SSVEP脑电数据集(附完整代码与数据重塑技巧)
  • 用ECharts搞定气象数据可视化:手把手教你绘制带风向箭头的风速曲线图
  • G-340A多量程全覆盖 集成式光缆普查设备符合油田矿山长距离线路检测需求
  • 2026 温州代账公司收费标准解析,温州代理记账公司排名口碑推荐 - 品牌智鉴榜
  • 数据的加密与解密(11:16)
  • 美国签证服务公司排行:5家机构核心能力实测对比 - 奔跑123
  • 从模拟量到开关量:2026隔离式安全栅十大品牌全覆盖 - 仪表人叶工
  • 深度解析抖音无水印批量下载器:技术架构与实战应用
  • 从SRAM模型到可靠FIFO:一个Verilog状态机设计的完整思考过程与代码迭代
  • S7.0代码思维vs用户思维——技术人的产品转型之路
  • 北京丽泽商务区劳动争议律所TOP榜:新兴金融集聚区企业劳动合规与纠纷处理 - 品牌2026
  • PCIe RAS:从硬件错误到系统恢复的完整链路解析
  • 如何策划海事执法标兵网络投票评选活动?云众评选教程指南 (强防刷+免费导出) - 微信投票小程序
  • 实战RT-Thread:手把手教你为嵌入式设备注入LittleVGL图形界面
  • 如何免费解锁WeMod高级功能:Wand-Enhancer完整使用教程
  • 2026北京黄金回收店排名:耀辉直营连锁模式定义行业标准 - 奢侈品回收
  • 2026年上海超声波焊接机设备厂家选型手册:从技术对标到快速交付 - 年度推荐企业名录
  • 别再死记硬背了!用VBA+Python快速解析DXF文件,自动提取Polyline坐标
  • 6月爱马仕、LV全品类回收,广州本地奢包变现 - 逸程
  • 35张实拍图:电脑设备与铜质零件图像识别训练用原始素材
  • 2026年上海羊毛地毯厂家联系电话:手工真丝/含毛量定制与居家美学地毯源头工厂 - 企业推荐官【官方】
  • 3个让你彻底告别华硕原厂控制软件的实用理由:G-Helper深度体验
  • 如何用BiliTools免费快速下载B站视频:从入门到精通
  • 从Anthropic 内部报告,看 AI 时代的「工程师三阶跃迁」
  • 5分钟快速上手:ncmppGui网易云音乐NCM格式解密转换终极指南