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} {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: " {Name}, ({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.2title>
  <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} {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: " {Name}, ({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图片文件。