当前位置: 首页 > news >正文

【2025最新】ArcGIS for JS 实现地图卷帘效果

ArcGIS for JS 地图卷帘效果的两种方法

本文适用 ArcGIS JS API 4.28-4.33 版本,核心功能是实现 “地图卷帘效果”—— 通过在同一个地图视图中加载两种不同类型的底图(街道地图和卫星影像),并借助 Swipe(卷帘)组件,让用户可以拖动分隔线,直观对比两种底图在同一区域的显示差异,常见于地理信息对比分析场景(如城市变迁、地形差异查看等)。

文章目录

  • ArcGIS for JS 地图卷帘效果的两种方法
    • 效果图
    • 一、核心功能实现
    • 二、方案1:通过Swipe组件方法进行实现(适用4.32以下版本)
      • 2.1 核心模块与天地图资源加载
      • 2.2 底图图层定义与实例化
      • 2.3 地图与 2D 视图创建
      • 2.4 卷帘微件配置与挂载
      • 2.5 所有代码
    • 三、方案2:通过Swipe组件方法进行实现(适用4.32以上版本)
      • 3.1 资源引入
      • 3.2 地图核心组件配置(HTML 标签式开发)
      • 3.3 ArcGIS 核心模块与天地图工具导入
      • 3.4 地图实例创建与卷帘功能绑定
      • 3.5 所有代码

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

效果图

效果图
在这里插入图片描述

一、核心功能实现

针对基础引入过程,本文将不过多赘述,有需要的,可自行查阅 《【2025最新】arcgis for js 如何引入前端项目,并使用插件的功能》

二、方案1:通过Swipe组件方法进行实现(适用4.32以下版本)

2.1 核心模块与天地图资源加载

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();

这是代码的 “资源初始化阶段”,负责加载实现地图功能的核心模块和天地图底图资源:

  • ArcGIS 模块动态导入

    • 使用 $arcgis.import() 方法(ArcGIS API 4.x 推荐的动态导入方式)加载三个关键模块:

      • Map:用于创建地图实例,管理地图的图层集合;

      • MapView:用于创建 2D 地图视图,控制地图的显示位置、缩放级别等交互属性;

      • Swipe:卷帘微件模块,是实现 “卷帘对比” 效果的核心组件。

    • 通过数组解构赋值,将导入的模块直接赋值给 MapMapViewSwipe 变量,方便后续使用。

  • 天地图资源加载

    • 从本地 ./js/tiandituLoader.js 文件中导入 loadTiandituBasemap 函数(该函数是自定义的天地图加载工具,封装了天地图底图的配置逻辑);

    • 调用 loadTiandituBasemap() 并通过解构赋值获取四个关键参数:

      • config:天地图配置信息(如子域名、空间参考等);

      • getUrlTemplate:获取天地图底图 URL 模板的函数(不同类型底图(街道、卫星)对应不同 URL);

      • WebTileLayer:ArcGIS 的 “网络切片图层” 类(天地图底图以切片形式提供,需用该类加载);

      • tileInfo:天地图切片的信息(如切片大小、比例尺等),确保 ArcGIS 能正确解析和渲染天地图切片。

2.2 底图图层定义与实例化

// 定义可用于对比的图层const layers =  [{id: "streets",name: "街道地图",type: "街道",url: getUrlTemplate('img'),opacity: 1},{id: "satellite",name: "卫星影像",type: "卫星",url: getUrlTemplate('ter'),opacity: 1}];// 加载所有图层const layerInstances = {}, allLayers =  [];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;allLayers.push(layer);}});

这部分负责 “定义对比图层” 并 “创建图层实例”,是实现卷帘对比的 “数据基础”:

  • 图层配置数组

    • layers 数组定义了两个用于对比的底图图层(街道地图和卫星影像),每个图层对象包含五个属性:

      • id:图层唯一标识(后续通过 ID 快速获取图层实例);

      • name:图层名称(用于显示,如图例说明);

      • type:图层类型(标识是街道还是卫星图);

      • url:调用 getUrlTemplate() 生成的底图 URL 模板('img' 对应街道图,'ter' 对应卫星影像,具体映射规则由 tiandituLoader.js 定义);

      • opacity:图层透明度(1 表示完全不透明,确保对比时图层清晰)。

  • 图层实例化与管理

    • 定义 layerInstances(对象,按 ID 存储图层实例,方便快速查找)和 allLayers(数组,存储所有图层实例,用于后续添加到地图);

    • 遍历 layers 数组,为每个图层配置创建 WebTileLayer 实例,传入关键参数:

      • urlTemplate:图层的 URL 模板(从配置中获取);

      • opacity:图层透明度(保持 1,不透明);

      • copyright:版权信息(天地图要求必须标注,符合数据使用规范);

      • spatialReference:空间参考(从 config 中获取,确保与天地图的空间参考一致,避免图层偏移);

      • tileInfo:切片信息(确保 ArcGIS 正确解析切片);

    • 实例化成功后,将图层实例存入 layerInstances(以 id 为键)和 allLayers 数组,完成图层的初始化和管理。

2.3 地图与 2D 视图创建

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

这部分是 “地图与视图的核心创建逻辑”,将前面准备的图层与页面容器关联,实现地图的基础显示:

  • 地图实例创建

    • 调用 new Map() 创建地图实例 map,并通过 layers: allLayers 将前面实例化的两个底图图层添加到地图中(此时两个图层会叠加显示,但后续卷帘微件会对它们进行分区显示)。
  • 2D 视图创建

    • 调用 new MapView() 创建 2D 地图视图实例 view,传入四个关键参数:

      • container: "viewDiv":指定视图挂载的页面容器(即前面的 #viewDiv),地图会在该容器中渲染;

      • map:关联的地图实例(将视图与地图绑定,视图显示的是该地图的内容);

      • center: [104, 35]:设置地图初始中心点坐标(经度 104°,纬度 35°,大致为中国地理中心位置,确保初始加载时显示中国全貌);

      • zoom: 4:设置初始缩放级别(ArcGIS 的 zoom 值越大,地图显示越详细,4 级对应 “中国全貌” 的显示尺度)。

2.4 卷帘微件配置与挂载

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

这是实现 “卷帘对比效果” 的最后一步,通过配置和挂载 Swipe 微件,让用户可以交互对比两个底图:

  • 卷帘微件实例化

    • 调用 new Swipe() 创建卷帘微件实例 swipeWidget,传入六个关键配置参数:

      • view: view:关联的地图视图(微件需知道在哪个视图上生效);

      • leadingLayers: [layerInstances["satellite"]]:“领先图层”(卷帘分隔线左侧显示的图层,这里设置为卫星影像);

      • trailingLayers: [layerInstances["streets"]]:“尾随图层”(卷帘分隔线右侧显示的图层,这里设置为街道地图);

      • // position: 50:注释掉的分隔线初始位置配置(值为 0-100 的数字,50 表示初始在视图中间,默认也为中间,故可注释);

      • direction: "vertical":卷帘方向(vertical 表示垂直卷帘,分隔线为竖线,拖动时左右分区;可选 horizontal 水平卷帘,分隔线为横线,上下分区);

      • visibleElements: { handle: true, divider: true }:设置显示的交互元素(handle: true 显示拖动手柄,divider: true 显示分隔线,两者都为 true 确保用户能看到并拖动分隔线)。

  • 微件挂载到视图

    • 调用 view.ui.add(swipeWidget) 将卷帘微件添加到地图视图的 UI 中(ArcGIS 视图的 ui 属性用于管理界面组件,添加后微件会自动在地图上显示,无需手动处理位置)。

2.5 所有代码

<!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%;}</style><!-- ArcGIS API for JavaScript --><link rel="stylesheet" href="https://js.arcgis.com/4.31/esri/themes/dark/main.css" /><script src="https://js.arcgis.com/4.31/"></script>
</head><body class="calcite-mode-dark"><div id="viewDiv"></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: "街道",url: getUrlTemplate('img'),opacity: 1},{id: "satellite",name: "卫星影像",type: "卫星",url: getUrlTemplate('ter'),opacity: 1}];// 加载所有图层const layerInstances = {}, allLayers = [];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;allLayers.push(layer);}});// 创建地图const map = new Map({layers: allLayers,});// 创建地图视图const view = new MapView({container: "viewDiv",map,center: [104, 35],// 中国中心位置zoom: 4});// 创建卷帘微件let swipeWidget = new Swipe({view: view,leadingLayers: [layerInstances["satellite"]],trailingLayers: [layerInstances["streets"]],// position: 50,direction: "vertical",visibleElements: {handle: true,divider: true}});view.ui.add(swipeWidget);</script>
</body></html>

三、方案2:通过Swipe组件方法进行实现(适用4.32以上版本)

3.1 资源引入

新增资源

  1. 引入 calcite.esm.js(3.2.1 版本),这是 ArcGIS 提供的轻量级 UI 组件库,包含按钮、列表、弹窗等基础组件,虽代码中未直接使用,但为后续扩展自定义 UI 预留了资源。
  2. 引入 map-components/ 组件库(4.33 版本),这是 ArcGIS 推出的 “开箱即用” 地图组件(如 <arcgis-map><arcgis-swipe>),无需手动编写复杂逻辑,直接通过 HTML 标签即可实现地图、卷帘等功能,大幅简化开发流程。
    Calcite Components(ArcGIS 官方组件库)
<script type="module" src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js"></script>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN --><link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/dark/main.css" /><script src="https://js.arcgis.com/4.33/"></script><!-- Load Map components from CDN--><script type="module" src="https://js.arcgis.com/4.33/map-components/"></script>

3.2 地图核心组件配置(HTML 标签式开发)

<arcgis-map zoom="4" center="116.258113, 39.985853"><arcgis-zoom position="top-left"></arcgis-zoom><arcgis-swipe swipe-position="32"></arcgis-swipe><arcgis-expand position="top-right"><arcgis-layer-list></arcgis-layer-list></arcgis-expand></arcgis-map>

这部分是代码的 “视觉与交互核心”,通过 ArcGIS 地图组件直接定义地图的基础属性与功能模块,属于 “低代码” 开发模式:

  • **核心地图容器 **<arcgis-map>

    • 这是 ArcGIS 地图组件的 “根容器”,所有地图相关功能(缩放、卷帘、图层列表)都需嵌套在该标签内;

    • 关键属性:

      • zoom="15":设置地图初始缩放级别(ArcGIS 缩放级别数值越大,地图显示越详细,15 级对应 “城市街区” 级别的显示精度);

      • center="-154.88, 19.46":设置地图初始中心点坐标(经度 -154.88°,纬度 19.46°,对应美国夏威夷州火奴鲁鲁附近区域)。

  • **缩放控制组件 **<arcgis-zoom>

    • 功能:提供 “放大”“缩小” 两个按钮,支持用户手动调整地图缩放级别;

    • position="top-left":设置组件在地图容器中的位置(左上角),符合用户 “左上角控制缩放” 的使用习惯。

  • **卷帘对比组件 **<arcgis-swipe>

    • 功能:实现 “卷帘效果”,通过拖动分隔线,对比分隔线两侧不同图层的显示差异;

    • swipe-position="32":设置卷帘分隔线的初始位置(数值范围 0-100,单位为百分比,32 表示分隔线初始在地图容器水平方向 32% 的位置,左侧显示 “领先图层”,右侧显示 “尾随图层”)。

  • 图层列表组件(带折叠功能)

    • <arcgis-expand>:折叠容器组件,点击可展开 / 收起内部内容,避免图层列表占用过多地图空间;

      • position="top-right":设置折叠容器在地图右上角;
    • <arcgis-layer-list>:图层列表组件,自动显示地图中所有已加载的图层,支持用户手动控制图层的显示 / 隐藏(如勾选 / 取消勾选图层),方便管理多图层。

3.3 ArcGIS 核心模块与天地图工具导入

const [Map, TileLayer] = await \$arcgis.import(["@arcgis/core/Map.js","@arcgis/core/layers/TileLayer.js",]);const arcgisSwipe = document.querySelector("arcgis-swipe");const viewElement = document.querySelector("arcgis-map");import { loadTiandituBasemap } from './js/tiandituLoader.js';const {config,getUrlTemplate,WebTileLayer, tileInfo } = await loadTiandituBasemap();const arcgisSwipe = document.querySelector("arcgis-swipe");const viewElement = document.querySelector("arcgis-map");import { loadTiandituBasemap } from './js/tiandituLoader.js';const {config,getUrlTemplate,WebTileLayer, tileInfo } = await loadTiandituBasemap();const infrared = new WebTileLayer({urlTemplate:getUrlTemplate('img'),copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});const nearInfrared = new WebTileLayer({urlTemplate: getUrlTemplate('ter'),copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});

这部分是 “数据与工具准备阶段”,负责导入实现图层加载与卷帘功能的核心模块,
与方法1相同,需要引入ArcGIS 核心模块、天地图底图图层创建,此处不再赘述;

3.4 地图实例创建与卷帘功能绑定

// 创建地图实例并关联到地图容器viewElement.map = new Map({basemap: "satellite",layers: [infrared, nearInfrared],});// 监听卷帘组件状态,绑定对比图层arcgisSwipe.addEventListener("arcgisPropertyChange", (e) => {if (e.detail.name === "state" && arcgisSwipe.state === "ready") {arcgisSwipe.leadingLayers.add(infrared);arcgisSwipe.trailingLayers.add(nearInfrared);}});

这部分是 “功能联动核心”,将创建的地图实例、图层与前面配置的 HTML 组件绑定,实现完整的卷帘效果:

  • 卷帘组件与图层绑定

    • 监听卷帘组件 <arcgis-swipe>arcgisPropertyChange 事件(ArcGIS 组件特有的 “属性变化事件”,当组件状态、位置等属性变化时触发);

    • 事件回调逻辑:

      • e.detail.name === "state":判断变化的属性是 “组件状态(state)”;

      • arcgisSwipe.state === "ready":确保卷帘组件已初始化完成(状态为 “就绪”,避免在组件未加载完成时绑定图层导致报错);

      • arcgisSwipe.leadingLayers.add(infrared):将天地图影像图(infrared)添加到卷帘的 “领先图层”(分隔线左侧显示的图层);

      • arcgisSwipe.trailingLayers.add(nearInfrared):将天地图地形图(nearInfrared)添加到卷帘的 “尾随图层”(分隔线右侧显示的图层);

    • 至此,卷帘组件已能控制两个图层的显示区域,用户拖动分隔线即可对比影像图与地形图的差异。

3.5 所有代码

<!DOCTYPE html>
<!doctype html>
<html lang="en"><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 {padding: 0;margin: 0;height: 100%;width: 100%;}</style><!-- Load Calcite components from CDN --><script type="module" src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js"></script><!-- Load the ArcGIS Maps SDK for JavaScript from CDN --><link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/dark/main.css" /><script src="https://js.arcgis.com/4.33/"></script><!-- Load Map components from CDN--><script type="module" src="https://js.arcgis.com/4.33/map-components/"></script>
</head><body class="calcite-mode-dark"><arcgis-map zoom="4" center="116.258113, 39.985853"><arcgis-zoom position="top-left"></arcgis-zoom><arcgis-swipe swipe-position="32"></arcgis-swipe><arcgis-expand position="top-right"><arcgis-layer-list></arcgis-layer-list></arcgis-expand></arcgis-map><script type="module">const [Map, TileLayer] = await $arcgis.import(["@arcgis/core/Map.js","@arcgis/core/layers/TileLayer.js",]);const arcgisSwipe = document.querySelector("arcgis-swipe");const viewElement = document.querySelector("arcgis-map");import { loadTiandituBasemap } from './js/tiandituLoader.js';const {config,getUrlTemplate,WebTileLayer, tileInfo } = await loadTiandituBasemap();const infrared = new WebTileLayer({urlTemplate:getUrlTemplate('img'),copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});const nearInfrared = new WebTileLayer({urlTemplate: getUrlTemplate('ter'),copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});// create the map with layersviewElement.map = new Map({basemap: "satellite",layers: [infrared, nearInfrared],});// wait for swipe to be ready, then add the leading and trailing layersarcgisSwipe.addEventListener("arcgisPropertyChange", (e) => {if (e.detail.name === "state" && arcgisSwipe.state === "ready") {arcgisSwipe.leadingLayers.add(infrared);arcgisSwipe.trailingLayers.add(nearInfrared);}});</script>
</body></html>
http://www.dtcms.com/a/439277.html

相关文章:

  • 网站域名备案密码新网站 被百度收录
  • 做网站开发没有人带贵阳市住房城乡建设局八大员网站
  • Vue3+TypeScript开发:从ProTable封装到Echarts联动
  • (二分、思维)洛谷 P4090 USACO17DEC Greedy Gift Takers P 题解
  • 业务层的抽取和业务层方法的实现详解
  • 【开题答辩全过程】以 “人和小区”便民快递平台为例,包含答辩的问题和答案
  • 找网络公司建网站每年收维护费手机网站会员中心模板
  • 网站建设公司谁管网络营销的发展趋势和前景
  • 网站建设公司包括哪些溧阳建设集团网站
  • wordpress访客统计插件网络优化怎么自己做网站
  • 小迪web自动笔记50
  • 网站模板交易seo 优化公司
  • 江西那家做网站公司好德州市住房和城乡建设局网站
  • 如何制作网站首页二维码生成短链接
  • GoFrame框架学习笔记
  • 东莞 网站建设淄博网站建设公司哪家好
  • 未备案运行网站2022年最新国际军事新闻
  • 门户网站集群建设域名注册服务商
  • MSF后渗透(提权)
  • 优秀的摄影作品网站企业管理课程视频
  • SNP亮相2025德莱维数字技术行业峰会
  • 中文人名生成器中文姓名姓氏名字称呼日本人名翻译人名英文人名可用于中文分词人名实体识别
  • 【Svelte】加载数据实现响应式的正确方式
  • 出售自己的网站Add-ons wordpress
  • 网络安全相关的专业术语
  • 帝国cms影视网站模板宁波网站制作哪家强
  • (一)算法
  • 23ICPC济南站补题
  • 商务网站建设ppt模板培训网站排名
  • 南阳市宛城区建设局网站设计本质