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猫公众号
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容