【2025最新】ArcGIS for JS 实现地图卷帘效果,动态修改参数(进阶版)

ArcGIS for JS 实现地图卷帘效果,动态修改参数(进阶版)

本文适用 ArcGIS JS API 4.28-4.33 版本,核心是实现一款进阶版地图卷帘组件。该组件在基础卷帘功能上,新增并强化了三大关键特性:多图层切换自定义滑块样式动态光影效果 ,并支持对 Swipe 组件参数的动态修改。

本文为

文章目录

工具 /插件/系统 名 版本 说明
ArcGIS JS API 4.28~4.33 地图核心能力(底图加载、视图渲染)
天地图服务 - 提供街道、卫星、地形等底图数据源

效果图

效果图

功能展示

  • 垂直/水平方向的卷帘切换
  • 自定义卷帘位置调整
  • 可选择对比的图层
  • 键盘方向键控制
  • 重置和全图查看功能
  • 美观的UI设计和动画效果

实现步骤

1. 基础HTML结构搭建

首先,我们需要创建基本的HTML页面结构,包括地图容器、控制面板和提示信息:

html 复制代码
<div id="viewDiv"></div>
<div id="controlPanel">
    <!-- 控制面板内容 -->
</div>
<div class="instruction">
    <i class="fa fa-hand-pointer-o" aria-hidden="true"></i> 拖动卷帘滑块或使用键盘方向键调整位置
</div>
  • viewDiv:用于显示地图的容器
  • controlPanel:包含各种控制元素的面板
  • instruction:底部的操作提示

2. 样式设计

为了使界面美观且易用,我们需要设计相应的CSS样式:

css 复制代码
/* 基础样式 */
html, body, #viewDiv {
    padding: 0;
    margin: 0;
    height: 100%;
    width: 100%;
}

/* 控制面板样式 */
#controlPanel {
    position: absolute;
    top: 10px;
    right: 10px;
    background-color: white;
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    z-index: 100;
    width: 280px;
}

/* 自定义卷帘样式 */
.esri-swipe__handle {
    background-color: #0079c1 !important;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5) !important;
}

/* 动态光影效果 */
@keyframes glow {
    0% { box-shadow: 0 0 5px rgba(0, 121, 193, 0.5); }
    50% { box-shadow: 0 0 20px rgba(0, 121, 193, 0.8); }
    100% { box-shadow: 0 0 5px rgba(0, 121, 193, 0.5); }
}

.esri-swipe__divider {
    animation: glow 2s infinite;
}

特别注意对卷帘组件的样式定制,通过!important覆盖默认样式,并添加了光影动画效果增强视觉体验。

3. 引入必要的库

我们需要引入ArcGIS API for JavaScript和Font Awesome图标库:

html 复制代码
<!-- ArcGIS API for JavaScript -->
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.28/"></script>
<!-- Font Awesome -->
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

4. 初始化地图和图层

首先,我们需要导入ArcGIS API的核心模块并创建地图实例:

javascript 复制代码
const [Map, MapView, Swipe] = await $arcgis.import([
    "@arcgis/core/Map",
    "@arcgis/core/views/MapView",
    "@arcgis/core/widgets/Swipe"
]);

// 创建地图
const map = new Map();

// 创建地图视图
const view = new MapView({
    container: "viewDiv",
    map: map,
    center: [104, 35], // 中国中心位置
    zoom: 4
});

接下来,定义并加载需要对比的图层:

javascript 复制代码
// 定义可用于对比的图层
const layers = [
    {
        id: "streets",
        name: "街道地图",
        type: "tile",
        url: getUrlTemplate('vec'),
        opacity: 1
    },
    {
        id: "satellite",
        name: "卫星影像",
        type: "tile",
        url: getUrlTemplate('img'),
        opacity: 1
    },
    {
        id: "topo",
        name: "地形图",
        type: "tile",
        url: getUrlTemplate('cta'),
        opacity: 1
    }
];

// 加载所有图层
const layerInstances = {};
layers.forEach(layerInfo => {
    let layer = new WebTileLayer({
        urlTemplate: layerInfo.url,
        opacity: layerInfo.opacity,
        copyright: "天地图 © 国家地理信息公共服务平台",
        spatialReference: config.spatialReference,
        tileInfo: tileInfo
    });
    if (layer) {
        layerInstances[layerInfo.id] = layer;
        map.add(layer);
    }
});

5. 创建图层选择器

为了允许用户切换对比的图层,我们需要创建下拉选择器并填充图层选项:

javascript 复制代码
// 填充图层选择器
const leadingLayerSelect = document.getElementById("leadingLayerSelect");
const trailingLayerSelect = document.getElementById("trailingLayerSelect");

layers.forEach(layerInfo => {
    // 为右侧图层选择器添加选项
    const leadingOption = document.createElement("option");
    leadingOption.value = layerInfo.id;
    leadingOption.textContent = layerInfo.name;
    leadingLayerSelect.appendChild(leadingOption);

    // 为左侧图层选择器添加选项
    const trailingOption = document.createElement("option");
    trailingOption.value = layerInfo.id;
    trailingOption.textContent = layerInfo.name;
    trailingLayerSelect.appendChild(trailingOption);
});

// 设置默认选择的图层
leadingLayerSelect.value = "streets";
trailingLayerSelect.value = "satellite";

6. 初始化卷帘组件

创建Swipe组件并添加到地图视图中:

javascript 复制代码
let swipeWidget = new Swipe({
    view: view,
    leadingLayers: [layerInstances["streets"]],
    trailingLayers: [layerInstances["satellite"]],
    position: 50, // 初始位置在50%处
    direction: "vertical", // 初始为垂直方向
    visibleElements: {
        handle: true,
        divider: true
    }
});

// 将卷帘组件添加到视图
view.ui.add(swipeWidget);

7. 添加交互功能

为了使卷帘工具更加易用,我们需要添加各种交互功能:

卷帘位置调整
javascript 复制代码
const swipePositionSlider = document.getElementById("swipePosition");
const positionValue = document.getElementById("positionValue");

swipePositionSlider.addEventListener("input", function () {
    const position = parseInt(this.value);
    swipeWidget.position = position;
    positionValue.textContent = position + "%";
});
卷帘方向切换
javascript 复制代码
const verticalBtn = document.getElementById("verticalBtn");
const horizontalBtn = document.getElementById("horizontalBtn");

verticalBtn.addEventListener("click", function () {
    swipeWidget.direction = "vertical";
    verticalBtn.classList.add("active");
    horizontalBtn.classList.remove("active");
});

horizontalBtn.addEventListener("click", function () {
    swipeWidget.direction = "horizontal";
    horizontalBtn.classList.add("active");
    verticalBtn.classList.remove("active");
});
图层切换功能
javascript 复制代码
leadingLayerSelect.addEventListener("change", function () {
    const selectedLayerId = this.value;
    const selectedLayer = layerInstances[selectedLayerId];
    
    if (selectedLayer) {
        swipeWidget.leadingLayers.removeAll();
        swipeWidget.leadingLayers.add(selectedLayer);
    }
});

trailingLayerSelect.addEventListener("change", function () {
    const selectedLayerId = this.value;
    const selectedLayer = layerInstances[selectedLayerId];
    
    if (selectedLayer) {
        swipeWidget.trailingLayers.removeAll();
        swipeWidget.trailingLayers.add(selectedLayer);
    }
});
键盘控制
javascript 复制代码
document.addEventListener("keydown", function (event) {
    if (event.key === "ArrowLeft" || event.key === "ArrowRight" ||
        event.key === "ArrowUp" || event.key === "ArrowDown") {
        
        event.preventDefault();
        let newPosition = swipeWidget.position;
        
        // 根据方向键和当前卷帘方向调整位置
        if (swipeWidget.direction === "vertical") {
            if (event.key === "ArrowLeft") {
                newPosition = Math.max(0, newPosition - 1);
            } else if (event.key === "ArrowRight") {
                newPosition = Math.min(100, newPosition + 1);
            }
        } else {
            if (event.key === "ArrowUp") {
                newPosition = Math.max(0, newPosition - 1);
            } else if (event.key === "ArrowDown") {
                newPosition = Math.min(100, newPosition + 1);
            }
        }
        
        swipeWidget.position = newPosition;
        // 更新滑块和显示值
        swipePositionSlider.value = newPosition;
        positionValue.textContent = newPosition + "%";
    }
});
重置和全图功能
javascript 复制代码
// 重置按钮事件
document.getElementById("resetBtn").addEventListener("click", function () {
    // 重置卷帘位置
    swipeWidget.position = 50;
    swipePositionSlider.value = 50;
    positionValue.textContent = "50%";
    
    // 重置图层选择
    leadingLayerSelect.value = "streets";
    trailingLayerSelect.value = "satellite";
    
    // 重置卷帘方向
    swipeWidget.direction = "vertical";
    verticalBtn.classList.add("active");
    horizontalBtn.classList.remove("active");
});

// 全图按钮事件
document.getElementById("fullExtentBtn").addEventListener("click", function () {
    view.goTo({
        center: [104, 35],
        zoom: 4
    });
});

所有代码

index.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>ArcGIS for JS 地图卷帘效果进阶</title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #controlPanel {
            position: absolute;
            top: 10px;
            right: 10px;
            background-color: white;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            z-index: 100;
            width: 280px;
        }

        .control-section {
            margin-bottom: 15px;
        }

        .control-section:last-child {
            margin-bottom: 0;
        }

        .control-label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
            color: #333;
        }

        .slider-container {
            display: flex;
            align-items: center;
        }

        .slider-container input[type="range"] {
            flex-grow: 1;
            margin-right: 10px;
        }

        .slider-value {
            width: 50px;
            text-align: right;
        }

        .button-group {
            display: flex;
            gap: 8px;
            margin-top: 10px;
        }

        button {
            padding: 8px 12px;
            background-color: #0079c1;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.2s;
        }

        button:hover {
            background-color: #005a8c;
        }

        button.reset {
            background-color: #f04e31;
        }

        button.reset:hover {
            background-color: #d93a1e;
        }

        .layer-selector {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background-color: white;
        }

        .instruction {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 20px;
            font-size: 14px;
            z-index: 100;
            pointer-events: none;
        }

        /* 自定义卷帘滑块样式 */
        .esri-swipe__handle {
            /* width: 4px !important; */
            background-color: #0079c1 !important;
            box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5) !important;
        }

        .esri-swipe__handle::before,
        .esri-swipe__handle::after {
            width: 30px !important;
            height: 30px !important;
            background-color: #0079c1 !important;
            border: 2px solid white !important;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3) !important;
        }

        /* 动态光影效果 */
        @keyframes glow {
            0% {
                box-shadow: 0 0 5px rgba(0, 121, 193, 0.5);
            }

            50% {
                box-shadow: 0 0 20px rgba(0, 121, 193, 0.8);
            }

            100% {
                box-shadow: 0 0 5px rgba(0, 121, 193, 0.5);
            }
        }

        .esri-swipe__divider {
            animation: glow 2s infinite;
        }
    </style>
    <!-- ArcGIS API for JavaScript -->
    <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css">
    <script src="https://js.arcgis.com/4.28/"></script>
    <!-- Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
</head>

<body>
    <div id="viewDiv"></div>
    <div id="controlPanel">
        <div class="control-section">
            <div class="control-label">卷帘位置</div>
            <div class="slider-container">
                <input type="range" id="swipePosition" min="0" max="100" value="50" class="slider">
                <span id="positionValue" class="slider-value">50%</span>
            </div>
        </div>
        <div class="control-section">
            <div class="control-label">卷帘方向</div>
            <div class="button-group">
                <button id="verticalBtn" class="active"><i class="fa fa-arrows-v" aria-hidden="true"></i> 垂直</button>
                <button id="horizontalBtn"><i class="fa fa-arrows-h" aria-hidden="true"></i> 水平</button>
            </div>
        </div>
        <div class="control-section">
            <div class="control-label">右侧图层</div>
            <select id="leadingLayerSelect" class="layer-selector"></select>
        </div>
        <div class="control-section">
            <div class="control-label">左侧图层</div>
            <select id="trailingLayerSelect" class="layer-selector"></select>
        </div>
        <div class="control-section">
            <div class="button-group">
                <button id="resetBtn" class="reset"><i class="fa fa-refresh" aria-hidden="true"></i> 重置</button>
                <button id="fullExtentBtn"><i class="fa fa-arrows-alt" aria-hidden="true"></i> 全图</button>
            </div>
        </div>
    </div>
    <div class="instruction">
        <i class="fa fa-hand-pointer-o" aria-hidden="true"></i> 拖动卷帘滑块或使用键盘方向键调整位置
    </div>

    <script type="module">
        const [Map,
            MapView,
            Swipe] = await $arcgis.import([
                "@arcgis/core/Map",
                "@arcgis/core/views/MapView",
                "@arcgis/core/widgets/Swipe"
            ])

        import { loadTiandituBasemap } from './js/tiandituLoader.js';
        const {
            config,
            getUrlTemplate,
            WebTileLayer, tileInfo } = await loadTiandituBasemap();
        // 定义可用于对比的图层
        const layers = [
            {
                id: "streets",
                name: "街道地图",
                type: "tile",
                url: getUrlTemplate('vec'),
                opacity: 1
            },
            {
                id: "satellite",
                name: "卫星影像",
                type: "tile",
                url: getUrlTemplate('img'),
                opacity: 1
            },
            {
                id: "topo",
                name: "地形图",
                type: "tile",
                url: getUrlTemplate('cta'),
                opacity: 1
            }
        ];

        // 创建地图
        const map = new Map();

        // 创建地图视图
        const view = new MapView({
            container: "viewDiv",
            map: map,
            center: [104, 35], // 中国中心位置
            zoom: 4
        });

        // 加载所有图层
        const layerInstances = {};
        layers.forEach(layerInfo => {
            let layer = new WebTileLayer({
                urlTemplate: layerInfo.url,
                opacity: layerInfo.opacity,
                // subDomains: config.subDomains,
                copyright: "天地图 © 国家地理信息公共服务平台",
                spatialReference: config.spatialReference,
                tileInfo: tileInfo
            });
            if (layer) {
                layerInstances[layerInfo.id] = layer;
                map.add(layer);
            }
        });

        // 填充图层选择器
        const leadingLayerSelect = document.getElementById("leadingLayerSelect");
        const trailingLayerSelect = document.getElementById("trailingLayerSelect");

        layers.forEach(layerInfo => {
            const leadingOption = document.createElement("option");
            leadingOption.value = layerInfo.id;
            leadingOption.textContent = layerInfo.name;
            leadingLayerSelect.appendChild(leadingOption);

            const trailingOption = document.createElement("option");
            trailingOption.value = layerInfo.id;
            trailingOption.textContent = layerInfo.name;
            trailingLayerSelect.appendChild(trailingOption);
        });

        // 默认选择的图层
        leadingLayerSelect.value = "streets";
        trailingLayerSelect.value = "satellite";

        // 创建卷帘微件
        let swipeWidget = new Swipe({
            view: view,
            leadingLayers: [layerInstances["streets"]],
            trailingLayers: [layerInstances["satellite"]],
            position: 50,
            direction: "vertical",
            visibleElements: {
                handle: true,
                divider: true
            }
        });

        view.ui.add(swipeWidget);

        // 更新图层选择器事件
        leadingLayerSelect.addEventListener("change", function () {
            const selectedLayerId = this.value;
            const selectedLayer = layerInstances[selectedLayerId];

            if (selectedLayer) {
                // 移除当前的leading图层
                swipeWidget.leadingLayers.removeAll();

                // 添加新的leading图层
                swipeWidget.leadingLayers.add(selectedLayer);
    }
        });

        trailingLayerSelect.addEventListener("change", function () {
            const selectedLayerId = this.value;
            const selectedLayer = layerInstances[selectedLayerId];

            if (selectedLayer) {
                // 移除当前的trailing图层
                swipeWidget.trailingLayers.removeAll();

                // 添加新的trailing图层
                swipeWidget.trailingLayers.add(selectedLayer);

                // 更新透明度滑块
                document.getElementById("trailingOpacity").value = selectedLayer.opacity * 100;
                document.getElementById("trailingOpacityValue").textContent = (selectedLayer.opacity * 100) + "%";
            }
        });

        // 卷帘位置滑块事件
        const swipePositionSlider = document.getElementById("swipePosition");
        const positionValue = document.getElementById("positionValue");

        swipePositionSlider.addEventListener("input", function () {
            const position = parseInt(this.value);
            swipeWidget.position = position;
            positionValue.textContent = position + "%";
        });



        // 卷帘方向按钮事件
        const verticalBtn = document.getElementById("verticalBtn");
        const horizontalBtn = document.getElementById("horizontalBtn");

        verticalBtn.addEventListener("click", function () {
            swipeWidget.direction = "vertical";
            verticalBtn.classList.add("active");
            horizontalBtn.classList.remove("active");
        });

        horizontalBtn.addEventListener("click", function () {
            swipeWidget.direction = "horizontal";
            horizontalBtn.classList.add("active");
            verticalBtn.classList.remove("active");
        });

        // 重置按钮事件
        document.getElementById("resetBtn").addEventListener("click", function () {
            // 重置卷帘位置
            swipeWidget.position = 50;
            swipePositionSlider.value = 50;
            positionValue.textContent = "50%";

            // 重置透明度
            const leadingLayer = swipeWidget.leadingLayers.getItemAt(0);
            const trailingLayer = swipeWidget.trailingLayers.getItemAt(0);

            if (leadingLayer) {
                leadingLayer.opacity = 1;
                document.getElementById("leadingOpacity").value = 100;
                document.getElementById("leadingOpacityValue").textContent = "100%";
            }

            if (trailingLayer) {
                trailingLayer.opacity = 1;
                document.getElementById("trailingOpacity").value = 100;
                document.getElementById("trailingOpacityValue").textContent = "100%";
            }

            // 重置图层选择
            leadingLayerSelect.value = "streets";
            trailingLayerSelect.value = "satellite";

            // 重置卷帘方向
            swipeWidget.direction = "vertical";
            verticalBtn.classList.add("active");
            horizontalBtn.classList.remove("active");
        });

        // 全图按钮事件
        document.getElementById("fullExtentBtn").addEventListener("click", function () {
            view.goTo({
                center: [104, 35],
                zoom: 4
            });
        });

        // 键盘方向键控制卷帘位置
        document.addEventListener("keydown", function (event) {
            if (event.key === "ArrowLeft" || event.key === "ArrowRight" ||
                event.key === "ArrowUp" || event.key === "ArrowDown") {

                event.preventDefault();

                let newPosition = swipeWidget.position;

                // 根据方向键和当前卷帘方向调整位置
                if (swipeWidget.direction === "vertical") {
                    if (event.key === "ArrowLeft") {
                        newPosition = Math.max(0, newPosition - 1);
                    } else if (event.key === "ArrowRight") {
                        newPosition = Math.min(100, newPosition + 1);
                    }
                } else {
                    if (event.key === "ArrowUp") {
                        newPosition = Math.max(0, newPosition - 1);
                    } else if (event.key === "ArrowDown") {
                        newPosition = Math.min(100, newPosition + 1);
                    }
                }

                swipeWidget.position = newPosition;
            }
        });

        // 初始化透明度滑块值
        document.getElementById("leadingOpacity").value = 100;
        document.getElementById("leadingOpacityValue").textContent = "100%";
        document.getElementById("trailingOpacity").value = 100;
        document.getElementById("trailingOpacityValue").textContent = "100%";

        // 添加按钮激活样式
        verticalBtn.classList.add("active");

    </script>
</body>

</html>

tiandituLoader.js

复制代码
/**
 * 天地图加载公共模块
 * 功能:封装天地图底图加载逻辑,返回配置好的Basemap实例
 * 依赖:ArcGIS API 4.x
 */
export async function loadTiandituBasemap() {
    try {
        // 1. 按需导入ArcGIS核心模块
        const [
            WebTileLayer,
            Basemap,
            TileInfo
        ] = await $arcgis.import([
            "@arcgis/core/layers/WebTileLayer",
            "@arcgis/core/Basemap",
            "@arcgis/core/layers/support/TileInfo",
        ]);

        // 2. 配置参数(可根据需求调整)
        const config = {
            tk:"你的密钥", // 天地图密钥
            spatialReference: { wkid: 4326 },       // 目标坐标系(WGS84)
            subDomains: ["0", "1", "2", "3", "4", "5", "6", "7"], // 多子域名
            tileMatrixSet: "c",                     // 天地图瓦片矩阵集
            layerType: {
                vec: "vec", // 矢量底图
                cva: "cva"  // 矢量注记
            }
        };

        // 3. 定义瓦片信息(匹配WGS84坐标系的瓦片规则)
        const tileInfo = new TileInfo({
            dpi: 90.71428571427429,
            rows: 256,
            cols: 256,
            compressionQuality: 0,
            origin: { x: -180, y: 90 },
            spatialReference: config.spatialReference,
            lods: [
                { level: 2, levelValue: 2, resolution: 0.3515625, scale: 147748796.52937502 },
                { level: 3, levelValue: 3, resolution: 0.17578125, scale: 73874398.264687508 },
                { level: 4, levelValue: 4, resolution: 0.087890625, scale: 36937199.132343754 },
                { level: 5, levelValue: 5, resolution: 0.0439453125, scale: 18468599.566171877 },
                { level: 6, levelValue: 6, resolution: 0.02197265625, scale: 9234299.7830859385 },
                { level: 7, levelValue: 7, resolution: 0.010986328125, scale: 4617149.8915429693 },
                { level: 8, levelValue: 8, resolution: 0.0054931640625, scale: 2308574.9457714846 },
                { level: 9, levelValue: 9, resolution: 0.00274658203125, scale: 1154287.4728857423 },
                { level: 10, levelValue: 10, resolution: 0.001373291015625, scale: 577143.73644287116 },
                { level: 11, levelValue: 11, resolution: 0.0006866455078125, scale: 288571.86822143558 },
                { level: 12, levelValue: 12, resolution: 0.00034332275390625, scale: 144285.93411071779 },
                { level: 13, levelValue: 13, resolution: 0.000171661376953125, scale: 72142.967055358895 },
                { level: 14, levelValue: 14, resolution: 8.58306884765625e-005, scale: 36071.483527679447 },
                { level: 15, levelValue: 15, resolution: 4.291534423828125e-005, scale: 18035.741763839724 },
                { level: 16, levelValue: 16, resolution: 2.1457672119140625e-005, scale: 9017.8708819198619 },
                { level: 17, levelValue: 17, resolution: 1.0728836059570313e-005, scale: 4508.9354409599309 },
                { level: 18, levelValue: 18, resolution: 5.3644180297851563e-006, scale: 2254.4677204799655 },
                { level: 19, levelValue: 19, resolution: 2.68220901489257815e-006, scale: 1127.23386023998275 },
                { level: 20, levelValue: 20, resolution: 1.341104507446289075e-006, scale: 563.616930119991375 }
            ]
        });

        // 4. 构建天地图URL模板(支持多子域名)
        const getUrlTemplate = (layer) => {
            return `http://t0.tianditu.gov.cn/${layer}_${config.tileMatrixSet}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${layer}&STYLE=default&TILEMATRIXSET=${config.tileMatrixSet}&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&FORMAT=tiles&tk=${config.tk}`;
        };

        // 5. 创建矢量底图图层
        const vecLayer = new WebTileLayer({
            urlTemplate: getUrlTemplate(config.layerType.vec),
            subDomains: config.subDomains,
            copyright: "天地图 © 国家地理信息公共服务平台",
            spatialReference: config.spatialReference,
            tileInfo: tileInfo
        });

        // 6. 创建矢量注记图层
        const cvaLayer = new WebTileLayer({
            urlTemplate: getUrlTemplate(config.layerType.cva),
            subDomains: config.subDomains,
            copyright: "天地图 © 国家地理信息公共服务平台",
            spatialReference: config.spatialReference,
            tileInfo: tileInfo
        });

        // 7. 创建自定义底图并返回
        const tiandituBasemap = new Basemap({
            baseLayers: [vecLayer],
            referenceLayers: [cvaLayer],
            title: "天地图矢量图(WGS84)",
            id: "tianditu-vector-wgs84"
        });

        return {
            tileInfo,
            config,
            getUrlTemplate,
            tiandituBasemap,
            WebTileLayer,
            Basemap,
            vecLayer,
            cvaLayer
        };

    } catch (error) {
        console.error("天地图加载失败:", error);
        throw new Error("天地图公共模块加载异常,请检查依赖和配置");
    }
}
相关推荐
枫叶丹42 小时前
【Qt开发】输入类控件(四)-> QSpinBox
开发语言·qt
Yupureki3 小时前
从零开始的C++学习生活 2:类和对象(上)
c语言·开发语言·c++·学习·visual studio
南屿im3 小时前
把代码变成“可改的树”:一文读懂前端 AST 的原理与实战
前端·javascript
羚羊角uou3 小时前
【Linux】线程的互斥
java·开发语言
mxd018483 小时前
最常用的js加解密之RSA-SHA256 加密算法简介与 jsjiami 的结合使用指南
开发语言·javascript·ecmascript
gopyer3 小时前
180课时吃透Go语言游戏后端开发7:Go语言中的函数
开发语言·游戏·golang·go·函数
来不及辣哎呀3 小时前
学习Java第三十天——黑马点评37~42
java·开发语言·学习
半桶水专家4 小时前
C语言中的setitimer函数详解
c语言·开发语言·算法