当前位置: 首页 > 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.zskr.cn/news/1503544.html

相关文章:

  • G-340A多量程全覆盖 集成式光缆普查设备符合油田矿山长距离线路检测需求
  • 美国签证服务公司排行:5家机构核心能力实测对比 - 奔跑123
  • 从模拟量到开关量:2026隔离式安全栅十大品牌全覆盖 - 仪表人叶工
  • 用ECharts搞定气象数据可视化:手把手教你绘制带风向箭头的风速曲线图
  • S7.0代码思维vs用户思维——技术人的产品转型之路
  • 北京丽泽商务区劳动争议律所TOP榜:新兴金融集聚区企业劳动合规与纠纷处理 - 品牌2026
  • 如何策划海事执法标兵网络投票评选活动?云众评选教程指南 (强防刷+免费导出) - 微信投票小程序
  • 6月爱马仕、LV全品类回收,广州本地奢包变现 - 逸程
  • 当 SKU 对齐不再拖后腿,市场分析才真正开始
  • 手绘遮罩+双算法图像修复工具:Tkinter界面,支持实时调参与撤销操作
  • 【WorkBuddy专栏19】技能的创造与迁移——从零开始打造你的AI工作流
  • 福州装修公司2026避坑指南:数据实测TOP6榜单 - GrowthUME
  • Anthropic芯片自研与AI硬件军备赛:从Clive Chan跳槽看大模型时代的算力争夺战
  • CANN架构解析|GE图编译引擎核心原理与优化策略:深度剖析图编译技术在异构计算中的应用与实践
  • 告别“大泥球”:我在 Spring Boot 单体架构中实践的模块化隔离
  • 华硕笔记本终极控制方案:G-Helper完整指南与优化教程
  • 从零打造复古像素字体:我的8x16 ASCII字模设计与优化心得
  • 惠州防水补漏 TOP5 排名及调研解析:2026 本地修缮企业盘点,阳台飘窗漏水、厨卫渗水、外墙防水以及瓷砖破损维修全覆盖 - 泛家庭维修
  • 北京黄金回收哪家价格高?2026 年 6 月最新甄选 TOP5 店铺推荐(服务体验篇) - 奢侈品回收
  • 抖音无水印视频下载器:三步轻松保存高清内容
  • OpenClaw 微信绑定全流程,手机端轻松操控电脑
  • 2026最新Java面试1000题(高频·带答案),覆盖大厂考点,建议直接收藏!
  • Linux——管理存储堆栈
  • UI自动化测试|元素操作浏览器操作实践
  • RabbitMQ中如何保证消息的可靠性传输
  • FPGA单端口RAM IP核实战:从配置到在线调试的完整流程
  • 游戏存档编辑神器:uesave让你轻松掌控游戏进度
  • eNSP实战:USG6000V防火墙NAT64配置与双栈网络互通详解
  • 深圳黄金回收放心之选!5家正规门店,资质齐全不踩坑 - 奢侈品回收测评
  • AI巨头IPO竞速与苹果WWDC 2026:AI资本化与消费级AI的新篇章