
用 fetchMap 快速搭建 CARTO Builder 地图deck.gl 纯 JavaScript 示例实战【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl本文以 deck.gl 仓库中 examples/get-started/pure-js/carto 下的纯 JavaScript 示例为主线讲解如何仅用少量代码把 CARTO Builder 中设计好的地图图层、视角、底图配置拉取到浏览器端通过 deck.gl 渲染并与 MapLibre 底图联动。读完本文你将掌握fetchMap的完整参数与返回值语义、示例中「deck.gl 画布 MapLibre 底图」双容器同步的关键写法以及deck.gl/carto模块背后图层工厂的实现原理可以直接复用到自己的项目里。一、示例定位一个开箱即用的纯 JS CARTO 演示在 examples/get-started/pure-js/ 目录下deck.gl 为每种常见集成场景apple-maps、arcgis、globe、mapbox、maplibre、openlayers、widgets 等都准备了一个最小可运行的纯 JavaScript 示例本篇文章聚焦其中的carto子目录。它对应 CARTO 官方在 deck.gl 中的集成模块deck.gl/carto——即 docs/api-reference/carto/overview.md 中描述的「Deck.gl 是使用 CARTO Location Intelligence 平台构建现代地理空间 Web 应用的首选与官方方案」。该示例目录共包含 4 个文件职责非常清晰文件作用README.md示例说明与运行指引app.js核心逻辑fetchMap加载 Builder 地图 deck.gl/MapLibre 渲染index.html页面骨架底图容器与 deck.gl 画布的层叠布局package.json依赖声明与 Vite 启动脚本其核心思路一句话概括在 CARTO Builder 里可视化配置地图然后通过fetchMap({cartoMapId})把整张地图初始视角 图层 底图配置一次性拉回前端渲染无需在代码中逐层手写图层定义。二、快速运行三步跑起 Demo原 README.md 给出了最精简的运行方式将本目录内容复制到你的项目中然后执行yarn yarn start对照示例的 package.json可以看到该示例基于 Vite 搭建声明了以下脚本scripts: { start: vite --open, start-local: vite --config ../../../vite.config.local.mjs, build: vite build }yarn start以 Vite 启动开发服务器并自动打开浏览器yarn start-local使用仓库根目录的本地 Vite 配置examples/vite.config.local.mjs启动便于在 deck.gl 源码仓库内直接调试未发布的模块版本yarn build构建生产版本。依赖方面示例只声明了两个运行时依赖dependencies: { deck.gl: ^9.0.0, maplibre-gl: ^5.0.0 }deck.gl聚合包提供了deck.gl/coreDeck 实例与deck.gl/cartofetchMap等模块maplibre-gl则用于渲染 CARTO 返回的 MapLibre 风格底图。运行前需先通过yarn或npm install安装依赖。说明cartoMapId使用的是公开示例地图ff6ac53f-741a-49fb-b615-d040bc5a96b8因此无需配置 accessToken 即可直接运行若替换为自己的私有地图则需要补充认证信息详见第五节。三、逐行拆解 app.jsfetchMap 的核心用法示例的全部业务逻辑只有 20 余行位于 app.js。它演示了两种能力的组合用 deck.gl 渲染数据图层、用 MapLibre GL 渲染底图并保持二者视角同步。3.1 引入模块import maplibregl from maplibre-gl; import {Deck} from deck.gl/core; import {fetchMap} from deck.gl/carto;fetchMap是deck.gl/carto导出的核心函数见 modules/carto/src/index.ts 中export {fetchMap, LayerFactory} from ./api/fetch-map。它的作用是从 CARTO Maps API 读取一张 Builder 地图的描述信息并返回「开箱即用」的 deck.gl 图层数组。3.2 指定地图 ID 并拉取地图配置const cartoMapId ff6ac53f-741a-49fb-b615-d040bc5a96b8; // Get map info from CARTO and update deck fetchMap({cartoMapId}).then(({initialViewState, basemap, layers}) { // ... });fetchMap返回一个 Promise解构出的三个字段正是前端渲染所需的三块拼图initialViewStateBuilder 中保存的初始视角经度、纬度、缩放、倾斜、方位角basemap底图配置对象含typemaplibre或google-maps与propslayersBuilder 中配置的各数据图层对应的 deck.gl Layer 实例数组。3.3 创建 Deck 实例渲染数据图层const deck new Deck({canvas: deck-canvas, controller: true, initialViewState, layers});这里把initialViewState与layers直接传给Deck并将控制器开启controller: true用户即可通过鼠标拖拽、滚轮缩放来交互。canvas: deck-canvas指定了 deck.gl 写入 WebGL 内容的画布元素 id与 index.html 中的canvas iddeck-canvas对应。3.4 用 MapLibre 渲染底图// Add Mapbox GL for the basemap. Its not a requirement if you dont need a basemap. const map new maplibregl.Map({container: map, ...basemap?.props, interactive: false});basemap?.props展开后即 docs/api-reference/carto/fetch-map.md 中描述的 MapLibre 底图属性style底图样式 URL 或样式对象、center[latitude, longitude]、zoom、pitch、bearing。interactive: false表示底图本身不响应交互——交互统一由 deck.gl 接管示例注释也说明如果不需要底图这行完全可以省略。3.5 双向同步视角变化时让底图跟随deck.setProps({ onViewStateChange: ({viewState}) { const {longitude, latitude, ...rest} viewState; map.jumpTo({center: [longitude, latitude], ...rest}); } });由于交互发生在 deck.gl 一侧底图必须跟随 deck.gl 的视角变化。这里监听onViewStateChange回调把新viewState中的longitude、latitude拆出来作为center其余字段zoom、pitch、bearing等直接透传给map.jumpTo从而让 MapLibre 底图与 deck.gl 数据图层始终保持同一视角。jumpTo是瞬时跳转避免了过渡动画带来的累积延迟适合这种「外部底图 deck.gl 覆盖层」的同步场景。四、index.html画布与底图的层叠布局index.html 只做了一件事把两个同尺寸的全屏容器叠在一起让底图在下、deck.gl 画布在上。style #container { position: fixed; top: 0; left: 0; right: 0; bottom: 0; } #container * { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /style div idcontainer div idmap/div canvas iddeck-canvas/canvas /div#container铺满视口两个子元素#map与#deck-canvas绝对定位并各占 100% 宽高实现像素级对齐#map是 MapLibre 的挂载点#deck-canvas是 deck.gl 的 WebGL 画布canvas 自然覆盖在底图之上DOM 顺序靠后页面还通过link引入了maplibre-gl的 CSS保证底图控件与样式渲染正确。这种「分离容器」方案是 deck.gl 与外部底图集成的通用范式deck.gl 负责叠加在其上的 WebGL 图层底图库负责瓦片底图二者互不干扰、只通过视角状态通信。五、fetchMap从 Builder 地图到 deck.gl 图层fetchMap是整个示例的枢纽其完整 API 语义记录在 docs/api-reference/carto/fetch-map.md 中下面结合该文档与源码展开。5.1 参数一览const map await fetchMap({cartoMapId, credentials, autoRefresh, onNewData});参数类型必填说明cartoMapIdstring是在 CARTO Builder 中创建的地图标识符accessTokenstring否CARTO 平台访问令牌仅私有地图需要apiBaseUrlstring否CARTO Maps API 的基础 URL例如欧盟西区账户为https://gcp-eu-west1.api.carto.comheadersobject否地图实例化请求附带的自定义 HTTP 头autoRefreshnumber否数据自动刷新间隔秒提供时必须同时提供onNewDataonNewDataFunction否图层数据变化时触发的回调提供时必须同时提供autoRefresh5.2 返回值fetchMap解析出地图信息后会生成对应的 deck.gl 图层并填充数据返回对象包含idcartoMapId本身title/descriptionBuilder 中为地图设置的标题与描述createdAt/updatedAt地图创建与最后更新时间initialViewState视图状态对象见 docs/developer-guide/views.md 对 view state 的定义layersdeck.gl Layer 实例数组basemap底图描述对象type为maplibre或google-mapsprops为传给对应底图实现的属性MapLibre 场景下含style、center、zoom、pitch、bearingGoogle Maps 场景下含mapTypeId、mapId、center、zoom相对 deck.gl 有 1 偏移、tilt、heading另有rawStyle、visibleLayerGroups、attribution等字段stopAutoRefresh仅当传入autoRefresh时存在调用它可停止自动刷新。5.3 源码纵深图层工厂的映射关系从源码 modules/carto/src/api/fetch-map.ts 可以看到fetchMap实际上是carto/api-client同名函数的封装底层函数返回的是图层描述descriptor而deck.gl/carto的fetchMap通过LayerFactory把描述转换为可直接使用的 Layer 实例。const layerClasses: RecordLayerType, _ConstructorOfLayer { clusterTile: ClusterTileLayer, h3: H3TileLayer, heatmapTile: HeatmapTileLayer, mvt: VectorTileLayer, quadbin: QuadbinTileLayer, raster: RasterTileLayer, tileset: VectorTileLayer } as const; export function LayerFactory(descriptor: LayerDescriptor): Layer { const LayerClass layerClasses[descriptor.type]; if (!LayerClass) { throw new Error(No layer class found for type: ${descriptor.type}); } return new LayerClass(descriptor.props); }这段代码揭示了几点实现事实Builder 地图中的每种图层类型都对应deck.gl/carto的一个具体图层类映射关系是硬编码的clusterTile → ClusterTileLayer、mvt/tileset → VectorTileLayer、h3 → H3TileLayer、quadbin → QuadbinTileLayer、raster → RasterTileLayer、heatmapTile → HeatmapTileLayer遇到未知类型会直接抛出No layer class found for type: ...错误避免静默渲染失败源码注释还给出了进阶用法需要更细粒度控制时可以直接使用carto/api-client的fetchMap拿到图层描述再自行调用LayerFactory按需创建图层。另外fetchMap的onNewData回调在包装层同样经过createResult转换把描述数组映射为 Layer 实例保证回调收到的layers与顶层返回值类型一致。5.4 动态数据的自动刷新模式docs/api-reference/carto/fetch-map.md 还给出了针对动态数据源如实时更新的表的进阶用法传入autoRefresh让地图数据定时刷新并通过onNewData把新图层回填给 Deckconst deck new Deck({canvas: deck-canvas}); const mapConfiguration { autoRefresh: 5, cartoMapId, onNewData: ({layers}) { deck.setProps({layers}); } }; const {initialViewState, layers, stopAutoRefresh} await fetchMap(mapConfiguration); deck.setProps({controller: true, initialViewState, layers}); buttonElement.addEventListener(click, () { stopAutoRefresh(); });这样便得到一张每秒示例为每 5 秒自动拉取新数据、且随时可通过stopAutoRefresh()停止刷新的实时地图。本示例pure-js/carto只演示了静态展示如需实时能力可直接照搬该模式。六、CARTO 模块全景与进阶阅读fetchMap只是deck.gl/carto模块的入口之一。从 modules/carto/src/index.ts 的导出列表可以看到该模块的完整能力面CARTO 图层ClusterTileLayer、H3TileLayer、HeatmapTileLayer、PointLabelLayer、QuadbinTileLayer、RasterTileLayer、VectorTileLayer另有内部图层_QuadbinLayer、_RasterLayer、_SpatialIndexTileLayer数据源函数boundaryQuerySource、h3QuerySource、vectorQuerySource、quadbinTableSource、rasterSource等从carto/api-client再导出配合图层使用即可直连云数仓中的数据集样式辅助colorBins、colorCategories、colorContinuous等配色工具底图相关BASEMAP常量、fetchBasemapProps等。若想深入了解建议按如下路径阅读仓库docs/api-reference/carto/fetch-map.mdfetchMap的完整参数与返回值规范本文第五节内容的权威出处docs/api-reference/carto/overview.mdCARTO 平台与 deck.gl 集成的整体介绍包括安装命令npm install deck.gl或分模块安装deck.gl/core deck.gl/layers deck.gl/geo-layers deck.gl/carto与自定义图层/数据源示例docs/api-reference/carto/basemap.mdbasemap对象与支持的底图类型说明docs/api-reference/carto/data-sources.mdCARTO 数据源函数的认证accessToken与连接connectionName配置modules/carto/src/api/fetch-map.tsfetchMap与LayerFactory的实现源码。七、小结通过这个 20 余行的纯 JavaScript 示例可以看到 deck.gl CARTO 的典型集成链路Builder 可视化配置 →fetchMap拉取地图配置 → Deck 渲染数据图层 MapLibre 渲染底图 → 视角状态双向同步。示例中的cartoMapId是公开演示地图直接复制目录运行即可看到效果而当你需要接入自己的数据时只需替换为私有地图 ID并配置accessToken或更进一步使用autoRefresh实现实时刷新、使用vectorQuerySource等数据源函数直接对接云数仓从而把「配置地图」的成本降到最低。【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考