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对象中的可视域进行处理、显示。

    完美!

  • 相关阅读:
    Codeforces Round #368 (Div. 2)D. Persistent Bookcase DFS
    POJ Sudoku 数独填数 DFS
    Memory
    UESTC 771 最大容积(前缀后缀和)
    【题解】P2916 [USACO08NOV]安慰奶牛Cheering up the Cow-C++
    Prim算法与Kruskal(没有代码)
    【题解】P1396 营救-C++
    【题解】Unit Fraction Partition-C++
    【题解】P2078 朋友-C++
    【题解】P1892 [BOI2003]团伙-C++
  • 原文地址:https://www.cnblogs.com/onsummer/p/6682666.html
Copyright © 2011-2022 走看看