想知道可視域分析是什么,就得知道可視域是什么
我們站在某個地方,原地不動轉一圈能看到的所有事物就叫可視域。當然平地就沒什么所謂的可視域。
如果在山區呢?可視范圍就會被山體擋住了。這個分析對軍事上有十分重要的意義。
在本例中,可視域是以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); }
首先,圖形圖層清零,獲取點擊點,命名為point(Point類的實例);
然后,根據這個point形成一個Graphic對象,名為inputGraphic,添加到圖形圖層中(顯示點擊點);
之后,根據可視域分析服務所需的參數
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對象中的可視域進行處理、顯示。
完美!