第七篇:告别手动拼 URL!我们封装自己的“地图超市”

news/2026/1/21 0:21:22/文章来源:https://www.cnblogs.com/arc3dlab/p/19509129

View Post

第七篇:告别手动拼 URL!我们封装自己的“地图超市”

📘 专栏说明

本专栏旨在手把手带你从零开始,基于开源三维地球引擎 Cesium 封装一套功能完善、可复用的 WebGIS 增强型 SDK。内容涵盖核心封装思路、关键代码实现、常用 GIS 功能抽象,以及基于该 SDK 构建的 UI 组件库开发。如果你更关注结果而非实现过程,也可直接使用已发布的成果:

🌟 GitHub仓库 📦 NPM 包公众号:经纬码客(欢迎关注)

💡 建议:即便你打算直接使用 SDK,也推荐订阅本专栏 -- 理解设计思路,才能更灵活地扩展属于你自己的专属 GIS 能力!

由于作者需兼顾全职工作,更新主要安排在晚间或节假日,无法保证高频发布,但会持续迭代,直至 SDK 达到实际项目落地标准。届时将完整开源所有源码,供学习与商用(遵循许可证协议)。

大家好,我是 Cesium 酱(也可以叫我“本猿”),一名在 WebGIS 领域摸爬滚打多年的前端开发者。前几期,我们封装了 Viewer、增强了事件系统。

但还有一个高频痛点没解决:底图和地形的初始化太繁琐

比如用天地图影像,原生要写:

const provider = new WebMapTileServiceImageryProvider({url: "https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&...&tk=你的密钥",layer: "img",tileMatrixSetID: "w",// ... 还有七八个参数
})

不仅冗长,还容易出错,更别说换图时要重写整个配置。

今天,我们就把这一切简化成:

viewer.baseImagery = BaseLayer.DefaultTdtImg

准备好了吗?打开你的编辑器,继续我们的SDK建设之旅,我们一起来建这个“地图超市”!


🧱 第一步:明确目标 —— 我们要支持哪些图源?

国内开发者最常用的底图/地形包括:

  • 单张静态图(用于离线或简单场景)
  • ArcGIS Online 全球影像/街道图(现在链接好像失效了)
  • 天地图影像 / 矢量 / 注记(需 token)
  • Cesium 官方全球地形
  • 自定义 TMS 地形(如本地部署的 terrain)

我们的 BaseLayer 就要为这些场景提供预设快捷方式


📦 第二步:创建工具函数 —— 天地图参数生成器

首先,在 src/utils/imagery/ImageryOption.ts 中,封装天地图的 URL 拼接逻辑:

// src/utils/imagery/ImageryOption.ts
import { TDT_KEY } from "../def/Default" // 这里是我申请的默认 token
/*** 生成天地图 WMTS 服务配置* @param type 'img' 影像, 'vec' 矢量, 'cva' 矢量注记, 'cia' 影像注记* @param token 天地图开发者密钥*/
export function getTdtOption(type: "img" | "vec" | "cva" | "cia",token = TDT_KEY
) {const url = `https://{s}.tianditu.gov.cn/${type}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${type}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={TileCol}&TILEROW={TileRow}&TILEMATRIX={TileMatrix}&tk=${token}`return {url,layer: type,style: "default",format: "tiles",tileMatrixSetID: "w",maximumLevel: 18,subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],token,}
}

✅ 从此以后,不用再手拼天地图 URL

✅ 支持四种图层类型,自动适配子域名和最大层级。

💡 提示:TDT_KEY 可在 src/utils/def/Default.ts 中定义为你的默认 token,方便团队共享。


🏗️ 第三步:实现 BaseLayer 核心模块

新建 src/core/layers/BaseLayer.ts,这是我们的“地图超市”货架:

// src/core/layers/BaseLayer.ts
import {ImageryLayer,SingleTileImageryProvider,ArcGisMapServerImageryProvider,WebMapTileServiceImageryProvider,createWorldTerrainAsync,Terrain,CesiumTerrainProvider,
} from "cesium"
// 引入本地静态图(sdk里面就是一张蓝色地球背景)
import globeImg from "src/static/globe-img"
// 引入天地图配置生成器
import { getTdtOption } from "src/utils/imagery/ImageryOption"
/*** 基础图层类,包括影像底图和地形底图*/
const BaseLayer = {/*** 默认单图像底图(适用于离线或兜底场景)*/get DefaultSingleImg() {return ImageryLayer.fromProviderAsync(SingleTileImageryProvider.fromUrl(globeImg),{})},/*** 默认 ArcGIS 全球街道图*/get DefaultArcgisImg() {return ImageryLayer.fromProviderAsync(ArcGisMapServerImageryProvider.fromUrl("https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"),{})},/*** 默认天地图影像地图*/get DefaultTdtImg() {const option = getTdtOption("img")return ImageryLayer.fromProviderAsync(Promise.resolve(new WebMapTileServiceImageryProvider(option)),{})},/*** 默认天地图矢量地图*/get DefaultTdtVec() {const option = getTdtOption("vec")return ImageryLayer.fromProviderAsync(Promise.resolve(new WebMapTileServiceImageryProvider(option)),{})},/*** 默认 Cesium 全球地形(带水体和法线)*/get DefaultTerrain() {const terrainProvider = createWorldTerrainAsync({requestWaterMask: true,requestVertexNormals: true,})return new Terrain(terrainProvider)},/*** 加载自定义 TMS 格式地形(如本地部署的 terrain)* @param url 地形服务根路径,如 "http://localhost:8080/terrain/"*/getTerrain(url: string): Terrain {return new Terrain(CesiumTerrainProvider.fromUrl(url))},
}
export default BaseLayer

✅ 所有图层都通过 getter 或方法暴露,使用时自动初始化。

fromProviderAsync + Promise.resolve 确保异步兼容性。

getTerrain() 支持任意 TMS 地形路径,灵活适配私有部署。


🔌 第四步:导出模块,让别人能用

修改 src/index.ts,将 BaseLayer 加入主入口:

// src/index.ts
export { Viewer } from "./core/Viewer"
export { default as BaseLayer } from "./core/layers/BaseLayer"
// 后续继续添加...

然后运行:

npm run build

构建成功后,BaseLayer 就可以在外部使用了!


🧪 第五步:本地测试 —— 一键切换底图!

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>003-底图调整</title><script src="./Cesium/Cesium.js"></script><link rel="stylesheet" href="./Cesium/Widgets/widgets.css" /><script src="./lib/arc3dlab.umd.js"></script><script src="./assests/dat.gui.min.js"></script><style>html,body {margin: 0;padding: 0;width: 100%;height: 100%;}#cesiumContainer {width: 100%;height: 100%;position: relative;}#gui-box {position: absolute;left: 5px;top: 5px;z-index: 99;}</style></head><body><div id="cesiumContainer"><div id="gui-box"></div></div><script>const viewer = new Arc3DLab.Viewer("cesiumContainer", {fpsShow: true,mapboxController: true,})initGui()function initGui() {const params = { message: "GUI面板-底图调整", "base-imagery": 0 }const gui = new dat.GUI({ autoPlace: false })const customContainer = document.getElementById("gui-box")customContainer.appendChild(gui.domElement)gui.add(params, "message")const baseImg = gui.add(params, "base-imagery", {SingleImage: 0,TDTImagery: 1,TDTVector: 2,ArcgisImagery: 3,})baseImg.onChange((val) => {const baseLayer = Arc3DLab.BaseLayerconst option = {0: baseLayer.DefaultSingleImg,1: baseLayer.DefaultTdtImg,2: baseLayer.DefaultTdtVec,3: baseLayer.DefaultArcgisImg,}const imagery = viewer.imageryLayers.add(option[val])viewer.baseImagery = option[val]})}</script></body>
</html>

刷新页面——

🎉 地球瞬间变成高清卫星影像!

✅ 无需拼 URL,无需查文档,一行代码搞定!

ScreenShot_2026-01-20_235830_512


❤️ 写在最后

今天我们做的,不是炫技,而是解决真实开发中的重复劳动

BaseLayer 就像一个“地图超市”,你只需要说“我要天地图影像”,它就给你打包好。

而这个模块还可以继续优化,后续我也确实会做如下扩展:

  • 支持高德、百度等国内地图(通过 XYZ 瓦片)
  • 添加 BaseLayer.fromXYZ(url) 快捷方法
  • 内置离线地形缓存策略

你的需求,就是下一次迭代的方向。

欢迎来 GitHub 提 Issue 或 PR!

让我们一起,把它打磨成你真正想用的工具。


🌟 项目开源,欢迎Star✨!

GitHub:https://github.com/jianlei-wang/Arc3DLab_SDK

NPM:https://www.npmjs.com/package/arc3dlab

Cesium 酱の百宝箱 · 第 7 篇

地图万千,取用一瞬。

2026 年元月之初,与你共建一张好用的地图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1191312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于微信小程序的小区租车拼车系统【源码+文档+调试】

&#x1f525;&#x1f525;作者&#xff1a; 米罗老师 &#x1f525;&#x1f525;个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 &#x1f525;&#x1f525;各类成品Java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot等项目&#…

数字频率计设计超详细版:基本结构与工作流程讲解

以下是对您提供的博文《数字频率计设计超详细版&#xff1a;基本结构与工作流程讲解》的深度润色与专业重构版本。本次优化严格遵循您的全部要求&#xff1a;✅ 彻底去除AI痕迹&#xff0c;语言自然、有“人味”&#xff0c;像一位资深嵌入式工程师在技术博客中娓娓道来&#x…

35岁转行学了网络安全,能谋生吗?

35岁转行学了网络安全&#xff0c;能谋生吗&#xff1f; 35岁转型搞安全是否还有戏&#xff1f; 放眼现在安全圈 00后的黑客CEO已经出场了 18岁的少年也开始穿梭于微软、谷歌、苹果各大国际公司的安全致谢榜 年轻的黑客们早已登上国际舞台&#xff0c;开始在世界顶级黑客大…

VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查

VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查 在使用 VitePress 搭建文档系统时,随着文件数量的增加,手动维护 .vitepress/config.ts 中的 si…

ERROR. pos 145, line 2, column 21, token COMMA 报错已解决

ERROR. pos 145, line 2, column 21, token COMMA 报错已解决 在软件开发过程中&#xff0c;尤其是 Java、C 以及基于模板的配置文件中&#xff0c;偶尔会遇到编译器或 IDE 报出的类似如下错误&#xff1a; ERROR. pos 145, line 2, column 21, token COMMA虽然错误提示看起来枯…

前端指纹技术是如何实现的?(Canvas、Audio、硬件API 核心原理解密)

什么是设备指纹&#xff1f;在讲实现之前&#xff0c;先纠正一个误区&#xff1a;设备指纹&#xff08;Device Fingerprint&#xff09;不是为了知道你是张三&#xff0c;而是为了知道 这台设备是编号 9527。它的核心逻辑只有一条&#xff1a;利用浏览器暴露的硬件底层差异&…

vivado安装资源推荐:新手自学的最佳路径

Vivado 安装指南&#xff1a;从零开始搭建 FPGA 开发环境 你是不是也曾在搜索“vivado安装”时&#xff0c;被一堆杂乱的教程、失效的链接和复杂的系统要求搞得头大&#xff1f; 明明只是想学点 FPGA 基础逻辑设计&#xff0c;结果第一步—— 装软件 &#xff0c;就卡了三天…

LLM动态调参医疗设备故障预警提前30%

&#x1f4dd; 博客主页&#xff1a;Jax的CSDN主页 LLM动态调参&#xff1a;医疗设备故障预警提前30%的范式突破 目录 LLM动态调参&#xff1a;医疗设备故障预警提前30%的范式突破 1. 引言&#xff1a;医疗设备故障的隐性危机 2. 现有预警系统的瓶颈与LLM的破局点 3. LLM动态调…

uni-app使用北斗卫星实现离线定位

权限配置仍然采用 HTML5 的定位方法&#xff0c;首先需要打开定位权限&#xff1a;// manifest.json/* 模块配置 */ "modules" : {"Geolocation" : {}, // 启用定位模块}, /* 应用发布信息 */ "distribute" : {/* android打包配置 */"andr…

React 官方纪录片观后:核心原理解析与来龙去脉

你真的理解 React 的运作方式吗&#xff1f;这段时间在回顾自己过去几年的 React 项目时&#xff0c;我发现一个有点尴尬但很真实的情况&#xff1a; 我能熟练写Hooks、拆组件、做性能优化&#xff0c;但如果有人让我用几分钟解释清楚——React 内部到底是怎么运作的&#xff0…

Java中构建前端可视化维度指标列表:从代码实现到最佳实践

在后端对接前端可视化需求&#xff08;比如雷达图、多维度评分展示&#xff09;时&#xff0c;经常需要把数据库中分散的字段&#xff0c;转换成前端友好的结构化数据格式。今天记录一段典型的“维度指标列表构建代码”&#xff0c;从实现逻辑到优化思路一次性讲透。 一、需求背…

AI法律文书准确性测试方法论

一、风险背景与技术挑战 当前法律AI工具在生成起诉状、合同等文书时存在三类核心风险&#xff1a;虚构法条&#xff08;如评测中出现的错误法条引用&#xff09;、逻辑矛盾&#xff08;如将"双方约定"误用为"甲方必须"的强制性表述&#xff09;及过时条款…

跨境电商“防关联”实战指南:把风险挡在账号之外

跨境平台的风控越来越“聪明”&#xff1a;同一批设备、网络、支付、收货、资料、操作习惯之间&#xff0c;只要出现可被平台归因的“共同点”&#xff0c;就可能触发关联审查&#xff0c;轻则限流、二审&#xff0c;重则直接封号、资金冻结。防关联不是“玄学”&#xff0c;核…

别管,咱们前端人有自己的拼夕夕~

这份清单&#xff0c;是无数次面试复盘后沉淀下来的“考点最大公约数”&#xff0c;是八股文里的精华。它由十六个经典模块构成&#xff0c;像积木一样&#xff0c;能拼出绝大多数大厂面试的轮廓&#xff1a; 1.JavaScript 深度解剖室&#xff1a;这里不问“怎么用”&#xff…

大家有空就去看这份前端宝典,真的能提高level

如果你感觉刷了无数八股文、背了各种框架API&#xff0c;面试时依然被问到哑口无言——问题可能不在于你不够努力&#xff0c;而在于你努力的方向&#xff0c;恰好错过了当前面试真正的筛选逻辑。 如今的前端面试&#xff0c;已经形成了一套高度标准化的「能力探测模型」&…

2026年国内GEO优化服务商深度评测:数据监测能力对比分析

本文深度评测 2026 年国内 GEO 优化服务商 TOP5,重点分析数据监测能力与服务透明度的核心差异。AIDSO 爱搜凭借公域开放、实时监测、白盒交付三大优势领跑行业,覆盖 10 个主流 AI 平台,为企业提供从数据诊断到效果验…

从策划到执行一站式服务,苏州合肥江苏南京双节美陈设计公司甄选

当节日的灯火渐次点亮&#xff0c;城市的脉搏也随之跃动。一场深入人心的节日氛围营造&#xff0c;不仅在于瞬间的视觉惊艳&#xff0c;更在于从概念萌芽到圆满呈现的完整旅程。在长三角的活力版图上&#xff0c;从苏州的精致园林到南京的厚重人文&#xff0c;从合肥的创新节奏…

收藏!大模型技术与应用体系梳理(小白程序员入门必看)

大模型技术开发属于多学科交叉的复杂领域&#xff0c;对初学者而言&#xff0c;搭建一套清晰的基础认知体系是关键——唯有理清核心逻辑&#xff0c;才能明确学习方向、掌握实操路径&#xff0c;避免在繁杂概念中迷失。 随着大模型技术的普及&#xff0c;笔者在与同行、技术爱好…

WPF 事件机制与初始化流程深度解析

1. 关于 WPF 隧道和冒泡的学习,特别是 Initialized 事件不触发断点的问题 在学习 WPF 的隧道和冒泡事件时,编写了简单的 XAML 和 C# 代码,发现给 Initialized 事件打断点不会触发,即使添加了更多元素的 Initialize…

java+vue+SpringBoot学生网上选课系统(程序+数据库+报告+部署教程+答辩指导)

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿ppt部署教程代码讲解代码时间修改工具 技术实现 开发语言&#xff1a;后端&#xff1a;Java 前端&#xff1a;vue框架&#xff1a;springboot数据库&#xff1a;mysql 开发工具 JDK版本&#xff1a;JDK1.8 数…