上一篇中提到,空間搜索小部件是Search這個類的實例化,作為視圖的ui屬性添加進去后,視圖就會出現搜索框了。
這節的主體代碼和上篇幾乎一致,區別就在上篇提及的sources屬性。
先看看結果:
由於不太清楚要素圖層里有什么東西,隨便輸了個字母匹配,結果如圖,中央出現了一個圖案並彈窗。
開始講課!
給出引用
require( [ "esri/Map", "esri/views/MapView", "esri/widgets/Search", "esri/layers/FeatureLayer", "esri/symbols/PictureMarkerSymbol", "dojo/domReady!" ], function(){} );
PictureMarkerSymbol是上圖中搜索結果的圖案所需的模塊。
可見此例子采用了要素圖層來進行搜索。
函數參數骨架
function(Map, MapView, Search, FeatureLayer, PictureMarkerSymbol){ var map = new Map({...}); var view = new MapView({...}); var searchWidget = new Search({ ... sources: [{...},{...}] } view.ui.add(searchWidget, {...}); )
上一節提到Search這個類有一個重要的屬性sources,它是Collection類型(同對象數組容器,與.NET中list容器差不多)。
看看完整代碼:
sources: [{ featureLayer: new FeatureLayer({ url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/CongressionalDistricts/FeatureServer/0", popupTemplate: { title: "Congressional District {DISTRICTID} </br>{NAME}, {PARTY}", overwriteActions: true } }), searchFields: ["DISTRICTID"], displayField: "DISTRICTID", exactMatch: false, outFields: ["DISTRICTID", "NAME", "PARTY"], name: "Congressional Districts", placeholder: "example: 3708", }, { featureLayer: new FeatureLayer({ url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/US_Senators/FeatureServer/0", popupTemplate: { title: "<a href={Web_Page} target='_blank'> {Name}</a>, ({Party}-{State}) ", overwriteActions: true } }), searchFields: ["Name", "Party"], suggestionTemplate: "{Name}, Party: {Party}", exactMatch: false, outFields: ["*"], name: "Senators", zoomScale: 500000, resultSymbol: new PictureMarkerSymbol({ url: "images/senate.png", height: 36, width: 36 }) }]
我這里沒有縮起來,原因就是已經很明顯了——
sources給了一個Object數組,數組內有兩個{}對象。
每個{}對象擁有以下屬性:【featureLayer,searchFields,suggestionTemplate,exactMatch,outFields,name,zoomScale,resultSymbol】
查閱API,得知sources接受以下數據類型作為搜索源:
featureLayerSource
locatorSource
在上面,sources[{...},{...}]中的每個大括號對象就是featureLayerSource類型的。這里有點拗口,featureLayerSource和locatorSource不是js中的類,而是一種“說法”,因為sources接受的是Object數組作為參數,只不過本例以featureLayerSource作為示范而已。
【featureLayerSource】可選參數
displayField(String):用於顯示結果的字段(名)
exactMatch(Boolean):是否精確搜索,默認是否(false)。
featureLayer(FeatureLayer):這個參數必須需要,因為是數據源啊。
searchFields(String[]):用於搜索的字段(名)。
searchQueryParams(Object):包括outSpatialReference、returnGeometry、num、outFields、where、maxAllowableOffset、objectIds
suggestQueryParams(Object):包括outSpatialReference、returnGeometry、num、outFields、where
以上兩個Object類型的參數不知道是干嘛用的,前一個似乎是搜索時的默認選項,后一個是請求建議時的默認選項(與Search類的suggest()方法有關)?
suggestionTemplate(String):displayField有多個時,需要有格式地顯示,就用這個。例子:suggestionTemplate: "Name: {OWNER}, Parcel: {PARCEL_ID}"
再看看locatorSource:
【locatorSource】可選參數
categories(String[])
countryCode(String)
localSearchOptions(Object)
locationToAddressDistance(Number)
searchTemplate(String)
locator(Locator)
singleLineFieldName(String)
關於locatorSource就不說多了,這個數據源是對Locator(定位)類熟練運用才能使用的,因為前面的筆記沒有對Locator有多余的描述,故僅僅在此記錄。
回到sources[{...},{...}]的代碼部分。
這樣思路就清晰了,使用featureLayerSource作為搜索數據源,就要定義賦值上面提到的屬性。
在featureLayer屬性中,使用了popupTemplate方便輸出。
在第二個featureLayerSource中,出現了一個新的東西——“resultSymbol”,它是PictureMarkerSymbol類的屬性。查詢API:
簡單,這就是用一張圖片指示出某個點。
這里用到了url、height、width三個屬性,不必說多也知道是什么意思了。常用的屬性還有xoffset、yoffset等。
總結一下。
如何在搜索小部件中使用多源數據呢?
只需要設置Search類的sources屬性即可,可以有兩種類型:featureLayerSource和locatorSource。
注意,雖然是這么說,但是寫法上還是屬於Object類型的。兩個類型都需要設置必要的、可選的屬性才能賦給sources屬性。
最后給出完整的官方代碼:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> <title>Search widget with multiple sources - 4.2</title> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } </style> <link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css"> <script src="https://js.arcgis.com/4.2/"></script> <script> require([ "esri/Map", "esri/views/MapView", "esri/widgets/Search", "esri/layers/FeatureLayer", "esri/symbols/PictureMarkerSymbol", "dojo/domReady!" ], function( Map, MapView, Search, FeatureLayer, PictureMarkerSymbol) { var map = new Map({ basemap: "dark-gray" }); var view = new MapView({ container: "viewDiv", map: map, center: [-97, 38], // lon, lat scale: 10000000 }); var searchWidget = new Search({ view: view, allPlaceholder: "District or Senator", sources: [{ featureLayer: new FeatureLayer({ url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/CongressionalDistricts/FeatureServer/0", popupTemplate: { // autocasts as new popupTemplate() title: "Congressional District {DISTRICTID} </br>{NAME}, {PARTY}", overwriteActions: true } }), searchFields: ["DISTRICTID"], displayField: "DISTRICTID", exactMatch: false, outFields: ["DISTRICTID", "NAME", "PARTY"], name: "Congressional Districts", placeholder: "example: 3708", }, { featureLayer: new FeatureLayer({ url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/US_Senators/FeatureServer/0", popupTemplate: { // autocasts as new popupTemplate() title: "<a href={Web_Page} target='_blank'> {Name}</a>, ({Party}-{State}) ", overwriteActions: true } }), searchFields: ["Name", "Party"], suggestionTemplate: "{Name}, Party: {Party}", exactMatch: false, outFields: ["*"], name: "Senators", zoomScale: 500000, resultSymbol: new PictureMarkerSymbol({ url: "images/senate.png", height: 36, width: 36 }) }] }); // Add the search widget to the top left corner of the view view.ui.add(searchWidget, { position: "top-right" }); }); </script> </head> <body> <div id="viewDiv"></div> </body> </html>
注意與html同級別下有一個image文件夾,里面存有senate.png圖片文件。