ArcGIS API for JavaScript 4.2学习笔记[19] 搜索小部件——使用更多数据源
上一篇中提到,空间搜索小部件是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图片文件。