You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArcGIS JavaScript API测量组件失效问题排查及修复咨询

ArcGIS JS API测量组件失效问题排查与修复

问题原因

  1. 视图类型不兼容:你使用了SceneView(3D场景视图),但DistanceMeasurement2D和AreaMeasurement2D是专门为MapView(2D平面视图)设计的组件,二者无法兼容,直接导致测量交互完全失效,无法选择测量点、不显示测量线条。
  2. 缺少按钮容器样式:代码中未给#topbar添加基础样式,测量按钮可能存在显示错位、不可点击的情况。
  3. 变量未声明:原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:42:26