從第一篇到現在都是基於地圖的,不管怎么樣,不管是2D還是3D,至少有個圖。
這次來個沒有圖的例子,看看純文字的空間查詢是什么樣的。
本例適用於后台查詢或低性能電腦的查詢。
預覽圖
由於4.3和4.2的這個例子沒有任何實質性的改動,我直接從官方運行的4.3的例子:
默認打開的時候,按下Find按鈕,右邊就會出現轉圈圈的圖,其實是個GIF圖片。
結果如上,將Spokane這個County的信息列舉出來了,列出的字段有County Name、State、Population(2012)、%Population Change(2000-2010)四個。
對應的值以常規字體列在下方。
是不是很簡單?代碼可不一定簡單。
給出引用
html上的引用就不需要css了:
<script src="https://js.arcgis.com/4.2/"></script>
只需要引用js庫即可。
函數引用:
require([ "esri/tasks/FindTask", "esri/tasks/support/FindParameters", "dojo/_base/array", "dojo/dom", "dojo/on", "dojo/domReady!" ], function(FindTask, FindParameters, arrayUtils, dom, on) { //代碼 } );
哦喲,FindTask居然不是用Query了,而是轉用FindParameters。看來對Query、Find、Search這幾個詞還是要區別的。
函數參數骨架
function(FindTask, FindParameters, arrayUtils, dom, on) { var loadingImg = dom.byId("loading"); var find = new FindTask({}); var params = new FindParameters({}); function doFind() {} var resultsTable = dom.byId("tbl"); function showResults(response) {} function rejectedPromise(err) {} on(dom.byId("findBtn"), "click", doFind); }
這個和上一個例子類似了,FindTask、FindParameters和QueryTask、Query差不多,成對出現:
var find = new FindTask({ url: "https://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_2000-2010_Population_Change/MapServer" }); var params = new FindParameters({ layerIds: [3], searchFields: ["NAME"] });
值得一提的是,FindTask這個類也是由ArcServer發布的服務實例化的。查閱API,得知FindTask類的細節:
FindTask
和QueryTask如出一轍,但是參數改為FindParameters了,返回值也變成FindResults類型的變量了。
FindParameters
和Query類似的東西:
列舉幾個常用屬性:searchText(String)、searchFields(String[])、returnGeometry(Boolean)、outSpatialReference(SpatialReference)
前面兩個就是本例中使用的屬性了,searchText是用戶輸入的需要進行搜索的文本,searchFields則是進行搜索的字段。后兩個和Query一樣。
FindResult
列舉幾個常用屬性:feature(Graphic)、foundFieldName(String)
前一個即為找到的幾何(在屬性表中對應一行),后一個為這個幾何所在FindParameters中設定搜索的字段中的那一個。
function doFind() {
loadingImg.style.visibility = "visible";
params.searchText = dom.byId("inputTxt").value;
find.execute(params)
.then(showResults)
.otherwise(rejectedPromise);
}
而doFind()和上一例的doQuery()也是類似的,成功就調用showResults(),失敗就調用rejectedPromise()。
最后一個則是為findBtn這個DOM按鈕添加click事件。
邏輯如下,和上一個例子幾乎一毛一樣,僅僅是showResults這個對返回結果的處理的方法不太一樣罷了。
下方高能!!
function showResults(response) { var results = response.results; resultsTable.innerHTML = ""; //如果返回的results是空,那么告訴用戶 if (results.length === 0) { resultsTable.innerHTML = "<i>No results found</i>"; loadingImg.style.visibility = "hidden"; return; } //HTML操作,加一行,加4個單元格 var topRow = resultsTable.insertRow(0); var cell1 = topRow.insertCell(0); var cell2 = topRow.insertCell(1); var cell3 = topRow.insertCell(2); var cell4 = topRow.insertCell(3); //HTML操作,給每一個單元格填入值 cell1.innerHTML = "<b>County Name</b>"; cell2.innerHTML = "<b>State</b>"; cell3.innerHTML = "<b>Population (2012)</b>"; cell4.innerHTML = "<b>% Population Change (2000 - 2010)</b>"; //!最關鍵的一段代碼! arrayUtils.forEach(results, function(findResult, i) { var county = findResult.feature.attributes.Name; var state = findResult.feature.attributes[ "State Abbreviation"]; var popGrowth = findResult.feature.attributes[ "2000-2010 Population Annual Compound Growth Rate (U.S. Census)" ]; var pop2012 = findResult.feature.attributes[ "2012 Total Population (Esri)"]; //HTML操作。加一行,加4個單元格,寫入值。 var row = resultsTable.insertRow(i + 1); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); var cell3 = row.insertCell(2); var cell4 = row.insertCell(3); cell1.innerHTML = county; cell2.innerHTML = state; cell3.innerHTML = pop2012; cell4.innerHTML = popGrowth; }); //轉圈圈的GIF圖不可見 loadingImg.style.visibility = "hidden"; }
別看這段代碼很長,很多都是HTML的DOM元素操作,我們單獨把關鍵段取出來:
arrayUtils.forEach(results, function(findResult, i) { //從FindResult對象中獲取需要的字段值 var county = findResult.feature.attributes.Name; var state = findResult.feature.attributes["State Abbreviation"]; var popGrowth = findResult.feature.attributes[ "2000-2010 Population Annual Compound Growth Rate (U.S. Census)"]; var pop2012 = findResult.feature.attributes["2012 Total Population (Esri)"]; // HTML操作 ...省略 });
注意到遍歷的是results,這個東西是Object數組,被裝箱成FindResult數組。這里其實就是從FindResult對象中獲取feature的attribute的值,再在下方進行HTML操作而已。
那么這個results是怎么來的呢?注意doFind()方法的最頭一句:
var results = response.results;
從傳入參數response中獲取的results屬性。經過查閱,這個response不是FindResult,而是PortalQueryResult類型的參數。
PortalQueryResult有一個屬性是results,值類型是Object數組。
那么現在就清楚了吧!這個小地方算是比較坑的。
總結一下。
使用FindTask和FindParameters進行“Find查找”操作,而不是“Query查詢”,也不是“Search搜索”。
對結果FindResult進行讀取,並寫入HTML元素上進行結果顯示。
整個例子沒有地圖,清新脫俗...#滑稽。