ArcGIS JavaScript API测量组件失效问题排查及修复咨询
ArcGIS JS API测量组件失效问题排查与修复
问题原因
- 视图类型不兼容:你使用了
SceneView(3D场景视图),但DistanceMeasurement2D和AreaMeasurement2D是专门为MapView(2D平面视图)设计的组件,二者无法兼容,直接导致测量交互完全失效,无法选择测量点、不显示测量线条。 - 缺少按钮容器样式:代码中未给
#topbar添加基础样式,测量按钮可能存在显示错位、不可点击的情况。 - 变量未声明:原代码中
activeWidget未提前声明,会造成全局变量污染,可能引发潜在逻辑问题。
修复方案
步骤1:替换视图类型
将SceneView替换为MapView,修改模块引入和视图实例化代码:
- 把
require数组中的"esri/views/SceneView"改为"esri/views/MapView" - 把视图实例从
SceneView改为MapView(MapView无需3D相关配置,保留center和zoom即可)
步骤2:补充按钮容器样式
在<style>标签中添加#topbar及按钮的样式,确保按钮正常显示和交互:
#topbar { background: rgba(255,255,255,0.9); padding: 10px; border-radius: 4px; } .action-button { margin: 0 5px; padding: 8px; border: none; border-radius: 4px; cursor: pointer; background: #fff; } .action-button.active { background: #0079c1; color: #fff; }
步骤3:声明缺失变量
在测量逻辑代码前添加let activeWidget;,避免全局变量污染。
完整修复代码
<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /> <title> BasemapGallery & Measurement | ArcGIS Maps SDK for JavaScript 4.26 </title> <link rel="stylesheet" href="https://js.arcgis.com/4.26/esri/themes/light/main.css" /> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } /* 新增测量工具栏样式 */ #topbar { background: rgba(255,255,255,0.9); padding: 10px; border-radius: 4px; } .action-button { margin: 0 5px; padding: 8px; border: none; border-radius: 4px; cursor: pointer; background: #fff; } .action-button.active { background: #0079c1; color: #fff; } </style> <script src="https://js.arcgis.com/4.26/"></script> <script> require([ "esri/Map", "esri/views/MapView", // 替换为MapView "esri/widgets/Expand", "esri/widgets/BasemapGallery", "esri/widgets/DistanceMeasurement2D", "esri/widgets/AreaMeasurement2D" ], (Map, MapView, Expand, BasemapGallery, DistanceMeasurement2D, AreaMeasurement2D) => { const map = new Map({ basemap: "topo-vector" }); const view = new MapView({ // 替换为MapView实例 container: "viewDiv", map: map, center: [-77.2627, 18.0927], zoom: 10 }); const basemapGallery = new BasemapGallery({ view: view, }); const bgExpand = new Expand({ view: view, content: basemapGallery }); basemapGallery.watch("activeBasemap", () => { const mobileSize = view.heightBreakpoint === "xsmall" || view.widthBreakpoint === "xsmall"; if (mobileSize) { bgExpand.collapse(); } }); view.ui.add(bgExpand, "top-left"); // 测量工具栏相关代码 view.ui.add("topbar", "top-right"); document .getElementById("distanceButton") .addEventListener("click", function () { setActiveWidget(null); if (!this.classList.contains("active")) { setActiveWidget("distance"); } else { setActiveButton(null); } }); document .getElementById("areaButton") .addEventListener("click", function () { setActiveWidget(null); if (!this.classList.contains("active")) { setActiveWidget("area"); } else { setActiveButton(null); } }); let activeWidget; // 声明activeWidget变量,避免全局污染 function setActiveWidget(type) { switch (type) { case "distance": activeWidget = new DistanceMeasurement2D({ view: view }); activeWidget.viewModel.start(); view.ui.add(activeWidget, "top-right"); setActiveButton(document.getElementById("distanceButton")); break; case "area": activeWidget = new AreaMeasurement2D({ view: view }); activeWidget.viewModel.start(); view.ui.add(activeWidget, "top-right"); setActiveButton(document.getElementById("areaButton")); break; case null: if (activeWidget) { view.ui.remove(activeWidget); activeWidget.destroy(); activeWidget = null; } break; } } function setActiveButton(selectedButton) { view.focus(); let elements = document.getElementsByClassName("active"); for (let i = 0; i < elements.length; i++) { elements[i].classList.remove("active"); } if (selectedButton) { selectedButton.classList.add("active"); } } }); </script> </head> <body> <div id="viewDiv"></div> <div id="topbar"> <button class="action-button esri-icon-measure-line" id="distanceButton" type="button" title="Measure distance between two or more points" ></button> <button class="action-button esri-icon-measure-area" id="areaButton" type="button" title="Measure area" ></button> </div> </body> </html>
内容的提问来源于stack exchange,提问作者user21045033
相关产品推荐
相关产品推荐

