8.过滤 feature layer

概述

本节您将学到: 对feature layer进行客户端或服务端的过滤显示。

在展示feature layer时,如果我们只需要展示其中符合某些条件的要素,就可以使用 feature laye r的过滤功能。 我们可以通过客户端方式或服务端方式结合SQL表示和空间表达式进行 feature layer 的过滤显示。
被过滤的feature layer 可以托管在 ArcGIS OnlineArcGIS Enterprise 上,或者也可以通过客户端进行创建。

  • 服务端方式:通过给 FeatureLayer 对象的 definitionExpression 属性设置SQL表达式,就可进行服务端属性过滤,由服务端进行过滤计算之后将过滤结果返回给客户端显示,所以服务端过滤无需先将f eature layer 添加至地图上。
  • 客户端方式:通过给 FeatureLayerView 对象的 filter 的属性设置SQL表达式和空间表达式,就可以进行客户端的属性过滤和空间过滤,由客户端接收服务端的整个图层数据之后根据条件进行过滤显示,所以需要先将 feature layer 添加至地图上,
    客户端过滤会比服务端过滤速度快。

在本节中,我们将使用SQL表达式对 Trails 进行客户端过滤和服务端过滤。效果如下,选择右上角下拉列表中的过滤条件,地图将显示过滤结果。

效果图

撸代码步骤

创建一个简单HTML页面

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS JavaScript Tutorials: Create a Starter App</title>
  <style>
    html, body, #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  
  <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
  <script src="https://js.arcgis.com/4.12/"></script>
  
  <script>  
    require([
      "esri/Map",
      "esri/views/MapView",
    ], function(Map, MapView) {

      var map = new Map({
        basemap: "topo-vector"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-118.80543,34.02700],
        zoom: 13
      });

    });
  </script>
</head>
<body>
  <div id="viewDiv"></div>
</body>
</html>

添加图层

创建一个 Trails 的 feature layer 并加到地图中。

  • require中加入 FeatureLayerGraphicLayerGraphic 的模块引用。
require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/FeatureLayer"
],function(Map, MapView, FeatureLayer

在 main 方法的底部,创建一个 TrailsFeatureLayer 对象,开启并设置 pop-up , 最后加入到地图中。

var featureLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails_Styled/FeatureServer/0",
    outFields: ["*"], // 返回所有字段,可供客户端查询使用
    popupTemplate: {  // 开启 popup
    title: "{TRL_NAME}",
    content: "The trail elevation gain is {ELEV_GAIN} ft." 
    }
});
map.add(featureLayer);

创建SQL表达式

  • 创建一个下拉列表,下拉内容为一系列的SQL表达式的过滤语句,用作过滤图层的条件,之后将这个下拉列表作为微件添加到地图中。
var sqlExpressions = ["TRL_ID = 0", "TRL_ID > 0",  "USE_BIKE = 'Yes'", "USE_BIKE = 'No'", "ELEV_GAIN < 1000", "ELEV_GAIN > 1000", "TRL_NAME = 'California Coastal Trail'"];

var selectFilter = document.createElement("select");
selectFilter.setAttribute("class", "esri-widget esri-select");
selectFilter.setAttribute("style", "width: 275px; font-family: Avenir Next W00; font-size: 1em;");

sqlExpressions.forEach(function(sql){
  var option = document.createElement("option");
  option.value = sql;
  option.innerHTML = sql;
  selectFilter.appendChild(option);
});
//添加下拉列表到地图微件中
view.ui.add(selectFilter, "top-right");

执行服务端过滤

我们可以给feature layer的 definitionExpression 设置SQL表达式进行服务端过滤。

  • 创建一个方法用来接收表达式并设置给feature layer 的 definitionExpression 属性。
function setFeatureLayerFilter(expression) {
  featureLayer.definitionExpression = expression;
}
  • 监听下拉框值改变事件,将下拉框选中值传给 setFeatureLayerFilter 方法,进行属性过滤。
selectFilter.addEventListener('change', function (event) {
  setFeatureLayerFilter(event.target.value);
});
  • 到此已经完成了服务端过滤,运行代码,选中下拉框不同的值可以看到feature layer 显示出来的要素不一样。

客户端过滤

当feature layer 的要素全部加载完成,可以给对应的 FeatureLayerView 设置 filter 属性来进行客户端过滤。客户端过滤可以同时进行属性过滤和空间过滤,过滤速度通常会比服务端过滤快。

  • 创建一个方法用来接收表达式并在 feature laye 加载完成时, 给对应的 FeatureLayerView 设置 filter 属性,进行客户端过滤。
function setFeatureLayerViewFilter(expression) {
  view.whenLayerView(featureLayer).then(function(featureLayerView) {
    featureLayerView.filter = {
      where: expression
    };
  });
}
  • 在下拉框的回调中注释调用来调用服务端过滤的代码,加入调用客户端过滤的代码。
selectFilter.addEventListener('change', function (event) {
  // setFeatureLayerFilter(event.target.value);
  setFeatureLayerViewFilter(event.target.value);
});
  • 到此已经完成了客户端过滤,运行代码,选中下拉框不同的值可以看到feature layer 显示出来的要素不一样,效果图如下。

效果图

再撸点

为被过滤排除的要素配置样式

默认情况下,当图层开启过滤时,只要符合过滤条件的要素才会显示出来,但如果我们也想显示不符合过滤条件的要素时,可以给 FeatureLayerVieweffect 属性设置值。该属性需要设置 filterexcludedEffect 分别代表过滤条件和被过滤排除要素的显示样式(使用CSS filter 语法)。

  • 以下改变客户端过滤的代码,将被过滤排除的要素透明度设置成 50% 进行显示。
function setFeatureLayerViewFilter(expression) {
  view.whenLayerView(featureLayer).then(function(featureLayerView) {
    // featureLayerView.filter = {
    //   where: expression
    // };
    //*** ADD ***//
    featureLayerView.effect = {
      filter: {
        where: expression
      },
      excludedEffect: "opacity(50%)"
    }
  });
}

查看和高亮要素

我们可以通过 view 对象的 hitTest 方法获取到屏幕坐标之后进行查找要素。当 viewFeatureLayerView 加载完成, 鼠标移到时,我们可以使用 hitTest 方法查找鼠标指向的要素,并且进行高亮,达到另外一种“过滤”的效果。

var highlight; //保存高亮要素
view.whenLayerView(featureLayer).then(function(featureLayerView) {
  view.on("pointer-move", function(event){
    view.hitTest(event).then(function(response){
      var feature = response.results.filter(function (result) {
        return result.graphic.layer === featureLayer;
      })[0].graphic;
      if (highlight) {
        highlight.remove();
      }
      // 高亮要素
      highlight = featureLayerView.highlight(feature);
    });
  });
});

效果如下,鼠标移动时,对应的要素会高亮。


**完整代码较长,可公众号回复数字8查看。

欢迎关注我的微信公众号,第一时间为您推送相关教程。

GIS猫公众号

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>通过属性查询地图服务中的信息</title> <link rel="stylesheet" href="https://js.arcgis.com/3.39/esri/css/esri.css"> <!-- <link rel="stylesheet" type="text/css" href="./css/esri.css" /> --> <link rel="stylesheet" href="https://js.arcgis.com/3.40/esri/themes/calcite/dijit/calcite.css"> <script src="https://js.arcgis.com/3.41/"></script> <script> require(["esri/map", //加载地图组件 "dojo/dom", "dojo/on", "esri/InfoTemplate", "esri/graphic", "esri/geometry/Point",//加载点对象组件 "esri/symbols/SimpleMarkerSymbol", "esri/geometry/Extent",//加载范围组件 "esri/layers/FeatureLayer", //加载FeatureLayer地图组件 // "esri/dijit/FeatureTable", "esri/layers/WebTiledLayer", //加载切片地图组件 "esri/layers/ArcGISDynamicMapServiceLayer",//加载动态地图组件 "esri/symbols/SimpleFillSymbol", "esri/renderers/UniqueValueRenderer", "esri/tasks/query", "esri/tasks/QueryTask", "esri/Color", "dojo/domReady!" ], function (Map, dom, on, InfoTemplate, Graphic, Point, SimpleMarkerSymbol,Extent, FeatureLayer, WebTiledLayer, ArcGISDynamicMapServiceLayer, SimpleFillSymbol, UniqueValueRenderer, Query, QueryTask, Color, GeoJsonLayer) { //初始化地图容器 // map = new Map("map", { logo: false, slider: false }, {zoom: 8}); map = new Map("map", { center: [109.33789 , 29.57985], basemap: "satellite", zoom: 10, sliderStyle: "small", logo: false }); // 创建底图 var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"); map.addLayer(basemap,0); // 创建动态图层 var dynamicLayer = new ArcGISDynamicMapServiceLayer("http://116.62.63.94:6080/arcgis/rest/services/sanhuxiangtest/MapServer"); map.addLayer(dynamicLayer,99); }) </script> </head> <body class="tundra"> <div id="map" style="width:900px; height:580px; border:1px solid #000;"></div> 类别名称:<input class="nm" type="text"> </body> </html>
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值