MapLibre GL JS加载ArcGis Terrain3D地形

#MapLibre GL JS加载ArcGis Terrain3D地形#

很惭愧代码基本由Google Gemini生成,生成的原始代码在转换上有些错误,我给了提示它给出了修复代码片段。我将代码片段替换到原始代码去,一切工作正常。仅此而已!我甚至不知道以后没有AI助手我还能不能继续写代码。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8" />
    <title>MapLibre GL 加载arcgis terrain3D</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <link href="https://unpkg.com/maplibre-gl@5.16.0/dist/maplibre-gl.css" rel="stylesheet" />
    <script src="https://unpkg.com/maplibre-gl@5.16.0/dist/maplibre-gl.js"></script>
    <script type="text/javascript" src="https://unpkg.com/lerc@latest/LercDecode.min.js"></script>
    <style>
        body { margin: 0; padding: 0; }
        #map { position: absolute; top: 0; bottom: 0; width: 100%; }
        .controls {
            position: absolute;
            top: 10px;
            left: 10px;
            z-index: 1;
            background: white;
            padding: 10px;
            border-radius: 4px;
            box-shadow: 0 0 10px rgba(0,0,0,0.2);
            font-family: sans-serif;
        }
    </style>
</head>
<body>

<div id="map"></div>
<div class="controls">
    <strong>MapLibre GL 加载arcgis terrain3D</strong><br>
    Google Gemini生成代码
</div>

<script>
    const map = new maplibregl.Map({
        container: 'map',
        // style: 'https://demotiles.maplibre.org/style.json', // 默认底图
        style: {
            "version": 8,
            // "glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
            "sources": {
                    "source-satellite": {
                    "type": "raster",
                    "tiles": ["https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png"],
                    "tileSize": 256,
                    "minzoom": 0,
                    "maxzoom": 20
                },
                "arcgisTerrainSource": {
                    "type": "raster-dem",
                    "tiles": ["arcgis-lerc://server.arcgisonline.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer/tile/{z}/{y}/{x}"],
                    "tileSize": 256,
                    "encoding": "mapbox"
                }
            },
            "layers": [
                {
                    "id": "base-layer-satellite",
                    "type": "raster",
                    "source": "source-satellite",
                    "layout": {
                        "visibility": "visible"
                    }
                }
            ]
        },
        center: [113.53658048252841, 37.70555767579111],
        zoom: 3
    });

    map.on('load', () => {

        // acgis地形图
        Lerc.load().then(()=>{
            /**
             * 自定义协议:将 ArcGIS LERC 转换为 MapLibre 识别的 DEM 数据
             */
            maplibregl.addProtocol('arcgis-lerc', async (params, abortController) => {
                const url = params.url.replace('arcgis-lerc://', 'https://');

                const t = await fetch(url);
                if (t.status == 200) {
                    const buffer = await t.arrayBuffer();
                    const decodedData = Lerc.decode(buffer);
                    const { width, height, pixels } = decodedData;
                    
                    // MapLibre 的地形要求:
                    // 1. 数据必须是经过 RGB 编码的图像,或者直接返回解码后的浮点数组(取决于版本)
                    // 2. 这里我们手动将浮点数转换为 MapLibre 预期的格式
                    const imageData = new Uint8ClampedArray(width * height * 4);
                    
                    for (let i = 0; i < pixels[0].length; i++) {
                        const elevation = pixels[0][i];
                        // 这里是一个简化的 Mapbox Terrain-RGB 编码逻辑
                        // 实际上 MapLibre 的某些版本支持更直接的返回,但这里使用通用转换
                        const value = Math.round((elevation + 10000) * 10);
                        imageData[i * 4] = (value >> 16) & 255;
                        imageData[i * 4 + 1] = (value >> 8) & 255;
                        imageData[i * 4 + 2] = value & 255;
                        imageData[i * 4 + 3] = 255;
                    }
                    const newImg = new ImageData(imageData, width, height);
                    const imageBitmap = await createImageBitmap(newImg);
                    return { data: imageBitmap };
                    // return { data: imageData, width, height };
                } else {
                    throw new Error(`Tile fetch error: ${t.statusText}`);
                }
            });

            map.setTerrain({
                source: 'arcgisTerrainSource',
                exaggeration: 1.0
            });
        });
        
    });
</script>

</body>
</html>
相关推荐
神探小白牙11 分钟前
eCharts 多系列柱状图增加背景图
javascript·ecmascript·echarts
cy_cy0023 小时前
互动滑轨屏如何优化参观动线?
科技·3d·人机交互·交互·软件构建
Coovally AI模型快速验证3 小时前
CVPR 2026|PanDA:首个多模态3D全景分割的无监督域适应框架
人工智能·3d·视觉检测·工业质检
多喝水就行6 小时前
ArcGIS10.2 许可License启动失败的其中一个解决办法
arcgis
薛定猫AI7 小时前
【深度解析】Gemma Chat 本地 AI 编程 Agent:Electron + MLX + 开源模型的离线 Vibe Coding 实战
javascript·人工智能·electron
全栈前端老曹7 小时前
【前端地图】多地图平台适配方案——高德、百度、腾讯、Google Maps SDK 差异对比、封装统一地图接口
前端·javascript·百度·dubbo·wgs84·gcj-02·bd09
笑虾7 小时前
Win10 修改注册表 让鼠标悬停PNG上时 tip 始终显示分辨率
开发语言·javascript·ecmascript
AGV算法笔记7 小时前
CVPR 2024顶级SLAM论文精读:SplaTAM如何用3D高斯实现稠密RGB-D SLAM?
深度学习·3d·机器人视觉·slam·三维重建
雾岛听风6918 小时前
JavaScript基础语法速查手册
开发语言·前端·javascript
用户2367829801688 小时前
从零实现 GIF 制作工具:LZW 压缩与 Median Cut 色彩量化
前端·javascript