ArcGIS API for JavaScript 4.2学习笔记[20] 使用参数查询要素(油井和地震关系)
这个例子相当复杂。我先简单说说这个例子是干啥的。
在UI上,提供了一个下拉框、两个滑动杆,以确定三个参数,使用这三个参数进行空间查询。这个例子就颇带空间查询的意思了。
第一个参数是油井类型,第二个参数是油井的缓冲半径,第三个参数是地震级别。
给定油井的类型,给定油井的缓冲半径(缓冲区分析生成),给定地震级别,就能在油井附近以这个缓冲半径为圆搜索出符合给定地震级别的地震点。
这个例子是干嘛的呢?
“因为开采油田会导致地下空间坍塌,而引发地震。”
看看搜索结果(随便选的参数):

橙色点即为搜索结果(地震点)。
给出引用
话不多说,看看这个例子的引用有多少:
require(
[
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/layers/GraphicsLayer",
"esri/geometry/geometryEngine",
"esri/Graphic",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleMarkerSymbol", "dojo/on",
"dojo/dom",
"dojo/dom-construct",
"dojo/domReady!"
],
function(...){...}
);
用到了两种Layer,FeatureLayer是数据图层,GraphicsLayer是缓冲区图层和结果显示图层。
为了支持GraphicsLayer的缓冲区,需要用到geometryEngine模块和Graphics模块。
为了支持结果显示,用到了SimpleFillSymbol模块和SimpleMarkerSymbol模块。
函数参数骨架
function(Map, MapView, FeatureLayer, GraphicsLayer, Graphics, SimpleFillSymbol, SimpleMarkerSymbol)
{
var quakesUrl = "...";
var wellBuffer,wellsGeometries,magnitude; //获取dom元素
var wellTypeSelect = dom.byId("well-type");
var magSlider = dom.byId("mag");
var distanceSlider = dom.byId("distance"); //FeatureLayer&GraphicsLayer定义
var wellsLayer = new FeatureLayer({...});
var quakesLayer = new FeatureLayer({...});
var resultsLayer = new GraphicsLayer({...}); var map = new Map({...});
var view = new MapView({...});
view.ui.add("infoDiv", "top-right");
view.then(function(){...}); //功能方法
function getValues(response){...}
function getUniqueValues(values){...}
function addToSelect(values){...}
function setWellsDefinitionExpression(newValue){...}
function queryForWellGeometries(){...}
function createBuffer(wellPoints){...} //事件
on(magSlider, "input", function(){...});
on(distanceSlider, "input", function(){...});
on(distanceSlider, "change", function(){...});
on(wellTypeSelect, "change", function(evt){...});
on(dom.byId("query-quakes"), "click", function(){...}); //其余方法
function queryEarthquakes(){...}
function displayResults(results){...}
)
函数参数骨架
可吓坏我了,这么庞大的骨架(script标签就有200+行)。
经过我一个月的细读,我终于把这些流程大概弄懂了,如下图:

有些地方表述可能不太对。
分为两块,一块是事件体,另一块是函数体。
先讲简单的吧,事件体。
事件体
wellTypeSelect和distanceSlider这两个dom元素的change事件体都会独立触发createBuffer()函数体,wellTypeSelect事件则会先触发setWellsDefinitionExpression()函数体进行遍历搜索几何体,然后把返回值(地震点的几何体集合wellsGeometries)交给createBuffer()函数体,生成缓冲区。
意思是只要油井类型(下拉列表的项目改变)和距离滑块改变,缓冲区就要进行重绘。
distanceSlider的input事件会改变DOM上的数值,为缓冲区半径的数值。
magSlider的input事件会改变DOM上的数值,为地震级别的数值。
queryQuakes按钮的click事件会通过已经生成的缓冲区进行叠置分析,搜索缓冲区内的地震点。
对大量的变量如果不是很懂,这里可以先缓缓,下面的函数体会更详细介绍,事件体主要明白DOM的事件能干啥就行了。
函数体
有几个函数体是连锁反应的,而且是在MapView的then中进行连锁异步操作的。
在这里我又不得不提一下异步操作和这个then的用法了。
then的含义就是,等then前面的操作在服务器上做完后,再执行then里面的内容。
因为js是单线程的解释型语言,不会编译,只会从头到尾一次读下来,所以执行到then前面的代码时,是不可能停在那里的。
then前面的代码执行完肯定有一个类似回执的东西(可以理解为返回值),但是浏览器不能一直等待这个回执啊?
所以就在then里面写一个回调函数,丢给服务器,在服务器端等待then前的操作完成后,再把“返回值”返还给回调函数做,即可。
then()里的东西不会立刻在本地执行,在本地等待前一步的操作结果只会让浏览器卡死。
实际上,我标红的关键词,就是异步操作的思想了。
复习完异步操作和then,我们再看看view的那一串then:
view.then(function() {
return wellsLayer.then(function() {
var query = wellsLayer.createQuery();
return wellsLayer.queryFeatures(query);
});
})
.then(getValues)
.then(getUniqueValues)
.then(addToSelect)
.then(createBuffer);
我直接给出我的解读:首先,view加载完后,执行第一个then,第一个then返回wellsLayer的空间搜索(queryFeatures()这个方法)结果,这个结果是FeatureSet类型的,名为response。这response在哪用呢?它传递给了getValues()这个方法体:
function getValues(response) {
var features = response.features;
var values = features.map(function(feature) {
return feature.attributes.STATUS2;
});
return values;
}
经查,response确实就是FeatureSet类的实例,通过getValues获取其内所有features的所有STATUS2字段的值,名为values,类型为AJS中的Collection类型。
values又传递给getUniqueValues()方法体:
function getUniqueValues(values) {
var uniqueValues = [];
values.forEach(function(item, i) {
if ((uniqueValues.length < 1 || uniqueValues.indexOf(item)===-1) && (item !== "")) {
uniqueValues.push(item);
}
});
return uniqueValues;
}
根据某些规则(if语句)遍历values,使用Collection类的forEach方法,然后把遍历结果作为JS的数组返回,名为uniqueValues,传递给
addToSelect()方法体,实现选择列表这个DOM元素上出现油井类型(option):
function addToSelect(values) {
values.sort();//排序
values.forEach(function(value) {
var option = domConstruct.create("option");
option.text = value;
wellTypeSelect.add(option);//给下拉列表添加选项
return setWellsDefinitionExpression(wellTypeSelect.value);
});
不能光添加呀!所以它就return了,方法setWellsDefinitionExpression()的结果。
setWellsDefinitionExpression()这个方法是设置wellsLayer的SQL查询语句的,但是没完,setWellsDefinitionExpression()这个方法内还有一层return:
function setWellsDefinitionExpression(newValue) {
wellsLayer.definitionExpression = "STATUS2 = '" + newValue + "'";
if (!wellsLayer.visible) {
wellsLayer.visible = true;
}
return queryForWellGeometries();
}
function queryForWellGeometries() {
var wellsQuery = wellsLayer.createQuery();
return wellsLayer.queryFeatures(wellsQuery)
.then(function(response) {
wellsGeometries = response.features.map(function(feature) {
return feature.geometry;//返回某个要素的几何体
});
return wellsGeometries;//返回所有的几何体(作为集合)
});
}
queryForWellGeometries()这个方法是setWellsDefinitionExpression()这个方法必定会触发的方法体,它用于搜索wellsLayer中的几何体。
空间查询要点
注意到了吗?空间查询是需要某个Layer的query对象的。
在wellsLayer中,使用createQuery()方法就能返回一个query对象,query对象包含了所有用于空间查询(搜索)用的信息,通过它,才能使用queryFeatures等方法对需要进行空间查询(搜索)的图层进行空间查询(搜索)。
所以图中的连串的then对应的方法体就已经解释完毕了。(呼呼~不知道各位能不能坚持到这,也不知道各位能不能看懂...)
还剩三个方法体,createBuffer()、queryEarthQuakes()和displayResults()方法体。
先来看看createBuffer():
function createBuffer(wellPoints) {
var bufferDistance = parseInt(distanceSlider.value);
var wellBuffers = geometryEngine.geodesicBuffer(wellPoints, [
bufferDistance
], "meters",
true);
wellBuffer = wellBuffers[0];
var bufferGraphic = new Graphic({
geometry: wellBuffer,
symbol: new SimpleFillSymbol({
outline: {
width: 1.5,
color: [255, 128, 0, 0.5]
},
style: "none"
})
});
view.graphics.removeAll();
view.graphics.add(bufferGraphic);
}
从DOM元素中获取缓冲区半径,然后用geometryEngine这个工具集(或者叫类,还没到空间分析章节就不说那么多了)中的geodesicBuffer方法产生缓冲区,数据是传入的参数wellPoints,即上面addToSelect()方法中最后一层返回的几何体集合(油井点集合)。
然后实例化Graphic实例,设置颜色、线宽,然后添加到view中的graphics容器内即可。
再看queryEarthQuakes()和displayResults():
function queryEarthquakes() {
var query = quakesLayer.createQuery();
query.where = "mag >= " + magSlider.value;
query.geometry = wellBuffer;
query.spatialRelationship = "intersects";
return quakesLayer.queryFeatures(query);
}
function displayResults(results) {
resultsLayer.removeAll();
var features = results.features.map(function(graphic) {
graphic.symbol = new SimpleMarkerSymbol({
style: "diamond",
size: 6.5,
color: "darkorange"
});
return graphic;
});
var numQuakes = features.length;
dom.byId("results").innerHTML = numQuakes + " earthquakes found";
resultsLayer.addMany(features);
}
前一个设置query(又是query!)的信息,返回quakesLayer搜索的结果(看下一个方法,应该是FeatureSet类型的),结果传递给displayResults(在按钮的click事件中通过then异步传递),名为results。
在后一个方法体中,使用map方法遍历要素中所有几何体,设置线宽和色彩等符号样式,最后在DOM元素上刷新显示搜索得到了多少个地震点“numQuakes earthquakes found”,并在结果图层中添加这些要素,刷新显示。
最后两个其实就是通过上方生成的缓冲区进行空间查询(搜索),得到结果并刷新显示的过程。
至此,本例就全部解释完毕了,至于有些变量是什么,看new的类型就知道啦,一路看我的文章应该都懂的。
————
感言:一个月了,好拖啊...4.3都出了这么久了,才把这个例子攻克。嗯,接下来的例子就不会那么又臭又长了...
总结一下
本例通过对图层的query对象的使用,以及结合空间分析中的缓冲区(使用geometryEngine),进一步加深了异步操作和遍历的代码理解。
要说能符合本章空间查询(搜索)的核心代码,也不过是wellsLayer.createQuery()这一句代码和query对象的属性设置了,Graphics的操作(遍历、属性设置)和结果的互相传递都不是本章的重点,所以导致了这个例子阅读困难。
大致流程为:从featureLayer中获取字段值,并加到下拉选择列表中——选择某个油井类型,设置缓冲半径,后台获取油井的点几何体集合,生成缓冲区——使用缓冲区,和设置好的地震级别,进行空间查询,得到地震点的搜索结果,刷新显示。
over!
ArcGIS API for JavaScript 4.2学习笔记[20] 使用参数查询要素(油井和地震关系)的更多相关文章
- ArcGIS API for JavaScript 4.2学习笔记[20] 使用缓冲区结合Query对象进行地震点查询【重温异步操作思想】
这个例子相当复杂.我先简单说说这个例子是干啥的. 在UI上,提供了一个下拉框.两个滑动杆,以确定三个参数,使用这三个参数进行空间查询.这个例子就颇带空间查询的意思了. 第一个参数是油井类型,第二个参数 ...
- ArcGIS API for JavaScript 4.2学习笔记[30] 点和线高程查询(第八章完结)
终于到最后一篇了,可喜可贺. 本例先说明了如何进行单点的高程差分析,然后说明了道路的起伏分析.前者很直观地比较了两个年份的高程数据之间的差值,体现山区的高程变化(有啥用啊?)后者,一条路上的起点终点起 ...
- ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录
放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 4.2全线基础学习请点击[直达] 4.3及更高版本的补充学习请关注我的博客. ArcGIS API for JavaScr ...
- ArcGIS API for JavaScript 4.2学习笔记[1] 显示地图
ArcGIS API for JavaScript 4.2直接从官网的Sample中学习,API Reference也是从官网翻译理解过来,鉴于网上截稿前还没有人发布过4.2的学习笔记,我就试试吧. ...
- ArcGIS API for JavaScript 4.2学习笔记[5] 官方API大章节概述与内容转译
内容如上,截图自ESRI官网,连接:ArcGIS API for JavaScript 4.2 [Get Started] 类似于绪论一样的东西,抽取了最需要关注的几个例子.如:加载Map和View, ...
- ArcGIS API for JavaScript 4.2学习笔记[21] 对3D场景上的3D要素进行点击查询【Query类学习】
有人问我怎么这个系列没有写自己做的东西呢? 大哥大姐,这是"学习笔记"啊!当然主要以解读和笔记为主咯. 也有人找我要实例代码(不是示例),我表示AJS尚未成熟,现在数据编辑功能才简 ...
- ArcGIS API for JavaScript 4.2学习笔记[16] 弹窗自定义功能按钮及为要素自定义按钮(第五章完结)
这节对Popups这一章的最后两个例子进行介绍和解析. 第一个[Popup Actions]介绍了弹窗中如何自定义工具按钮(名为actions),以PopupTemplate+FeatureLayer ...
- ArcGIS API for JavaScript 4.2学习笔记[7] 鹰眼(缩略图的实现及异步处理、Promise、回调函数、监听的笔记)
文前说明:关于style就是页面的css暂时不做评论,因为官方给的例子的样式实在太简单了,照抄阅读即可. 这篇文章有着大量AJS 4.x版本添加的内容,如监听watch.Promise对象.回调函数. ...
- ArcGIS API for JavaScript 4.2学习笔记[19] 搜索小部件——使用更多数据源
上一篇中提到,空间搜索小部件是Search这个类的实例化,作为视图的ui属性添加进去后,视图就会出现搜索框了. 这节的主体代码和上篇几乎一致,区别就在上篇提及的sources属性. 先看看结果: 由于 ...
随机推荐
- FineUIMvc随笔(4)自定义回发参数与自定义回发
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 不能忘却的回发 在上一篇文章中,我们对FineUIMvc中的回发进行了详细描述,目的是为了告诉大家: 1. FineUIMvc中 ...
- JAVA学习之动态代理
JDK1.6中的动态代理 在Java中Java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成一个动态代理对象.JDK提供 ...
- java 线程中断机制
上一篇文章我们了解过了java有关线程的基本概念,有线程的属性,线程可能处于的状态,还有线程的两种创建的方式,最后还说了一个关键字synchronized,解决了高并发导致数据内容不一致问题,本篇文章 ...
- ActiveMQ学习系列(四)----消息持久化到mysql
前记:目前学习还比较杂乱,还未找到系统化地学习ActiveMq的方法.在网上看到消息持久化的demo,了解了一下,在此记录. 一.目前ActiveMq支持的持久化方法 url:http://activ ...
- java算法 蓝桥杯(题+答案) 方格填数
6.方格填数 (结果填空) 如下的10个格子 (如果显示有问题,也可以参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案 ...
- Java集合ArrayList源码解读
最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见. :) 内部原理 ArrayList 的3个字段 priva ...
- 清理浏览器网站缓存的几种方法(meta,form表单,ajax)
1.meta方法 HTML header中加入 <meta http-equiv="pragma" content="no-cache"> 说明 ...
- const与readonly
readonly 关键字与 const: const 字段只能在该字段的声明中初始化.readonly 字段可以在声明或构造函数中初始化. 因此,根据所使用的构造函数,readonly 字段可能具有不 ...
- 利用Arcgis for javascript API绘制GeoJSON并同时弹出多个Popup
1.引言 由于Arcgis for javascript API不可以绘制Geojson,并且提供的Popup一般只可以弹出一个,在很多专题图制作中,会遇到不少的麻烦.因此本文结合了两个现有的Arcg ...
- 深入浅出数据结构C语言版(3)——递归简论
相信学习过C语言的读者都已经接触过递归(不论是谭浩强的C程序设计还是C Primer Plus都有递归程序),本文就是对递归的基本原则进行简要介绍.首先,我们写一个基本的递归函数作为例子: int ...