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图片文件。

posted @ 2017-02-21 20:06 秋意正寒 阅读(...) 评论(...) 编辑 收藏