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

要说GIS空间分析最经典的例子,就是缓冲区分析了。

本例使用geometryEngine来绘制缓冲区环。因为官方给的例子有3D和2D场景,所以就会显得比较复杂。

当鼠标在视图上点击时,就会生成一个缓冲区环(以点击的点为中心);

当鼠标拖拽时,若不是漫游状态,则缓冲区环也会跟着一起动。

我会把生成缓冲区的核心代码用大标题红色标出,各位可以直接跳到那里学缓冲区的生成。



首先了解一下,缓冲区是以什么样的东西存在的?

在桌面GIS里,缓冲区就是一个面要素,可以是要素类也可以是shp文件。

在AJS里,缓冲区是一个Polygon或Polygon[],存在于GraphicsLayer图层对象中。

在正式看这个例子之前,需要了解一个极为重要的工具类:geometryEngine。它提供了数十种空间分析方法,如buffer()、clip()、intersect()等等等等。

在这里就只用到了geodesicBuffer()。//至于geodesicBuffer()和buffer()的区别是什么,暂时还不得知,待查。

好了,有了这些预备知识,我们就可以开始了!

结果展示

在Navigation Mode复选框没有点选之前,对当前地图框点击或者拖拽会生成一个以点击点为中心的缓冲区圆环。

给出引用

var chkMapView = false, chkSceneView = false;require([
    "esri/Map", "esri/views/SceneView",  "esri/views/MapView",
    "esri/layers/GraphicsLayer", "esri/Graphic",
    "esri/symbols/SimpleMarkerSymbol","esri/symbols/SimpleFillSymbol",
    "esri/geometry/geometryEngine",
    "dojo/on",
    "dojo/dom",
    "dojo/domReady!"
  ],
  function(
    Map,SceneView,MapView,
    GraphicsLayer,Graphic,
    SimpleMarkerSymbol,SimpleFillSymbol,
    geometryEngine,
    on, dom
  ){...}
);

哇2D3D同时用好酷炫。

注意:注意:注意:require上方多了两个bool类型的变量,有什么用,下面会说。

关键就是geometryEngine了。

思路

因为这个例子的多余代码太多了,我就先讲讲思路吧,否则读者会被绕晕。

点击视图——获取点位——传入geometryEngine的geodesicBuffer()方法——返回Polygon到GraphicsLayer——刷新view的显示。

骨架

function(...)
{
    var map = new Map({...});
    var view3d = new SceneView({...});
    var view2d = new MapView({...});
    var polySym = new SimpleFillSymbol({...});    var pointSym = new SimpleMarkSymbol({...});

    var bufferLayer = new GraphicsLayer();
    var pointLayer = new GraphicsLayer();

    map.addMany([bufferLayer, pointLayer]);

    view2d.on(‘drag‘, function(evt){...});
    view3d.on(‘drag‘, function(evt){...});
    view2d.on("click", function(evt){...});
    view3d.on(‘click‘, function(evt){...});

    function bufferPoint(point){...}
    function clearGraphics(){...}

    on(dom.byId("chkBoxMap"), "click", function(evt){...});
    on(dom.byId("chkBoxScene"), "click", function(evt){...});
}

除去6个事件方法体,和老生常谈的map、view,就只有polySym和pointSym这两个符号对象、两个几何图层、两个功能函数,并不是很难理解这个例子。

//题外话:老外估计写这个demo也是交叉混写的,双引号和单引号随便用,同一章不同例子的函数参数名有时候也是随便写,可能是js的语言特性吧。

在这里,polySym和pointSym两个对象的作用仅仅是显示鼠标点击点和生成缓冲区的圆区域,不作为重点,但是具体代码还是给有需要的人看看:

var polySym = new SimpleFillSymbol({
  color: [140, 140, 222, 0.5],
  outline: {
    color: [0, 0, 0, 0.5],
    width: 2
  }
});

var pointSym = new SimpleMarkerSymbol({
  color: [255, 0, 0],
  outline: {
    color: [255, 255, 255],
    width: 1
  },
  size: 7
});

两个符号对象

先讲讲两个方法体有什么作用吧:

两个方法体:生成缓冲区与清理图层

function bufferPoint(point) {
  clearGraphics();

  pointLayer.add(new Graphic({
    geometry: point,
    symbol: pointSym
  }));

  var buffer = geometryEngine.geodesicBuffer(point, 560, "kilometers");
  bufferLayer.add(new Graphic({
    geometry: buffer,
    symbol: polySym
  }));
}

function clearGraphics() {
  pointLayer.removeAll();
  bufferLayer.removeAll();
}

后面一个一目了然,清除两个几何图层上的要素。

前一个,先调用后一个,然后把传入的点添加到点几何图层上,使用pointSym符号对象。

最关键的一句就是geometryEngine.geodesicBuffer()了,可知传入的point,是个geometry类的对象,缓冲半径为560"kilometers".

返回的是一个polygon(因为这里只有一个单点),然后把这个polygon(名为buffer)添加到面几何图层上。

——————

其实缓冲区的例子说到这里就可以结束了,但是还有一大堆的事件是告诉我们怎么获取点击点的,又怎么把点击的点转化成Geometry的,因为事件中肯定会调用这两个方法体的,不然无法生成缓冲区。

还有兴趣的同学可以继续跟我探寻这6个事件。

先上一个流程图:

就是这么简单。

先看看两个纯DOM元素的click事件吧:

on(dom.byId("chkBoxMap"), "click", function(evt) {
  chkMapView = dom.byId("chkBoxMap").checked;
  if (chkMapView) {
    clearGraphics();
  }
});

on(dom.byId("chkBoxScene"), "click", function(evt) {
  chkSceneView = dom.byId("chkBoxScene").checked;
  if (chkSceneView) {
    clearGraphics();
  }
});

点击复选框后,将复选框的值(是否选中)赋给chkMapView和chkSceneView这两个最开始在require前面的变量。

然后检查chkMapView和chkSceneView的值,如果是真,即说明刚刚点击是从缓冲区生成状态转变为漫游状态,则需要执行clearGraphics()方法清理图层上的图案。

再来看看四个其他的事件,是两个view上的事件:

view2d.on(‘drag‘, function(evt) {
  if (!chkMapView) {
    evt.stopPropagation();
    var point = view2d.toMap({
      x: evt.x,
      y: evt.y
    });
    if (point) {
      bufferPoint(point);
    }
  }
  else if (chkMapView) {
    clearGraphics();
  }
});

view3d.on(‘drag‘, function(evt) {
  if (!chkSceneView) {
    evt.stopPropagation();
    var point = view3d.toMap({
      x: evt.x,
      y: evt.y
    });
    if (point) {
      point.hasZ = false;
      point.z = undefined;
      bufferPoint(point);
    }
  }
  else if (chkSceneView) {
    clearGraphics();
  }
});

drag事件

拖拽事件,比click事件略微复杂。

先进去就是if else分支,如果在漫游状态则调用clearGraphics(),如果不在漫游状态:

首先停止漫游状态,调用stopPropagation()方法。

然后获取单击的点的信息,使用View的toMap方法,返回一个Point对象(Geometry的子类)。

若返回的Point对象不为空,则执行bufferPoint()方法,生成缓冲区。

在3D视图中还会检查z坐标。

view2d.on("click", function(evt) {
  if (!chkMapView) {
    if (evt.mapPoint) {
      bufferPoint(evt.mapPoint);
    }
  }
  else if (chkMapView) {
    clearGraphics();
  }
});

view3d.on(‘click‘, function(evt) {
  if (!chkSceneView) {
    if (evt.mapPoint) {
      evt.mapPoint.hasZ = false;
      evt.mapPoint.z = undefined;
      bufferPoint(evt.mapPoint);
    }
  }
  else if (chkSceneView) {
    clearGraphics();
  }
});

view的click事件

这两个click事件就简单了,其实就是没有了drag事件的stopPropagation()那部分,获取点位也没那么麻烦了,直接传evt事件流中的mapPoint属性即可。



可能有人会问,为什么2d视图移动点后3d视图也跟着动呢?

是因为两个视图共用了一份map,map中是包含了两个显示缓冲区用的GraphicsLayer的。

好了,这个例子就不总结啦,都在最顶头就说完了。下个例子见。

时间: 2024-10-20 19:41:09

ArcGIS API for JavaScript 4.2学习笔记[26] 缓冲区分析【基于geometryEngine工具类】的相关文章

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

放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 诸君,我喜欢嫩的--呸呸呸 诸君,我喜欢3D咋了?新事物会替代旧事物不是~ ArcGIS API for JavaScript 4.2概述 AJS 4.2,即ArcGIS API for JavaScript 4.2,是美国ESRI公司针对WebGIS市场推出的.利用JavaScript和Dojo开发的一款产品,它在2016年12月发布.而AJS 4.0 beta则在一年前就发布了. 关于AJS3和AJS4选择的问题,

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

ArcGIS API for JavaScript 4.2直接从官网的Sample中学习,API Reference也是从官网翻译理解过来,鉴于网上截稿前还没有人发布过4.2的学习笔记,我就试试吧. 什么是ArcGIS API for JS?这里就不多介绍了,最关键的一点是4.x版本与3.x版本的变化,按官方的意思是重新写了底层. 笔记中规定: ArcGIS API for JavaScript简称AJS 使用CDN(即不配置本地环境)进行测试开发 其余根据需要进行修改.增删. 要将地图显示在h

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

内容如上,截图自ESRI官网,连接:ArcGIS API for JavaScript 4.2 [Get Started] 类似于绪论一样的东西,抽取了最需要关注的几个例子.如:加载Map和View,加载layers,使用弹出窗口,视觉化,与使用窗口小部件.(wtf居然没有分析你想搞事情啊web除了展示难道不应该有()&&*--@) [Mapping and Views] (点击进入我写的章节详细介绍) 最基础的,知道地图和视图的区别,能使用2D和3D地图,对地图的布局有一定的了解,对地图

ArcGIS API for JavaScript 4.2学习笔记[16] 弹窗自定义功能按钮及为要素自定义按钮(第五章完结)

这节对Popups这一章的最后两个例子进行介绍和解析. 第一个[Popup Actions]介绍了弹窗中如何自定义工具按钮(名为actions),以PopupTemplate+FeatureLayer的形式测量要素的长度为例子进行介绍. 第二个[Custom popup actions per feature]则是上一个的升级,如果说上一个例子的功能是写死的,那么这个例子就把这个功能写活了.什么意思呢?上个例子的测距仅仅能测距,没有什么别的特别的.而这个例子以啤酒店的分布(点要素图层)为例,在自

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

文前说明:关于style就是页面的css暂时不做评论,因为官方给的例子的样式实在太简单了,照抄阅读即可. 这篇文章有着大量AJS 4.x版本添加的内容,如监听watch.Promise对象.回调函数.异步处理等内容,原理性的东西我会在文末解释,各位看官不用担心看不懂,我尽量用通俗的语言解释这些. 惯例,如果不习惯从头看到尾,可以直接跳到后面看总结. 大家应该看过商业地图的缩略图功能吧?以度娘地图为例,在使用街景地图的时候,左下角会出现一个地点一样的2D小地图: 这个就是鹰眼功能的应用,在很多桌面

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

好吧,我都要吐了. 接连三个例子都是类似的套路,使用某个查询参数类的实例,结合对应的Task类,对返回值进行取值.显示. 这个例子是Identify识别,使用了TileLayer这种图层,数据来自Server的MapServer. 结果演示 戳不同的地方会有不同的识别结果. 我对TileLayer不是很了解,这一例仅针对有了解的同学,做一个IdentifyTask的解释. IdentifyTask/IdentifyParameter/IdentifyResult三个类 既然是一样的套路,那么先对

ArcGIS API for JavaScript 4.2学习笔记[9] 同一种视图不同数据(Map)同步

本例子核心:对MapView对象的map属性值进行替换即可达到更改地图数据的效果. 这个例子用的不是Map对象了,而是用的发布在服务器上的专题地图(WebMap)来加载到MapView上进行显示. 在html标签中,使用了section标签,不过没什么稀奇的,就把仨按钮放一块而已. 先给出预览图 三张专题地图:失踪人口密度分布.难民迁徙路线.2015年欧洲来港者. 这个东西很有用,尤其是在展示同一地区的专题地图的时候,这里也展示了什么叫View,什么叫Map. 因为中心点.比例尺是由View对象

ArcGIS API for JavaScript 4.2学习笔记[23] 没有地图如何进行查询?【FindTask类的使用】

从第一篇到现在都是基于地图的,不管怎么样,不管是2D还是3D,至少有个图. 这次来个没有图的例子,看看纯文字的空间查询是什么样的. 本例适用于后台查询或低性能电脑的查询. 预览图 由于4.3和4.2的这个例子没有任何实质性的改动,我直接从官方运行的4.3的例子: 默认打开的时候,按下Find按钮,右边就会出现转圈圈的图,其实是个GIF图片. 结果如上,将Spokane这个County的信息列举出来了,列出的字段有County Name.State.Population(2012).%Popula

ArcGIS API for JavaScript 4.2学习笔记[30] 点和线高程查询(第八章完结)

终于到最后一篇了,可喜可贺. 本例先说明了如何进行单点的高程差分析,然后说明了道路的起伏分析.前者很直观地比较了两个年份的高程数据之间的差值,体现山区的高程变化(有啥用啊?)后者,一条路上的起点终点起伏多少,可以给驾驶导航提供更多样化的数据. 本例使用了高程图层和RouteTask. 本例对应的官方例子是:Query Elevation (Points)和Query Elevation (Lines) 1. 点高程差查询 1.1 结果显示 选了一个明显的点,绿色的是地形变化前的高程点,红色的球是