天天看點

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

使用FindTask和FindParameters進行“Find查找”操作,而不是“Query查詢”,也不是“Search搜尋”。

對結果FindResult進行讀取,并寫入HTML元素上進行結果顯示。

從第一篇到現在都是基于地圖的,不管怎麼樣,不管是2D還是3D,至少有個圖。

這次來個沒有圖的例子,看看純文字的空間查詢是什麼樣的。

本例适用于背景查詢或低性能電腦的查詢。

預覽圖

由于4.3和4.2的這個例子沒有任何實質性的改動,我直接從官方運作的4.3的例子:

預設打開的時候,按下Find按鈕,右邊就會出現轉圈圈的圖,其實是個GIF圖檔。

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

結果如上,将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

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

和QueryTask如出一轍,但是參數改為FindParameters了,傳回值也變成FindResults類型的變量了。

FindParameters

和Query類似的東西:

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

列舉幾個常用屬性:searchText(String)、searchFields(String[])、returnGeometry(Boolean)、outSpatialReference(SpatialReference)

前面兩個就是本例中使用的屬性了,searchText是使用者輸入的需要進行搜尋的文本,searchFields則是進行搜尋的字段。後兩個和Query一樣。

FindResult

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

列舉幾個常用屬性: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這個對傳回結果的處理的方法不太一樣罷了。

ArcGIS API for JavaScript 4.2學習筆記[23] 沒有地圖如何進行查詢?【FindTask類的使用】

下方高能!!

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數組。

那麼現在就清楚了吧!這個小地方算是比較坑的。

總結一下。

整個例子沒有地圖,清新脫俗...#滑稽。

繼續閱讀