zoukankan      html  css  js  c++  java
  • ArcGIS API for JavaScript 4.2学习笔记[28] 可视域分析【使用Geoprocessor类】

    想知道可视域分析是什么,就得知道可视域是什么

    我们站在某个地方,原地不动转一圈能看到的所有事物就叫可视域。当然平地就没什么所谓的可视域。

    如果在山区呢?可视范围就会被山体挡住了。这个分析对军事上有十分重要的意义。

    在本例中,可视域是以GraphicLayer中的Graphics[]形式存在的。

    这个例子用到了Geoprocessor这个类。这个类的对象是如何判别我要进行可视域分析呢?且听我慢慢道来。


    看看结果

    点击山谷的位置,出现一个红点,稍等10s左右,出现橙色的面块,橙色的面块就是红点位置所能看到的范围了(比起桌面的可视域分析还是弱了点),比起桌面来说可谓是所见即所得。

    这个在AJS 3.x是做不到的,因为这里有强大的3D分析功能嘛。


    Geoprocessor类

    这个类很强大,和之前的四个Task不太一样,它接受的处理参数不再是一个类,而是一个Object数组。也就是说,是什么样子的处理,就输入什么样的参数。

    官方举例如下:

    假设有Input_Points和Distance两个需要输入的参数,那么

    就在Geoprocessor类的execute()方法中传入这么一个Object对象:

    {
       Input_Points: <FeatureSet>,
       Distance: <Number>
    }

    这就是GP类的强大之处。如果需要进行异步操作,则使用submitJob()代替execute()方法,节约网页等待时间。

    Geoprocessor类的execute()方法返回一个Object对象,其包含有:

    两个属性,我们关心的是results属性,其为ParameterValue[]类型。下面我就要说说ParameterValue这个类,它和前面某某Result类十分相似。

    ParameterValue类

     

    它是execute()或submitJob()的返回值中的results属性类型。

    它有三个属性:dataType(String类型)、declareClass和value(Object类型)

    什么意思呢?GP处理的结果当然是因输入的参数决定的,所以在本例中,dataType就规定成了"record-set"或"feature-record-set-layer", 即value属性就被装箱成了FeatureSet类型。

    dataType的值就确定了value的值类型,见这个表格:点我

    有了这些预备知识,讲解这个例子和下一个例子就不难了。


     给出引用

    require([
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/GraphicsLayer","esri/Graphic",
        "esri/geometry/Point",
        "esri/symbols/SimpleMarkerSymbol","esri/symbols/SimpleFillSymbol",
        "esri/tasks/Geoprocessor",
        "esri/tasks/support/LinearUnit","esri/tasks/support/FeatureSet",
        "dojo/domReady!"
      ],
      function(Map, SceneView, GraphicsLayer, Graphic, Point,
        SimpleMarkerSymbol, SimpleFillSymbol, Geoprocessor,
        LinearUnit, FeatureSet) {
        ...
        }
    );

    嗯,对Geoprocessor的引用。

    函数框架

    function(...){
        var gpUrl ="https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed";
        var map = new Map({...});
        var view = new SceneView({...});
        var graphicsLayer = new GraphicsLayer({...)};
        map.add(graphicsLayer);
        
        var markerSymbol = new SimpleMarkerSymbol({...});
        var fillSymbol = new SimpleFillSymbol({...});
        
        var gp = new Geoprocessor(gpUrl);
        gp.outSpatialReference = {...};
    
        //重点
        view.on("click", computeViewshed);
        
        function computeViewshed(event){...}
        function drawResultData(result){...}
    }

    我想到这,就不必解释很多了,我们直接关注数据处理的重点代码:view的click事件和两个处理函数computeViewshed()和drawResultData()。

    gp这个Geoprocessor类的实例化在上方已经说明了,就不说那么详细了。

    computeViewshed(event)方法

    这个方法有点长,但是每一行的意义都很明确。它做的就是获取点击点,生成一个红色的点符号,然后获取gp.execute()的输入参数,执行execute()方法。

    function computeViewshed(event) {
      graphicsLayer.removeAll();
    
      var point = new Point({
        longitude: event.mapPoint.longitude,
        latitude: event.mapPoint.latitude
      });
    
      var inputGraphic = new Graphic({
        geometry: point,
        symbol: markerSymbol
      });
    
      graphicsLayer.add(inputGraphic);
    
      var inputGraphicContainer = [];
      inputGraphicContainer.push(inputGraphic);
      var featureSet = new FeatureSet();
      featureSet.features = inputGraphicContainer;
    
      var vsDistance = new LinearUnit();
      vsDistance.distance = 5;
      vsDistance.units = "miles";
    
      var params = {
        "Input_Observation_Point": featureSet,
        "Viewshed_Distance": vsDistance
      };
    
      gp.execute(params).then(drawResultData);
    }
    computeViewshed()方法

    首先,图形图层清零,获取点击点,命名为point(Point类的实例);

    然后,根据这个point形成一个Graphic对象,名为inputGraphic,添加到图形图层中(显示点击点);

    之后,根据可视域分析服务所需的参数

    "Input_Observation_Point"和"Viewshed_Distance",分别为FeatureSet类和LinearUnit类的数据
    实例化所需的参数featureSet对象和vsDistance对象,组成params这个Object对象;
    执行gp.execute(params)。
    最后,execute(params)接着一个异步操作then(drawResultData),绘制处理结果。
    我们已经知道了,这里返回的Object对象中results属性为ParameterValue[]类型。我们只需从中获取需要的可视域数据(FeatureSet)即可。

    drawResultData()方法

    function drawResultData(result) {
      var resultFeatures = result.results[0].value.features;
    
      var viewshedGraphics = resultFeatures.map(function(feature) {
        feature.symbol = fillSymbol;
        return feature;
      });
    
      graphicsLayer.addMany(viewshedGraphics);
    
      view.goTo({
        target: viewshedGraphics,
        tilt: 0
      });
    }

    result即为execute()返回的Object对象,获取results[0]的value(即FeatureSet)中的features(类型为Graphic[]),命名为resultFeatures。

    对这个Graphic[]变量进行遍历(map()方法),对每个Graphic设置填充符号,返回一个新的Graphic[]变量viewshedGraphics;

    然后把这个Graphic[]变量添加到图形图层上;

    最后让视图跳转到这个图形图层。

    总结一下

    通过单击,获取这个点位信息——通过这个点生成需要的可视域分析所需的参数集(Object类型),传入gp.execute()——对返回的Object对象中的可视域进行处理、显示。

    完美!

  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/onsummer/p/6682666.html
Copyright © 2011-2022 走看看