上一篇寫道,使用Query類進行查詢featureLayer圖層的要素,也簡單介紹了QueryTask類的使用。
這一篇博文繼續推進,使用Query類和QueryTask類進行空間查詢,查詢USA的著名山體點要素。
同樣的,只介紹重點。本章官方名字是:Query using QueryTask
照常,先看看結果:(默認三個參數都不動,直接點擊按鈕)
出現了綠色的圓錐體,點擊圓錐體可以出現定制好的彈窗(PopupTemplate):
好,開始上課。
給出引用
require([ "esri/Map", "esri/views/SceneView", "esri/layers/GraphicsLayer", "esri/symbols/PointSymbol3D", "esri/symbols/ObjectSymbol3DLayer", "esri/tasks/QueryTask", "esri/tasks/support/Query", "dojo/_base/array", "dojo/dom", "dojo/on", "dojo/domReady!" ], function( Map, SceneView, GraphicsLayer, PointSymbol3D, ObjectSymbol3DLayer, QueryTask, Query, arrayUtils, dom, on) {...} )
GraphicsLayer是用於顯示綠色的圓錐體的幾何圖層;
ObjectSymbol3DLayer、PointSymbol3D是用於顯示綠色圓錐的模塊;
Query和QueryTask是本節空間查詢必須的模塊。
給出骨架
function(...) { var peaksUrl = ...(要素服務) var popupTemplate = {...}; var mtnSymbol = new PointSymbol3D({...}); var resultsLyr = new GraphicsLayer({...}); //空間查詢二要素 var qTask = new QueryTask({...}); var params = new Query({...}); var map = new Map({...}); var view = new SceneView({...}); var attributeName = dom.byId("attSelect"); var expressionSign = dom.byId("signSelect"); var value = dom.byId("valSelect"); //方法體 function doQuery(){...} function getResult(response){...} function promiseRejected(err){...} //DOM按鈕事件 on(dom.byId("doBtn"), "click", doQuery); }
為了節約篇幅與抓重點,從這兒開始就不再對Map類和View類的對象實例化進行代碼展示了,我相信一路看過來我的博文的同學都能看懂那個基礎的兩個類的使用了。除非這兩個類有新的屬性賦值,否則均省略不寫。
這例程序仍然有popupTemplate,作為綠色圓錐點狀符號的查詢結果彈出窗。驚奇的是我發現了可以通過CSS控制彈窗的部分樣式:
.esri-popup .esri-popup-header .esri-title { font-size: 18px; font-weight: bolder; } .esri-popup .esri-popup-body .esri-popup-content { font-size: 14px; }
使用的是.選擇器。
簡略看看彈窗模板的構成:(復習一下)
var popupTemplate = { title : "{...},{...}", fieldsInfos: [{...},{...},{...},{...},{...},{...}], content: "<b><a href='https://en.wikipedia.org/wiki/Topographic_prominence'>Prominence:</a>" + "</b> {PROMINENCE_ft} ft ({PROMINENCE_m} m)" + "<br><b>Prominence Rank:</b> {RANK}" + "<br><b>Elevation:</b> {ELEV_ft} ft ({ELEV_m} m)" + "<br><b><a href='https://en.wikipedia.org/wiki/Topographic_isolation'>Isolation:</a>" + "</b> {ISOLATION_mi} mi ({ISOLATION_km} km)" };
title使用兩個字段填充,擁有6個字段信息(fieldsInfos)作為content的填充內容;
content仍然是使用html語言的文本形式進行輸出。
緊接着是符號和幾何圖層的定義:
var mtnSymbol = new PointSymbol3D({ symbolLayers: [new ObjectSymbol3DLayer({ resource: { primitive: "cone" } })] }); var resultsLyr = new GraphicsLayer();
在這里要提及一下PointSymbol3D類,這個類是esri/Symbol下的一個模塊,同等級的還有LineSymbol3D、MeshSymbol3D、PolygonSymbol3D等。
這里用了一個屬性:symbolLayers,類別是ObjectSymbol3DLayer數組(Collection類型,所以這里給的形式是[]數組)。
在屬性的賦值中直接new了ObjectSymbol3DLayer,ObjectSymbol3DLayer使用了resourse屬性,它是一個Object類型的屬性。這里給定值primitive屬性是"cone"字符串,代表的意義就是圓錐。primitive是一個resource屬性的屬性,其是一個枚舉值,見:點我
緊接着就是本文最重點的地方了!
空間查詢二元素
上代碼:
var qTask = new QueryTask({ url: peaksUrl }); var params = new Query({ returnGeometry: true, outFields: ["*"] });
Query見上篇博文,而這個QueryTask則需要好好解釋一下了:
它是esri/tasks/目錄下的一個模塊,繼承自Accessor的子類Task,是AJS4.x才有的。
它的出現,是為了滿足在某一個圖層上進行空間查詢的需要。它最常用的方法就是excute()方法了,通常,需要傳入一個Query對象。
它的返回類型是Promise的FeatureSet類的對象(有點拗口,Promise算是一個特征吧)
返回的FeatureSet是符合傳入Query的在圖層上的所有要素的集合。
本例中,使用了要素服務作為QueryTask的構造器:
var qTask = new QueryTask({ url: peaksUrl });
url這個屬性見下:
它可以是FeatureServer,也可以是MapServer。也就是說我們可以使用Server上的這兩種服務來實例化一個QueryTask對象。
好,空間分析二元素就創建好了,有了Query對象和QueryTask對象,我們就需要進行空間搜索了,既然巧婦難為無米之炊,現在有了米,也該炊起來了。
分析部分
我先上個圖,會比代碼看起來更有立體感:
當按下DOM上的按鈕時,觸發doQuery事件,此時從三個下拉框中獲取參數(即option標簽的value值),設置成SQL查詢語句,即Query對象的where屬性。
此時,把Query對象(名為param)傳入QueryTask對象(名為qTask)的excute()方法內,使用getResults()方法作為成功查詢的回調函數,使用promiseRejected()方法作為查詢失敗的回調函數。
邏輯很簡單,只有一個分支,失敗的promiseRejected()就不細說了,只是在后台控制台輸出錯誤信息而已。
主要看getResults,看看它對查詢結果做了什么:
function getResults(response) { var peakResults = arrayUtils.map(response.features, function(feature) {
feature.symbol = new PointSymbol3D({...}); feature.popupTemplate = popupTemplate; return feature; }); resultsLyr.addMany(peakResults); view.goTo(peakResults); dom.byId("printResults").innerHTML = peakResults.length + " results found!"; }
response就是FeatureSet對象了吧,對其features對象使用一個方法體function(feature){...}來操作每一個feature:
首先,設置symbol屬性,就是圖中綠色的小圓錐體;
其次,設置的是popupTemplate屬性,就是彈窗,在本篇上面有介紹。
最后返回feature,作為peakResults數組的一個元素。
這個peakResults數組就是搜索得到的要素的集合,只不過添加了彈窗模板和圓錐點狀符號而已~
在這里,使用到了arrayUtils這個類的map方法,遍歷操作了features的每一個feature。
【經過查詢,arrayUtils查不到信息,dojo官方網站給的是array.map()方法,可能這兩個是版本區別吧...?】
關於PointSymbol3D({...})這里面的內容我不多敘述了,給出源代碼,各位對符號有興趣可以自行學習。

feature.symbol = new PointSymbol3D({ symbolLayers: [new ObjectSymbol3DLayer({ material: { color: "green" }, resource: { primitive: "cone" }, width: 100000, height: feature.attributes.ELEV_m * 100 })] });
peakResults作為Object數組傳入resultLyr,然后將視圖定位到peakResults(使用goTo()動畫),並刷新DOM上的文字信息,提示有多少個點被找到。
總結一下
這個例子,我沒記錯的話是第一個接觸到Task這個類的東西,這里是Task類的子類QueryTask。
思路比較簡單,把Query對象傳入QueryTask對象,再由回調函數處理返回的FeatureSet即可。
這里還用到了簡單的3D點符號~
【最后嘆一句:終於能恢復更新了,估計這周內就能完成空間查詢和空間分析章節的筆記!】