系列文章目录

【1】 ArcGIS API for JS 4.x + Vue 之 显示地图和添加点线面
【2】 ArcGIS API for JS 4.x + Vue 之 显示场景(3D)、距离面积测量、光照变换、天气变换
【3】 ArcGIS API for JS 4.x + Vue 之 剖面分析、视域分析
【4】 ArcGIS API for JS 4.x + Vue 之 获取场景内要素、高亮场景图层



前言

提示:这里可以添加本文要记录的大概内容:
本文介绍的是ArcGIS API for JS 4.x版本在Vue上的使用,且假设阅读者对Vue有一定的了解。

1.假设VScode、nodejs等已经安装好了;

2.全局安装vue-cli,vue-cli可以帮助我们快速构建Vue项目;

3.安装webpack,它是打包js的工具;

4.创建Vue项目。


提示:以下是本篇文章正文内容,下面案例可供参考

获取场景内要素、高亮场景图层

安装依赖

从 ArcGIS API for JavaScript v4.18 开始,您可以尝试安装@arcgis/core并使用 ES 模块进行构建, 而不是使用 esri-loader。

npm install @arcgis/core --save

1. 添加模块

import WebScene from "@arcgis/core/WebScene";
import SceneView from "@arcgis/core/views/SceneView";
import esriConfig from "@arcgis/core/config";

import Query from "@arcgis/core/rest/support/Query";
import Legend from "@arcgis/core/widgets/Legend";

2. 引入CSS样式

@import "https://js.arcgis.com/4.22/@arcgis/core/assets/esri/themes/dark/main.css";

若要在本地导入样式可查看官方文档

3. 获取密钥

一个API 密钥是访问ArcGIS 服务所必需的。

  1. 转到你的开发人员仪表板以获取API 密钥.
  2. 复制密钥,因为它将在下一步中使用。

若没有ArcGIS账号,直接在跳转页面注册即可。(注意不要使用企鹅邮箱,如果emit长时间转圈需要搭梯子)

4. 创建场景

一个Web场景是作为一个项目存储在ArcGIS Online中的场景。Web场景项目包含了场景的所有配置设置(JSON格式),比如extent, basemap,数据层和样式。应用程序可以使用它的项目ID访问和显示Web场景。

esriConfig.apiKey = '你的API密钥'
// 创建场景
this.map = new WebScene({
  portalItem: {
    id: "b6c889ff1f684cd7a65301984b80b93d"
  }
});

5. 创建场景视图

使用一个SceneView类来设置要绘制的地图和图层。

// 创建场景视图
this.mapView = new SceneView({
  map: this.map,
  container: "viewDiv", //地图容器id
  qualityProfile: "high",
  // 设置高亮显示选项
  environment: {
    lighting: {
      directShadowsEnabled: true,
      ambientOcclusionEnabled: true
    }
  },
  // 默认情况下,高亮颜色设置为青色
  highlightOptions: {
    haloColor: [255, 38, 150],
    color: [255, 255, 255],
    fillOpacity: 0.3
  }
});

6. 获取视图范围内的要素

通过WebScene类中的allLayers.filter()方法获取指定图层。在视图更新完成后查询视图中的要素并获取其属性。

this.mapView.when(() => {
  // 获取 webScene 上的图层
  const campusSceneLayer = this.map.allLayers.filter((elem) => {
    return elem.title === "Batiments Remarquables 3D selected - Batiments Remarquables 3D selected";
  }).items[0];
  // 定义查询中使用的属性
  campusSceneLayer.outFields = ["name"];

  // 高亮设置在layerView上,所以我们需要检测layerView什么时候准备好了
  this.mapView.whenLayerView(campusSceneLayer).then((campusLayerView) => {
      this.campusLayerView = campusLayerView
    // 等待视图完成更新
    this.mapView.watch("updating", (val) => {
      if (!val) {
        // 查询可用于绘图的要素并获取属性
        const query = new Query();
        campusLayerView.queryFeatures(query).then((result) => {
          this.buildingData = []
          let count = 0
          result.features.forEach((feature) => {
            const attributes = feature.attributes;
            this.buildingData[count] = {}
            this.buildingData[count].objectId = feature.attributes.OBJECTID_1
            if(feature.attributes.Name === 'ID_18_normals_geo.dae'){
              this.buildingData[count].name = 'Tour Eiffel'
            }else{
              this.buildingData[count].name = 'Palais de Chaillot'
            }
            count++
          });
        });
      }
    });
  });
});

7. 点击高亮要素并缩放至其范围

通过SceneLayerView.queryExtent()获取到要素的3D范围,使用SceneLayerView.highlight()高亮要素。

this.highlight = null;
const queryExtent = new Query({
    objectIds: row.objectId
});
this.campusLayerView
    .queryExtent(queryExtent)
    .then((result) => {
    // 放大到该要素的范围
    // 使用扩展方法,以防止缩放太接近要素
    if (result.extent) {
        this.mapView
        .goTo(result.extent.expand(1), {
            speedFactor: 0.5
        })
        .catch((error) => {
            if (error.name != "AbortError") {
                console.error(error);
            }
        });
    }
    });
// 移除之前的高亮部分
if (this.highlight) {
    this.highlight.remove();
}
// 传递objectId给方法用于高亮要素
this.highlight = this.campusLayerView.highlight([row.objectId]);

参考例子

示例图:
请添加图片描述

代码如下(示例):

<template>
  <div>
    <div class="panel-side esri-widget">
        <h2>建筑列表</h2>
        <p id="buildingCount">{{'视图中的建筑: ' + buildingData.length + ' 栋'}}</p>
        <el-table
            :data="buildingData"
            style="width: 100%"
            @row-click="tableClick"
            :show-header="headerStatus">
            <el-table-column
                prop="name"
                align="center">
            </el-table-column>
        </el-table>
    </div>
    <div id="viewDiv"></div>
  </div>
</template>

<script>
import WebScene from "@arcgis/core/WebScene";
import SceneView from "@arcgis/core/views/SceneView";
import esriConfig from "@arcgis/core/config";

import Query from "@arcgis/core/rest/support/Query";
import Legend from "@arcgis/core/widgets/Legend";

export default {
  name: "HighlightScenelayer",
  data() {
    return {
      map: null,
      mapView: null,

      buildingData: [],
      headerStatus: false,
      highlight: null,
      campusLayerView: null,
    };
  },
  methods: {
    initMap() {
      esriConfig.apiKey =
        "你的ApiKey";
      // 创建场景
      this.map = new WebScene({
        portalItem: {
          id: "b6c889ff1f684cd7a65301984b80b93d"
        }
      });

      // 创建场景视图
      this.mapView = new SceneView({
        map: this.map,
        container: "viewDiv", //地图容器id
        qualityProfile: "high",
        // 设置高亮显示选项
        environment: {
          lighting: {
            directShadowsEnabled: true,
            ambientOcclusionEnabled: true
          }
        },
        // 默认情况下,高亮颜色设置为青色
        highlightOptions: {
          haloColor: [255, 38, 150],
          color: [255, 255, 255],
          fillOpacity: 0.3
        }
      });
    },
    getLayerFeatures() {
      this.mapView.when(() => {
        // 获取 webScene 上的图层
        const campusSceneLayer = this.map.allLayers.filter((elem) => {
          return elem.title === "Batiments Remarquables 3D selected - Batiments Remarquables 3D selected";
        }).items[0];
        // 定义查询中使用的属性
        campusSceneLayer.outFields = ["name"];

        // 高亮设置在layerView上,所以我们需要检测layerView什么时候准备好了
        this.mapView.whenLayerView(campusSceneLayer).then((campusLayerView) => {
            this.campusLayerView = campusLayerView
          // 等待视图完成更新
          this.mapView.watch("updating", (val) => {
            if (!val) {
              // 查询可用于绘图的要素并获取属性
              const query = new Query();
              campusLayerView.queryFeatures(query).then((result) => {
                this.buildingData = []
                let count = 0
                result.features.forEach((feature) => {
                  const attributes = feature.attributes;
                  this.buildingData[count] = {}
                  this.buildingData[count].objectId = feature.attributes.OBJECTID_1
                  if(feature.attributes.Name === 'ID_18_normals_geo.dae'){
                    this.buildingData[count].name = 'Tour Eiffel'
                  }else{
                    this.buildingData[count].name = 'Palais de Chaillot'
                  }
                  count++
                });
              });
            }
          });
        });
      });
    },
    tableClick(row, column, event){
        this.highlight = null;

        const queryExtent = new Query({
            objectIds: row.objectId
        });
        this.campusLayerView
            .queryExtent(queryExtent)
            .then((result) => {
            // 放大到该要素的范围
            // 使用扩展方法,以防止缩放太接近要素
            if (result.extent) {
                this.mapView
                .goTo(result.extent.expand(1), {
                    speedFactor: 0.5
                })
                .catch((error) => {
                    if (error.name != "AbortError") {
                        console.error(error);
                    }
                });
            }
            });
        // 移除之前的高亮部分
        if (this.highlight) {
            this.highlight.remove();
        }
        // 传递objectId给方法用于高亮要素
        this.highlight = this.campusLayerView.highlight([row.objectId]);
    },
  },
  mounted() {
    this.initMap();
    this.getLayerFeatures();
  },
};
</script>

<style scoped>
@import "https://js.arcgis.com/4.22/@arcgis/core/assets/esri/themes/dark/main.css";
#viewDiv {
  height: 100vh;
  width: 100%;
}

.panel-side {
  width: 250px;
  position: absolute;
  top: 14px;
  right: 14px;
  bottom: 28px;
  color: #323232;
  background-color: rgb(255, 255, 255);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  overflow: auto;
  z-index: 60;
  font-size: 12px;
  text-align: center;
}

.panel-side h2 {
  padding: 0 20px;
  margin: 20px 0;
  font-size: 14px;
  font-weight: 600;
}

#buildingCount,
h2 {
  text-align: center;
}
</style>

Logo

前往低代码交流专区

更多推荐