
deck.gl BitmapLayer 实战指南在地图上渲染位图、像素拾取与纹理控制【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.glBitmapLayer是 deck.gl 中用于在地图指定地理边界内渲染位图栅格图片的基础图层典型应用包括叠加卫星影像、街区分布底图、自定义栅格标注等。本文以官方 API 文档 bitmap-layer.md 为核心结合 bitmap-layer 源码 与 单元测试完整讲解其安装方式、全部配置属性、像素级拾取原理以及底层坐标转换机制读完后你可以直接用一行new BitmapLayer({...})将任意图片精确铺设在目标地理范围内。快速开始把一张图片贴到地图上BitmapLayer的核心思想很简单给定一张图片image和一个地理包围盒bounds图层自动把图片拉伸覆盖到该范围内。下面的 JavaScript 示例把一张旧金山区域图叠加到对应经纬度区域上import {Deck} from deck.gl/core; import {BitmapLayer} from deck.gl/layers; const layer new BitmapLayer({ id: BitmapLayer, bounds: [-122.519, 37.7045, -122.355, 37.829], image: https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-districts.png, pickable: true }); new Deck({ initialViewState: { longitude: -122.4, latitude: 37.74, zoom: 11 }, controller: true, getTooltip: ({bitmap}) bitmap ${bitmap.pixel}, layers: [layer] });TypeScript 版本额外导入了BitmapLayerPickingInfo类型用于给getTooltip回调提供精确的类型提示import {Deck} from deck.gl/core; import {BitmapLayer, BitmapLayerPickingInfo} from deck.gl/layers; const layer new BitmapLayer({ id: BitmapLayer, bounds: [-122.519, 37.7045, -122.355, 37.829], image: https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-districts.png, pickable: true }); new Deck({ initialViewState: { longitude: -122.4, latitude: 37.74, zoom: 11 }, controller: true, getTooltip: ({bitmap}: BitmapLayerPickingInfo) bitmap ${bitmap.pixel}, layers: [layer] });React 用法与上述基本一致通过deck.gl/react的DeckGL组件挂载图层import React from react; import {DeckGL} from deck.gl/react; import {BitmapLayer} from deck.gl/layers; import type {BitmapLayerPickingInfo} from deck.gl/layers; function App() { const layer new BitmapLayer({ id: BitmapLayer, bounds: [-122.519, 37.7045, -122.355, 37.829], image: https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-districts.png, pickable: true }); return DeckGL initialViewState{{ longitude: -122.4, latitude: 37.74, zoom: 11 }} controller getTooltip{({bitmap}: BitmapLayerPickingInfo) bitmap ${bitmap.pixel}} layers{[layer]} /; }网站文档中的交互式示例BitmapLayerDemo正是这个配置的演示定义在 website/src/doc-demos/layers.js其中getTooltip同样读取bitmap.pixel显示当前悬停像素坐标。安装与导入通过 npm 安装npm install deck.gl # 或按需安装核心与图层两个子包 npm install deck.gl/core deck.gl/layers随后导入图层类与类型import {BitmapLayer} from deck.gl/layers; import type {BitmapLayerProps, BitmapLayerPickingInfo} from deck.gl/layers; new BitmapLayer(...props: BitmapLayerProps);通过预打包脚本使用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此时全局变量deck下即可访问new deck.BitmapLayer({})。属性详解Data 数据类image要显示的图片类型string | Texture | Image | ImageData | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | Promise | object默认值nullimage支持以下输入形式字符串会被解释为 URL 或 Data URLdata:前缀的内联图片任意 WebGL2 纹理的合法像素源即texImage2D支持的像素类型如Image、ImageData、HTMLCanvasElement、HTMLVideoElement、ImageBitmap一个 luma.glTexture实例一个可传给Texture构造器的普通对象例如{width: number, height: number, data: Uint8Array}。注意当该对象发生浅比较变化时会创建新纹理以上任意一种的 Promise 形式。图片数据最终都会被转换为 luma.glTexture对象如需高级定制请配合textureParameters属性。在 源码 defaultProps 中该属性声明为{type: image, value: null, async: true}表明它是异步加载的image类型属性加载完成后图层会自动触发重绘加载期间拾取接口返回的bitmap字段为null。bounds图片对应的地理范围类型number[4] | Position[4]默认值[1, 0, 0, 1]支持两种格式包围盒坐标[left, bottom, right, top]例如[-122.519, 37.7045, -122.355, 37.829]四角坐标[[left, bottom], [left, top], [right, top], [right, bottom]]每个角点可带第三个分量z构成三维坐标。语义说明left/right对应图片左右两侧的世界经度或 xtop/bottom对应图片上下两侧的世界纬度或 y。测试 bitmap-layer.spec.ts 验证了二维包围盒与带z的四角坐标都能正确生成positions顶点属性例如[2,4,1, 2,8,1, 16,8,1, 16,4,1]这样的 Float32Array。从源码看_createMesh()会先把包围盒格式归一化为四角格式再交给 create-mesh.ts 生成网格未指定网格分辨率时使用单四边形4 个顶点、6 个索引纹理坐标固定为[0,1, 0,0, 1,0, 1,1]指定分辨率时来自context.viewport.resolution按分辨率将四边形细分为uCount × vCount的网格顶点按双线性插值interpolateQuad计算可让大范围图片贴合投影曲面如 Globe 视图。loadOptions加载选项类型object可选在核心图层的默认加载选项之外当image为 URL 时还接受 loaders.gl 的ImageLoader选项用于控制图片的加载行为如跨域设置、解码优先级等。textureParameters纹理采样参数类型object默认值null用于定制 luma.gl 的纹理采样器参数。若不指定图层默认使用以下参数创建线性平滑纹理{ minFilter: linear, magFilter: linear, mipmapFilter: linear, addressModeU: clamp-to-edge, addressModeV: clamp-to-edge }例如去掉平滑、实现像素风马赛克效果可将过滤方式改为最近邻new BitmapLayer({ // ... textureParameters: { minFilter: nearest, magFilter: nearest } })注意该属性仅在image首次加载或更换时生效。源码中它被标记为{type: object, ignore: true, value: null}即不参与属性 diff 的浅比较这也印证了“只有图片变化时才重建纹理”的行为。_imageCoordinateSystem图像坐标系的解释方式实验性类型string默认值default注意该属性为实验性 API命名以下划线开头。默认情况下图片被均匀拉伸以填满bounds定义的几何范围。但若图片编码所用坐标系与图层当前投影不一致这种线性解释就不正确了——例如一张按经纬度编码的全球卫星影像在 Web Mercator 可视化中不应被线性解释。该属性允许你显式告知图层图片的坐标系default使用图层默认的图像解释方式lnglatx 轴映射经度、y 轴映射纬度cartesian图片已预投影到 Web Mercator 平面。此选项仅适用于地理空间视图且bounds必须为正交格式[left, bottom, right, top]。若配合四角格式使用源码会直接抛出Error(_imageCoordinateSystem only supports rectangular bounds)见 bitmap-layer.ts。相关坐标系背景可参考 坐标系统指南。底层转换原理源码通过coordinateConversion标志实现三种模式——0表示无需转换默认纹理坐标直接线性插值-1表示图片是经纬度编码、视图为 Web Mercator片元着色器会把像素位置反投影回经纬度后再采样见 bitmap-layer-fragment.ts 中的mercator_to_lnglat1表示图片是 Web Mercator 编码而视图为经纬度如 Globe此时顶点被lngLatToWorld换算成 Mercator 平面坐标。测试 imageCoordinateSystem 针对 MapView 与 GlobeViewport 分别验证了这三种转换值及生成的新 bounds例如 Globe 视图下 CARTESIAN 图像得到[256, 211.24, 320, 256]的 Mercator 坐标边界。属性详解Render Options 渲染类以下三个属性均支持过渡动画transition-enabled。desaturate去饱和度类型number默认值0取值范围[0, 1]0为原色1为完全灰度。对应片元着色器中的color_desaturate先求 RGB 均值作为亮度再用mix(color, luminance, desaturate)混合见 bitmap-layer-fragment.ts。在 WebGPU 的 WGSL 着色器 中有完全相同的实现。transparentColor透明像素的替代色类型Color即[r, g, b, a]各分量范围[0, 255]默认值[0, 0, 0, 0]相当于把图片叠加在指定颜色背景上用于处理图片的透明区域。源码注释说明由于地面影像的混合模式alpha 在透明区域与底图混合时并不生效因此需要手动将 RGB 与背景色混合。着色器中的apply_opacity实现了标准的 alpha 混合公式blendedAlpha alpha bgAlpha * (1 - alpha)并反算出前景占比见 bitmap-layer-fragment.ts。tintColor着色染色类型Color即[r, g, b]各分量范围[0, 255]默认值[255, 255, 255]白色即不改变颜色对位图进行乘法染色例如传入偏蓝色调可实现“夜间模式”底图效果。着色器实现为逐通道相乘color * tintColor且传入 uniform 前会除以 255 归一化见 bitmap-layer.ts。三个渲染属性的处理顺序在片元着色器中固定为去饱和 → 染色 → 与背景色混合 → 乘以图层 opacity最终输出fragColor见 bitmap-layer-fragment.ts。像素级拾取Pixel Picking与常规图层返回“对象索引”不同BitmapLayer的拾取返回的是被点击图片像素的位置。在 getPickingInfo 中图层利用片元着色器把 UV 坐标编码进拾取颜色将 u、v 的高 8 位放入 R、G 通道低 4 位余数打包进 B 通道见packUVsIntoRGBbitmap-layer-fragment.ts因此可精确寻址 4096×4096 的像素拾取时再通过unpackUVsFromRGB逆向解码出 UV进而算出像素坐标。回调onHover、onClick等收到的 picking info 会额外携带bitmap字段bitmappixel[x: number, y: number]位图中的整数像素坐标size{width: number; height: number}位图的像素尺寸uv[u: number, v: number]归一化0-1浮点坐标。需要说明鼠标离开图层或位图尚未加载完成时bitmap字段为null使用前务必判空。下面的代码演示点击图层时直接读取被点击像素的颜色值new BitmapLayer({ image: ./my-image.png, bounds: [-122.45, 37.75, -122.43, 37.78], pickable: true, onClick: ({bitmap, layer}) { if (bitmap) { const {device} layer.context; const pixelColor device.readPixelsToArrayWebGL(layer.props.image, { sourceX: bitmap.pixel[0], sourceY: bitmap.pixel[1], sourceWidth: 1, sourceHeight: 1 }); console.log(Color at picked pixel:, pixelColor); } } })单元测试 BitmapLayer#picking 验证了拾取正确性对 8×8 的Uint8Array图片进行 hover拾取颜色[64, 32, 0]解码后得到uv: [0.25, 0.125]、pixel: [2, 1]与预期完全一致。测试同时验证了autoHighlight下高亮颜色会被编码为[1, 0, 0]这是因为该图层不使用实例索引拾取颜色统一取自常量vec3(1.0, 0.0, 0.0)见 bitmap-layer-vertex.ts。深入从属性到渲染的完整链路了解源码结构有助于你排查问题或扩展功能相关实现全部位于 modules/layers/src/bitmap-layer/bitmap-layer.ts图层主类。定义defaultProps、注册positions/texCoords/indices三个顶点属性其中positions为float64类型以支持 64 位精度、负责网格重建与拾取解码create-mesh.ts根据bounds生成四边形或细分网格的顶点、索引与纹理坐标bitmap-layer-vertex.ts / bitmap-layer-fragment.tsWebGL2GLSL ES 300顶点与片元着色器实现坐标转换、去饱和、染色、背景混合与 UV 拾取编码bitmap-layer.wgsl.ts与 GLSL 对等的 WebGPUWGSL着色器说明该图层已原生支持 WebGPU 渲染路径bitmap-layer-uniforms.ts声明bitmap统一块bounds、coordinateConversion、desaturate、tintColor、transparentColor同一份数据同时供 GLSL 与 WGSL 使用。渲染调用链为updateState检测到bounds变化时重建网格并失效对应属性 →draw阶段把tintColor、transparentColor归一化后通过model.shaderInputs.setProps({bitmap})写入 uniform → 执行一次model.draw()。图层以topology: triangle-list、isInstanced: false的非实例化方式绘制单个网格见 bitmap-layer.ts。适用场景与注意事项典型用途卫星/航拍影像叠加、行政区划底图、自定义栅格标注、视频纹理image支持HTMLVideoElement等一切“把图片钉在地图上”的需求image为异步加载图层加载完成前bitmap拾取字段为null且纹理变化只在首次加载或更换图片时生效想要像素级精确拾取务必设置pickable: true并在回调中先对bitmap判空大范围覆盖如全球影像建议显式配合_imageCoordinateSystem与正确的bounds格式并参考 坐标系统指南 理解投影差异若追求像素风或需要清晰放大可通过textureParameters将过滤方式改为nearest。如需继续深入可阅读核心图层通用属性的官方文档 layer.md或在仓库中搜索BitmapLayer的其他引用如 GeoJsonLayer 对位图图层的组合用法以了解其在复合场景中的应用。【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考