尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

deck.gl TileLayer 完全指南:视口驱动的海量瓦片数据按需加载与渲染

deck.gl TileLayer 完全指南:视口驱动的海量瓦片数据按需加载与渲染 deck.gl TileLayer 完全指南视口驱动的海量瓦片数据按需加载与渲染【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.glTileLayer是 deck.gl 地理图层geo-layers模块中的核心复合层composite layer它让 WebGL2 可视化框架能够在不加载完整数据集的前提下以按需切片的方式渲染海量数据仅获取并绘制当前视口可见的瓦片tile其余数据保持待命。本文将以 tile-layer.md 为主线结合modules/geo-layers/src/tile-layer与modules/geo-layers/src/tileset-2d的源码实现完整讲解 TileLayer 的索引体系、全部配置属性、自定义索引方案以及背后的请求调度、缓存与视觉保真机制帮助读者从能跑通示例进阶到能按业务定制瓦片方案。TileLayer 是什么为超大数据集而生的按需渲染层TileLayer解决的问题非常具体传统图层需要一次性把整个数据集交给 GPU当数据量达到百万、千万级别或者数据本身分布在网络上的无数个文件中时全量加载既不现实也不经济。它的思路是把数据按瓦片tile切分——每个瓦片拥有预定义的包围盒bounding box和细节层级level of detail图层只加载并渲染当前视口真正覆盖到的那些瓦片。在 deck.gl 中TileLayer是一个复合层CompositeLayer子类其核心文件位于 modules/geo-layers/src/tile-layer/tile-layer.tsexport default class TileLayerDataT any, ExtraPropsT extends {} {} extends CompositeLayer ExtraPropsT Required_TileLayerPropsDataT { static defaultProps: DefaultProps defaultProps; static layerName TileLayer; ... }它自身并不绘制任何图形而是完成三件事判定瓦片集合根据当前 viewport计算出应该加载哪些{x, y, z}索引的瓦片获取瓦片数据通过data的 URL 模板或自定义的getTileData回调获取每个瓦片的内容渲染子层把已加载的瓦片内容交给renderSubLayers返回的图层默认是GeoJsonLayer来绘制。这种数据不落地、视口决定一切的架构正是构建 OSM 底图、矢量切片、栅格影像、3D 建筑物等场景的基础。安装与导入TileLayer 随deck.gl/geo-layers包发布同时依赖deck.gl/core与deck.gl/layers默认渲染子层GeoJsonLayer来自 layersnpm install deck.gl # 或按需拆分安装 npm install deck.gl/core deck.gl/layers deck.gl/geo-layers模块化导入TypeScript 类型import {TileLayer} from deck.gl/geo-layers; import type {TileLayerProps, TileLayerPickingInfo} from deck.gl/geo-layers; new TileLayerTileDataT(...props: TileLayerPropsTileDataT[]);预打包脚本方式script srchttps://unpkg.com/deck.gl^9.0.0/dist.min.js/script !-- 或 -- script srchttps://unpkg.com/deck.gl/core^9.0.0/dist.min.js/script script srchttps://unpkg.com/deck.gl/layers^9.0.0/dist.min.js/script script srchttps://unpkg.com/deck.gl/geo-layers^9.0.0/dist.min.js/scriptnew deck.TileLayer({});快速上手用 OSM 瓦片渲染一幅地图底图官方示例用 OSM 标准瓦片服务演示了 TileLayer 的最小可用配置。data使用 URL 模板{z}、{x}、{y}会在请求时被替换为实际瓦片索引renderSubLayers中通过props.tile.boundingBox将每个瓦片映射为一个BitmapLayer。JavaScriptimport {Deck} from deck.gl/core; import {TileLayer} from deck.gl/geo-layers; import {BitmapLayer} from deck.gl/layers; const layer new TileLayer({ id: TileLayer, data: https://c.tile.openstreetmap.org/{z}/{x}/{y}.png, maxZoom: 19, minZoom: 0, renderSubLayers: props { const {boundingBox} props.tile; return new BitmapLayer(props, { data: null, image: props.data, bounds: [boundingBox[0][0], boundingBox[0][1], boundingBox[1][0], boundingBox[1][1]] }); }, pickable: true }); new Deck({ initialViewState: { longitude: -122.4, latitude: 37.74, zoom: 11 }, controller: true, getTooltip: ({tile}) tile x:${tile.index.x}, y:${tile.index.y}, z:${tile.index.z}, layers: [layer] });TypeScript 版本仅需额外引入TileLayerPickingInfo类型import {Deck} from deck.gl/core; import {TileLayer, TileLayerPickingInfo} from deck.gl/geo-layers; import {BitmapLayer} from deck.gl/layers; const layer new TileLayer({ id: TileLayer, data: https://c.tile.openstreetmap.org/{z}/{x}/{y}.png, maxZoom: 19, minZoom: 0, renderSubLayers: props { const {boundingBox} props.tile; return new BitmapLayer(props, { data: null, image: props.data, bounds: [boundingBox[0][0], boundingBox[0][1], boundingBox[1][0], boundingBox[1][1]] }); }, pickable: true }); new Deck({ initialViewState: { longitude: -122.4, latitude: 37.74, zoom: 11 }, controller: true, getTooltip: ({tile}: TileLayerPickingInfo) tile x:${tile.index.x}, y:${tile.index.y}, z:${tile.index.z}, layers: [layer] });React 写法deck.gl/react的DeckGL组件 getTooltip回调import React from react; import {DeckGL} from deck.gl/react; import {TileLayer} from deck.gl/geo-layers; import {BitmapLayer} from deck.gl/layers; import type {TileLayerPickingInfo} from deck.gl/geo-layers; function App() { const layer new TileLayer({ id: TileLayer, data: https://c.tile.openstreetmap.org/{z}/{x}/{y}.png, maxZoom: 19, minZoom: 0, renderSubLayers: props { const {boundingBox} props.tile; return new BitmapLayer(props, { data: null, image: props.data, bounds: [boundingBox[0][0], boundingBox[0][1], boundingBox[1][0], boundingBox[1][1]] }); }, pickable: true }); return DeckGL initialViewState{{ longitude: -122.4, latitude: 37.74, zoom: 11 }} controller getTooltip{({tile}: TileLayerPickingInfo) tile x:${tile.index.x}, y:${tile.index.y}, z:${tile.index.z}} layers{[layer]} /; }值得注意的细节示例中的getTooltip直接读取了tile.index说明在 picking 命中时TileLayer 会把命中的瓦片信息注入到PickingInfo中详见下文拾取Picking一节这对于按瓦片做数据下钻、调试非常有用。索引系统{x}/{y}/{z} 是如何确定的地理视图OSM 瓦片编号在每一个整数缩放层级z上视图空间的 XY 平面被划分为大小相同的正方形瓦片每块瓦片由唯一的x、y索引标识。z每增加 1视图空间放大 2 倍——z层级的一块瓦片恰好覆盖z1层级的四块瓦片。当TileLayer与地理视图如 MapView配合使用时x、y、z依据标准的 OSM 瓦片编号体系Slippy map tilenames确定。底层实现位于 modules/geo-layers/src/tileset-2d/tile-2d-traversal.ts 的getOSMTileIndices以OSMNode(0, 0, 0)为根节点构造视口平截头体的剔除体culling volume对每个节点计算包围体getBoundingVolume先用bounds即extent属性做范围裁剪再用cullingVolume.computeVisibility做视锥剔除依据相机距离进行 LOD 判定z Math.floor(Math.log2(distance))tile-2d-traversal.ts当层级达到maxZoom或距离足够远时停止细分并标记为选中否则递归进入四个子节点对全球视图GlobeViewport还会额外用beyondHorizon剔除被近半球遮挡的瓦片并对重复世界subViewports做多份偏移检测MAX_MAPS 3。同时utils.ts 中的osmTile2lngLat提供了从 OSM 瓦片坐标到经纬度的换算供包围盒计算使用。非地理视图世界原点起算当TileLayer与 OrthographicView 或 OrbitView 这类非地理视图配合时x、y从世界原点开始递增每个瓦片的宽高等于tileSize属性的值。例如x: 0, y: 0的瓦片占据[0, 0]到[tileSize, tileSize]的正方形区域。从源码看非地理视图走的是 utils.ts 的getIdentityTileIndices分支用Math.floor(min)到max的双重循环直接枚举覆盖视口包围盒的瓦片索引并在getTileIndices入口处统一决定取层级的策略let z viewport.isGeospatial ? Math.round(viewport.zoom Math.log2(TILE_SIZE / tileSize) zoomOffset) : Math.ceil(viewport.zoom zoomOffset);源码注释特别指出utils.tsMath.round是为了与 Google Maps、MapLibre 等保持一致——例如viewport.zoom 9.5时应该取z 10而非z 9。zoomOffset提前取更清晰的分辨率如果需要错位取瓦片——例如希望在当前视角下取更高一级分辨率的瓦片以获得更清晰的画面可以使用zoomOffset属性必须为整数默认0。它会整体平移上述公式中的z取值而不改变视口的实际缩放。Properties 全解析TileLayer继承 base Layer 的全部属性若使用默认的renderSubLayers即GeoJsonLayer则还支持 GeoJSONLayer 的全部样式属性。以下分类讲解其自有属性默认值均可在 tile-layer.ts 的defaultProps中找到对应声明。Data Options数据选项datastring | string[]可选默认值[]URL 模板或 URL 模板数组。字符串形式中{x}、{y}、{z}子串会在请求时被替换为实际瓦片索引。数组形式用于域分片domain sharding每个端点对同一瓦片索引必须返回相同内容浏览器借此并发下载更多资源请求会基于瓦片索引在端点间负载均衡。底层实现见 utils.ts 的getURLFromTemplate数组场景下先用stringHash(id) % template.length选择一个模板再逐个替换{key}此外还向后兼容支持{-y}占位符Math.pow(2, z) - y - 1方便接入某些坐标系 y 轴翻转的瓦片服务。isURLTemplate函数utils.ts则用于校验模板是否包含{z}、{x}与{y}/{-y}。getTileDataFunction可选默认值tile load(tile.url)自定义瓦片数据获取函数接收一个tile参数包含以下字段字段类型说明indexobject瓦片索引形如{x, y, z}的整数值idstring索引的唯一字符串表示urlstring若提供了data属性则为解析后的瓦片 URL否则为nullbboxobject瓦片包围盒。地理视图下为{west, north, east, south}经纬度非地理视图下为{left, top, right, bottom}signalobject一个 [AbortSignal]当排队请求过多时可能被触发中止。注意只有不可见的瓦片才会被中止它应返回瓦片数据或解析为该数据的 Promise。若data指向受支持的格式默认支持 JSON 与图片则此属性非必需可通过注册 loaders.gl 模块扩展更多格式。中止信号的使用规范强烈建议把signal传给任何fetch调用并在做昂贵计算前检查其aborted属性。若signal已中止应从getTileData抛出错误或返回 falsy 值避免缓存不完整数据反之若中止后仍返回 truthy 响应该数据会被缓存。getTileData: ({url, signal}) { const data fetch(url, {signal}); if (signal.aborted) { return null; } // Expensive computation on returned data }从源码看TileLayer 默认的getTileDatatile-layer.ts会先根据data模板解析出tile.url再按getTileData→ 内置fetch→null的优先级决定数据来源。TilesetClassclass可选默认值Tileset2D瓦片索引所用的 tileset 类。继承并扩展Tileset2D可实现自定义索引方案如 quadkey、geohash、H3 等具体见下文Tileset2D 与自定义索引方案。tileSizenumber可选默认值512瓦片的像素尺寸通常为 2 的幂。地理视图中它表示每个瓦片渲染时的目标像素宽高值越小内容显示分辨率越高但填充同一视口需要加载的瓦片数也越多。非地理视图中tileSize应等于瓦片的真实像素尺寸。zoomOffsetnumber可选默认值0取瓦片时对z层级的偏移量必须是整数。参见上文索引系统。maxZoomnumber | null可选默认值null数据存在的最大缩放层级。当视口被过度放大zoom maxZoom时仍显示该层级的瓦片放大模糊由渲染层处理。从源码看tile-2d-traversal.tsz达到maxZoom即停止递归细分。minZoomnumber可选默认值0数据存在的最小缩放层级。当视口过度缩小zoom minZoom时除非定义了extent否则图层不显示任何瓦片以避免发出过多瓦片请求。源码中utils.tsz minZoom且无extent时直接返回空数组有extent时把z钳制到minZoom。visibleMinZoom/visibleMaxZoomnumber | null可选默认值null瓦片可见的缩放范围与minZoom/maxZoom控制瓦片获取相互独立。当视口 zoom 低于visibleMinZoom或高于visibleMaxZoom时不渲染任何瓦片。源码中utils.ts直接返回空数组。extentnumber[4]可选默认值null图层数据的包围盒形如[minX, minY, maxX, maxY]。提供后图层只加载并渲染填充该包围盒所需的瓦片——这正是数据源只覆盖局部区域如单城市、单省份时的关键配置。maxCacheSizenumber可选默认值null瓦片缓存的最大数量。缓存让已加载瓦片在不可见后仍驻留内存减少用户平移/缩放时反复下载同一数据带来更平滑的体验。若未提供则按当前视口瓦片数的 5 倍计算。源码中的实现位于 tileset-2d.ts 的_resizeCacheconst maxCacheSize opts.maxCacheSize ?? (opts.maxCacheByteSize ! null ? Infinity : DEFAULT_CACHE_SCALE * this.selectedTiles.length);其中DEFAULT_CACHE_SCALE 5tileset-2d.ts。缓存超限时会按顺序驱逐不可见且未选中的瓦片并触发onTileUnload。maxCacheByteSizenumber可选默认值null用于缓存瓦片的最大内存字节数。若设置此限制getTileData返回的对象必须包含byteLength字段Tile2DHeader.byteLength会读取该字段并据此统计缓存占用见 tile-2d-header.ts。未设置时视为Infinity。注意一旦启用字节限制maxCacheSize的5 倍视口兜底逻辑会退化为Infinity见上段源码即只按字节数驱逐。refinementStrategystring | Function可选默认值best-available图层细化瓦片可见性的策略。缩放过程中如果只显示当前层级的瓦片新数据加载期间会出现不愉快的闪烁。通过该属性图层可在数据就绪前用其它层级的缓存内容维持视觉连续best-available当前视口内的瓦片若在等待加载用最近层级的缓存内容填充空白最大程度减少因内容缺失造成的闪烁no-overlap回填缓存内容时避免瓦片重叠适合瓦片背景不透明会遮挡下层的场景never不显示任何未选中的瓦片等价于tile.isVisible tile.isSelected自定义函数见下。三种内置策略在 tileset-2d.ts 中有完整实现updateTileStateDefaultbest-available为每个选中且尚未加载的瓦片先在祖先链中找已加载的占位瓦片getPlaceholderInAncestors逐级向上直到minZoom找不到则递归下探子节点getPlaceholderInChildrenupdateTileStateReplaceno-overlap先统一向上找祖先占位再按zoom升序处理显式隐藏被占位瓦片覆盖的全部子瓦片避免重叠updateTileStateNevernever空操作仅保留选中瓦片可见。自定义策略应用可提供自己的回调函数它会在每次视口更新与瓦片加载事件时被调用收到一个包含缓存中所有 Tile 实例的数组。回调中可以修改tile.isVisible初始值等于isSelected即never行为随后子层才渲染。maxRequestsnumber可选默认值6并发getTileData调用的最大数量。若 0不节流getTileData可无限并发无论瓦片可见多久若 0最多并发maxRequests个调用。未可见足够长时间而未被调度启动的请求可能永远不会发出当并发超限且其中一些属于不再可见的瓦片时请求可能通过getTileData收到的signal被中止排队时离视口中心更近的瓦片优先调度。针对 HTTP/1 服务器maxRequests应对应浏览器最大并发fetch数Chrome 每域 6。data指定多个域名即可提高该上限例如 3 个域名时 Chrome 下可设maxRequests18。若服务器支持 HTTP/2Chrome DevTools 的 Protocol 列显示 h2可设maxRequests-1无限并发——但请注意这会为每个瓦片都发请求无论其可见时长可能增加服务器负载。请求调度的底层是 loaders.gl 的RequestScheduler在 tileset-2d.ts 中构造throttleRequests在maxRequests 0 || debounceTime 0时启用。优先级由_getRequestPrioritytileset-2d.ts决定选中瓦片优先SELECTED_TILE_PRIORITY 0可见未选中次之VISIBLE_TILE_PRIORITY 1e8且同档内按到视口中心的屏幕距离排序_pruneRequeststileset-2d.ts会在超限时逐个 abort 未选中的进行中请求。debounceTimenumber可选默认值0瓦片请求的防抖毫秒数直到debounceTime毫秒内没有新瓦片加入队列才批量发出请求。debounceTime 0在maxRequests并发限制内尽快发出请求debounceTime 0交互式视角过渡期间可能减少带宽占用和总加载时间。Render Options渲染选项renderSubLayersFunction可选默认值props new GeoJsonLayer(props)渲染一个或多个 Layer 实例接收全部TileLayerprops 以及以下附加 props字段说明id子层的唯一 iddata由getTileData解析得到的数据deck.gl 8.2 起始终是 Promise 解析后的数据不再是 Promise 本身tile对应的 Tile 实例以下子层 props 会被 TileLayer 内部覆盖visible按瓦片可见性切换highlightedObjectIndex基于父层的高亮状态设置子层实例会被缓存在tile.layers中见 tile-layer.ts 的renderLayers只有未缓存时才调用renderSubLayers并通过flatten展平然后用layer.clone({tile, ...subLayerProps})注入瓦片引用数据加载完成_onTileLoad或出错_onTileError后都会把tile.layers置空并触发重渲染。zRangenumber[2]可选默认值null视为[0, 0]瓦片内容的高度范围[minZ, maxZ]专为 2.5D 内容如建筑物、地形设计。在高俯仰角下这类瓦片可能在其 2D 包围盒已离开视口时仍伸入视口因此需要提供额外信息让图层正确工作。该值有两个用途1判定需要加载/渲染的瓦片2判定拾取时可能相交的瓦片。该属性目前仅在地理视图下生效。源码中zRange会传入getOSMTileIndices把米制高度换算为 common spaceunitsPerMeter[2]后作为包围体的 Z 轴范围参与视锥剔除与拾取计算tile-2d-traversal.ts。modelMatrixMatrix4可选默认值null同时影响渲染与瓦片获取产生一个被变换的瓦片图层。注意若modelMatrix定义了旋转等变换可能导致瓦片在extent之外被获取。Tileset2D会维护矩阵及其逆矩阵_modelMatrixInversetileset-2d.ts并在非地理视图下用transformBoxutils.ts对extent做逆变换后再计算瓦片索引渲染阶段的filterSubLayer也会用modelMatrix变换瓦片包围盒做屏幕空间剔除tile-layer.ts。Callbacks回调onViewportLoadFunction可选默认值data null当前视口内所有瓦片加载完成时调用参数为已加载 Tile 实例数组。源码中tile-layer.ts它在 tileset 的加载状态从 false 变 true 或帧号变化时被触发参数是tileset.selectedTiles。onTileLoadFunction可选默认值() {}单个瓦片成功加载时调用参数为已加载的 tile。内部实现tile-layer.ts在回调后会清空tile.layers并触发重渲染。onTileErrorFunction可选默认值console.error瓦片加载失败时调用参数为errorError。从源码看即便加载失败瓦片请求本身也会被标记为已结束_isLoaded truecontent 为null保证onViewportLoad不会因为 404/空内容而永久等待见 tile-2d-header.ts 的注释说明。onTileUnloadFunction可选默认值() {}瓦片被清出缓存时调用参数为被清除的 tile。它由Tileset2D._resizeCache在驱逐瓦片时触发tileset-2d.ts。Tile 类单个瓦片的状态容器Tile源码中为Tile2DHeader见 modules/geo-layers/src/tileset-2d/tile-2d-header.ts用于承载单个瓦片的读取状态具有以下属性属性说明index瓦片索引{x, y, z}id索引的唯一字符串形如x-y-z例如0-2-3boundingBox瓦片包围盒形如[[minX, minY], [maxX, maxY]]content瓦片的缓存内容初始加载未完成、被取消或出错时为nulldata瓦片的请求内容加载中时返回一个 Promise完成后解析为加载内容parent缓存中存在时最近的祖先瓦片更低z且包含本瓦片的瓦片children缓存中存在时最近的子瓦片更高z且被本瓦片包含的瓦片isSelected该瓦片是否预期出现在当前视口isVisible该瓦片是否应被渲染isLoaded该瓦片内容是否已加载瓦片的加载生命周期由loadData管理tile-2d-header.ts先通过RequestScheduler.scheduleRequest排队拿到调度令牌后调用getData({index, id, bbox, userData, zoom, signal})并通过loaderId保证过期请求的结果被丢弃。abort()会置_isCancelled并触发AbortController同时确保已加载瓦片不被误中止。Tileset2D 与自定义索引方案Tileset2Dmodules/geo-layers/src/tileset-2d/tileset-2d.ts是负责瓦片数据加载与清理的管理类它缓存最近访问的瓦片只在瓦片首次出现时创建新实例并维护瓦片间的父子树_rebuildTree通过_getNearestAncestor链接祖先。其update方法tileset-2d.ts是每次视口变化的核心入口比较视口/zRange/modelMatrix重新计算getTileIndices→ 生成选中瓦片 → 更新各瓦片状态updateTileStates应用 refinement 策略→ 裁剪请求 → 必要时收缩缓存。要实现自定义索引方案如 quadkey、geohash 等继承Tileset2D并实现以下接口方法职责getTileIndices({viewport, maxZoom, minZoom, zRange, modelMatrix, modelMatrixInverse})返回给定视口下的索引数组。索引应为对象形态如{q: 0123}以便在data的 URL 模板中被引用getTileId(index)返回瓦片索引的唯一字符串键getParentIndex(index)返回父瓦片的索引getTileZoom(index)返回瓦片索引对应的缩放层级getTileMetadata(index)返回附加到瓦片上的元数据官方文档给出了用 quadkeyBing 地图瓦片体系索引的完整示例。quadkey 与 OSM 瓦片共享网格布局因此可以复用内置的 OSM 索引算法仅做索引转换import {_Tileset2D as Tileset2D} from deck.gl/geo-layers; class QuadkeyTileset2D extends Tileset2D { getTileIndices(opts) { // Quadkeys and OSM tiles share the layout, leverage existing algorithm // Data format: [{quadkey: 0120}, {quadkey: 0121}, {quadkey: 0120},...] return super.getTileIndices(opts).map(tileToQuadkey); } getTileId({quadkey}) { return quadkey; } getTileZoom({quadkey}) { return quadkey.length; } getParentIndex({quadkey}) { const quadkey quadkey.slice(0, -1); return {quadkey}; } } const quadkeyTileLayer new TileLayer({ TilesetClass: QuadkeyTileset2D, data: quadkey/{quadkey}.json, ... });注意 URL 模板中的占位符也要同步改成{quadkey}——因为getURLFromTemplate会遍历tile.index的所有键做替换utils.ts。Tileset2D通过deck.gl/geo-layers的私有导出_Tileset2D对外提供相关导出见 modules/geo-layers/src/tileset-2d/index.ts。进阶原理请求、缓存与拾取加载状态机与视口加载判定TileLayer.isLoaded的定义tile-layer.ts值得细读它要求所有选中瓦片isLoaded且对每个瓦片要么content为空错误/空瓦片已经尘埃落定要么其缓存的子层全部isLoaded——这是onViewportLoad能可靠触发的关键。屏幕空间剔除CullingTileLayer 通过filterSubLayertile-layer.ts实现屏幕空间剔除对每个瓦片调用tileset.isTileVisible(tile, cullRect, modelMatrix)tileset-2d.ts用getCullBounds将剔除矩形反投影到世界坐标后与瓦片 bbox 做相交检测地理视图按west/east/south/north比较非地理视图处理 y 轴翻转后比较并支持 modelMatrix 变换后的包围盒。这保证了大俯仰角下部分进入视口的瓦片也能被正确渲染。拾取PickinggetPickingInfotile-layer.ts把命中信息包装为TileLayerPickingInfotile被拾取的瓦片仅命中时存在sourceTile发出拾取事件的瓦片sourceTileSubLayer发出拾取事件的子层实例。这就是快速上手示例中getTooltip能直接拿到tile.index的原因。高亮处理则委托给sourceTileSubLayer.updateAutoHighlighttile-layer.ts。测试覆盖TileLayer 有专门的单元测试 test/modules/geo-layers/tile-layer/tile-layer.spec.ts覆盖默认配置下子层数量与加载状态断言、自定义getTileData与renderSubLayers单层与嵌套多子层、不同 WebMercatorViewport 视口下瓦片选取等场景可作为理解属性行为与验证自定义方案的参考。小结TileLayer的价值在于把海量数据渲染问题转化为视口驱动的瓦片调度问题data模板与getTileData决定数据从哪来Tileset2D及其子类决定如何索引与缓存refinementStrategy决定加载间隙的视觉连续性maxRequests/debounceTime决定网络压力而renderSubLayers决定最终呈现。无论是渲染 OSM 底图、矢量瓦片、栅格影像还是用 quadkey/geohash 等自定义索引承载业务数据理解本文涉及的属性语义与源码实现都能帮助你写出更流畅、更可控的瓦片可视化应用。【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表