好吧,我都要吐了。

接连三个例子都是类似的套路,使用某个查询参数类的实例,结合对应的Task类,对返回值进行取值、显示。

这个例子是Identify识别,使用了TileLayer这种图层,数据来自Server的MapServer。


结果演示

戳不同的地方会有不同的识别结果。

我对TileLayer不是很了解,这一例仅针对有了解的同学,做一个IdentifyTask的解释。


IdentifyTask/IdentifyParameter/IdentifyResult三个类

既然是一样的套路,那么先对这三个类有了解的话就会好说很多吧。

IdentifyTask

当前,IdentifyTask不能在SceneView和dynamic layers中使用。有关Identify是什么,请【点我】

 其执行成功的返回值包括有一个IdentifyResult[]。

IdentifyParameters

本例中用到的属性有:tolerance(Number)、mapExtent(Extent类)、layerId(Number[])、layerOption(String)、width(Number)、height(Number)、geometry(Geometry类);

分别意义是:屏幕像素与应被识别的几何体之间的距离;地图外框;需要被识别的图层的ID号;哪些图层需要被识别(默认顶层图层),是个枚举量;view的长宽。

IdentifyResult

本例中用到IdentifyResult的属性有:

layerName(String类)、feature(Geometry类)

后者是识别得到的几何体,前者是包括后者的图层的图层名。


给出引用

require([
"esri/Map",
"esri/views/MapView",
"esri/layers/TileLayer",
"esri/tasks/IdentifyTask",
"esri/tasks/support/IdentifyParameters",
"dojo/_base/array",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
],
function(
Map, MapView, TileLayer,
IdentifyTask, IdentifyParameters,
arrayUtils, on, dom
)
}

不解释,和前两篇类似。

函数参数骨架

function(Map, MapView, TileLayer, IdentifyTask, IdentifyParameters, arrayUtils, on, dom){

    var identifyTask, params;
var soilURL = "https://services.arcgisonline.com/arcgis/rest/services/Specialty/Soil_Survey_Map/MapServer";
    var parcelsLyr = new TileLayer({...});
var map = new Map({...});
map.add(parcelsLyr); var view = new MapView({...});
view.then(function(){...}); //每次点击地图时,就会处理一次的方法体
function executeIdentifyTask(event){...}
}

看起来也不是很复杂的样子,嗯,时间不早了,先吃个晚饭,晚上回来继续写完第七章。

好的我吃完了,咱们继续学习Identify这个例子。

首先是根据soilURL这个MapServer地址生成一个TileLayer,名为parcelsLyr,把它添加到实例化的Map中。

在MapView对象创建完成后,紧接着一个异步操作,下面就对MapView对象的回调函数进行解释:

view.then(function() {
on(view, "click", executeIdentifyTask); identifyTask = new IdentifyTask(soilURL); params = new IdentifyParameters();
params.tolerance = 3;
params.layerIds = [0, 1, 2];
params.layerOption = "top";
params.width = view.width;
params.height = view.height;
});

每当点击view的时候,触发click事件executeIdentifyTask()。

然后就实例化一个IdentifyTask对象和一个IdentifyParameters对象,并对IdentifyParameters对象赋值(属性)。

于是这个例子最大头的executeIdentifyTask()方法体就是核心了,先把它骨架化:

function executeIdentifyTask(event) {
params.geometry = event.mapPoint;
params.mapExtent = view.extent;
dom.byId("viewDiv").style.cursor = "wait"; identifyTask.execute(params)
.then(function(response) {..这里很长..})
.then(showPopup); function showPopup(response){...}
}

首先呢,获取一些必要的参数,传递给IdentifyParameters(geometry属性和mapExtent属性)

然后执行IdentifyTask的execute()方法,这个方法有两个异步操作,第一个异步操作的回调函数非常的长,还得继续往下拆。

第二个回调函数待第一个回调函数完成后,显示一个弹窗。

那么【第一个回调函数】继续拆解如下:

.then(function(response) {

  var results = response.results;

  return arrayUtils.map(results, function(result) {

    var feature = result.feature;
var layerName = result.layerName; feature.attributes.layerName = layerName;
if (layerName === 'Soil Survey Geographic') {
feature.popupTemplate = {...};
}
else if (layerName === 'State Soil Geographic') {
feature.popupTemplate = {...};
}
else if (layerName === 'Global Soil Regions') {
feature.popupTemplate = {...};
}
return feature;
});
})

从response中获取results属性,该属性为Object数组,装箱为IdentifyResult类型的数组。(同上例)

紧接着返回arrayUtils.map方法遍历results(IdentifyResult数组)得到的feature集合(Geometry类型)。

arrayUtils.map()方法遍历得到的是Geometry数组。

这个map()方法里做了什么呢?

首先,获取IdentifyResult数组其中的IdentifyResult元素中的一个属性——feature(Graphic类型),然后对不同的IdentifyResult对象的LayerName,设置feature不同的弹窗模板。

————是不是很乱?

1. 遍历IdentifyResult[]中的每一个IdentifyResult;//别问我IdentifyResult[]怎么来的,从response中来的。见上一篇博客。

2. 对于每一个IdentifyResult,它有两个属性:feature(Graphic类型)和layerName(String类型);

3. 对于每一个IdentifyResult,如果layerName不同,那么对应的feature的弹窗信息格式(即popupTemplate)肯定不同;

4. 三个分支,对不同layerName的IdentifyResult,其feature就设置不同的popupTemplate;

5. 返回此IdentifyResult的feature。

这一层回调函数就算OK了。因为feature是Graphic类型的,所以map返回的就是Graphic[]类型的。

题外话,其实ESRI这样写很绕,虽然充分利用了JS的灵活和强大,但是代码解读起来就非常困难,函数能作为变量到处嵌套。

【第二个回调函数】

.then(showPopup);

function showPopup(response) {
if (response.length > 0) {
view.popup.open({
features: response,
location: event.mapPoint
});
}
dom.byId("viewDiv").style.cursor = "auto";
}

这回终于把回调函数写出来了。

第二层回调函数的response参数是什么呢?

可以看到,把response赋给了popup的features属性了,可知response是Graphic[]类型的,这与上一个then返回的值一致。

这样,就能利用第一个回调函数中设置好的popupTemplate进行不同格式的弹窗了。

关于第一个回调函数的弹窗popupTemplate不作详细解释了,因为这已经够绕了。我在文末给出整个js代码以供需要的同学参考。

总结一下

本例,仍然是对某某Result中的Graphic或者Geometry的属性进行读取或者操作。

和上两篇是类似的,空间查询的重点就是某某Task和某某Parameters和某某Result的交叉使用:

某某Task.execute(某某Parameters)

.then(回调函数处理某某Result)

.then(..)....

至于怎么处理这个Result中的feature,官方的例子写的很明确了,但是值类型就很隐晦。

因为JS的弱类型性,导致这些值类型十分模糊,所以绕、晕也是正常的,我已经尽我所能把每个关键的地方的值类型进行解释和说明了,希望大家能看懂我的胡言乱语。

好了,第七章空间查询的内容并不是很多,这几个Task肯定很有用,我在写完第八章空间查询后会对其进行一个比较全面的解释。

第八章见!

附上这例子的全代码:

  <script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/TileLayer",
"esri/tasks/IdentifyTask",
"esri/tasks/support/IdentifyParameters",
"dojo/_base/array",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
], function(
Map, MapView, TileLayer,
IdentifyTask, IdentifyParameters,
arrayUtils, on, dom
) { var identifyTask, params; // URL to the map service where the identify will be performed
var soilURL =
"https://services.arcgisonline.com/arcgis/rest/services/Specialty/Soil_Survey_Map/MapServer"; // Add the map service as a TileLayer for fast rendering
// Tile layers are composed of non-interactive images. For that reason we'll
// use IdentifyTask to query the service to add interactivity to the app
var parcelsLyr = new TileLayer({
url: soilURL,
opacity: 0.85
}); var map = new Map({
basemap: "osm"
});
map.add(parcelsLyr); var view = new MapView({
map: map,
container: "viewDiv",
center: [-120.174, 47.255],
zoom: 7
}); view.then(function() {
// executeIdentifyTask() is called each time the view is clicked
on(view, "click", executeIdentifyTask); // Create identify task for the specified map service
identifyTask = new IdentifyTask(soilURL); // Set the parameters for the Identify
params = new IdentifyParameters();
params.tolerance = 3;
params.layerIds = [0, 1, 2];
params.layerOption = "top";
params.width = view.width;
params.height = view.height;
}); // Executes each time the view is clicked
function executeIdentifyTask(event) {
// Set the geometry to the location of the view click
params.geometry = event.mapPoint;
params.mapExtent = view.extent;
dom.byId("viewDiv").style.cursor = "wait"; // This function returns a promise that resolves to an array of features
// A custom popupTemplate is set for each feature based on the layer it
// originates from
identifyTask.execute(params).then(function(response) { var results = response.results; return arrayUtils.map(results, function(result) { var feature = result.feature;
var layerName = result.layerName; feature.attributes.layerName = layerName;
if (layerName === 'Soil Survey Geographic') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "{Map Unit Name}",
content: "<b>Dominant order:</b> {Dominant Order} ({Dom. Cond. Order %}%)" +
"<br><b>Dominant sub-order:</b> {Dominant Sub-Order} ({Dom. Cond. Suborder %}%)" +
"<br><b>Dominant Drainage Class:</b> {Dom. Cond. Drainage Class} ({Dom. Cond. Drainage Class %}%)" +
"<br><b>Farmland Class:</b> {Farmland Class}"
};
}
else if (layerName === 'State Soil Geographic') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "{Map Unit Name}",
content: "<b>Dominant order:</b> {Dominant Order} ({Dominant %}%)" +
"<br><b>Dominant sub-order:</b> {Dominant Sub-Order} ({Dominant Sub-Order %}%)"
};
}
else if (layerName === 'Global Soil Regions') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: layerName,
content: "<b>Dominant order:</b> {Dominant Order}" +
"<br><b>Dominant sub-order:</b> {Dominant Sub-Order}"
};
}
return feature;
});
}).then(showPopup); // Send the array of features to showPopup() // Shows the results of the Identify in a popup once the promise is resolved
function showPopup(response) {
if (response.length > 0) {
view.popup.open({
features: response,
location: event.mapPoint
});
}
dom.byId("viewDiv").style.cursor = "auto";
}
}
});
</script>

script标签

ArcGIS API for JavaScript 4.2学习笔记[24] 【IdentifyTask类】的使用(结合IdentifyParameters类)(第七章完结)的更多相关文章

  1. ArcGIS API for JavaScript 4.2学习笔记[27] 网络分析之最短路径分析【RouteTask类】

    要说网页端最经典的GIS应用,非网络分析莫属了. 什么?你没用过?百度高德谷歌地图的路线分析就是活生生的例子啊!只不过它们是根据大实际背景优化了结果显示而已. 这个例子使用RouteTask进行网络分 ...

  2. ArcGIS API for JavaScript 4.2学习笔记[28] 可视域分析【使用Geoprocessor类】

    想知道可视域分析是什么,就得知道可视域是什么 我们站在某个地方,原地不动转一圈能看到的所有事物就叫可视域.当然平地就没什么所谓的可视域. 如果在山区呢?可视范围就会被山体挡住了.这个分析对军事上有十分 ...

  3. ArcGIS API for JavaScript 4.2学习笔记[26] 缓冲区分析【基于geometryEngine工具类】

    要说GIS空间分析最经典的例子,就是缓冲区分析了. 本例使用geometryEngine来绘制缓冲区环.因为官方给的例子有3D和2D场景,所以就会显得比较复杂. 当鼠标在视图上点击时,就会生成一个缓冲 ...

  4. ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录

    放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 4.2全线基础学习请点击[直达] 4.3及更高版本的补充学习请关注我的博客. ArcGIS API for JavaScr ...

  5. ArcGIS API for JavaScript 4.2学习笔记[1] 显示地图

    ArcGIS API for JavaScript 4.2直接从官网的Sample中学习,API Reference也是从官网翻译理解过来,鉴于网上截稿前还没有人发布过4.2的学习笔记,我就试试吧. ...

  6. ArcGIS API for JavaScript 4.2学习笔记[5] 官方API大章节概述与内容转译

    内容如上,截图自ESRI官网,连接:ArcGIS API for JavaScript 4.2 [Get Started] 类似于绪论一样的东西,抽取了最需要关注的几个例子.如:加载Map和View, ...

  7. ArcGIS API for JavaScript 4.2学习笔记[21] 对3D场景上的3D要素进行点击查询【Query类学习】

    有人问我怎么这个系列没有写自己做的东西呢? 大哥大姐,这是"学习笔记"啊!当然主要以解读和笔记为主咯. 也有人找我要实例代码(不是示例),我表示AJS尚未成熟,现在数据编辑功能才简 ...

  8. ArcGIS API for JavaScript 4.2学习笔记[7] 鹰眼(缩略图的实现及异步处理、Promise、回调函数、监听的笔记)

    文前说明:关于style就是页面的css暂时不做评论,因为官方给的例子的样式实在太简单了,照抄阅读即可. 这篇文章有着大量AJS 4.x版本添加的内容,如监听watch.Promise对象.回调函数. ...

  9. ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类

    Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...

随机推荐

  1. memcached复制-repcached

    1.前言 由于memcached把数据都放到内存里,因此性能是极高的,正因为如此,不可避免会造成数据丢失,repcached就派上用场了,它可以实现memcached的主从复制 2.安装repcach ...

  2. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

  3. PAT B1045 快速排序(25)

    1045. 快速排序(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 著名的快速排序算法里有一个经典的划分 ...

  4. mysql索引优化面试题

    曾经偷偷的面试了两个单位,都提到了Mysql的优化问题,所以以后要多多学习数据库的优化知识了.建设数据库的优化大概主要就是索引的优化了吧,因为我们不可能修改数据结构的情况下,提高数据库的查询效率似乎也 ...

  5. window下phpstudy的nginx配置虚拟主机

    由于很长时间没有配置Apache,虽然说知道怎么配置nginx,但是还是花费了一些时间这次记下来下次直接用 在其他选项文件菜单中->打开配置文件->选择vhosts-conf nginx的 ...

  6. lnmp1.3 配置pathinfo---thinkphp3.2 亲测有效

    lnmp1.3环境下配置pathinfo模式试了很多方法,都以失败告终,博主被这个问题困扰了很久,终于解决了!现记录如下: 1.打开php.ini 通常该文件在 /usr/local/php/etc/ ...

  7. 05.haproxy+mysql负载均衡 整合 redis集群+ssm

    本篇重点讲解haproxy+mysql负载均衡,搭建完成后与之前搭建的redis+ssm进行整合 (注:这里用到了两台mysql数据库,分别安装两台虚拟机上,已经成功实现主主复制,如果有需要,请查看我 ...

  8. jupyter的交互小工具-----ipyleaflet

    ipyleaflet(一个用于创建简单的交互式地图的平移和缩放的库,ipyleaflet支持诸如多边形,标记和更一般的任何地理编码地理数据结构的注释) from ipyleaflet import M ...

  9. Windows下docker的安装,将ASP.NET Core程序部署在docker中

    参考文章: https://www.cnblogs.com/jRoger/p/aspnet-core-deploy-to-docker.html https://www.cnblogs.com/jRo ...

  10. python 序列:字符串、列表、元组

    python 序列:字符串.列表.元组   序列:包含一定顺序排列的对象的一个结构 内建函数:str() list() tuple() 可以使用str(obj)可以把对象obj转换成字符串 list( ...