概述
本节您将学到: 对feature layer进行客户端或服务端的过滤显示。
在展示feature layer时,如果我们只需要展示其中符合某些条件的要素,就可以使用 feature laye r的过滤功能。 我们可以通过客户端方式或服务端方式结合SQL表示和空间表达式进行 feature layer 的过滤显示。
被过滤的feature layer 可以托管在 ArcGIS Online
或 ArcGIS 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
中加入FeatureLayer
、GraphicLayer
和Graphic
的模块引用。
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer"
],function(Map, MapView, FeatureLayer
在 main 方法的底部,创建一个 Trails
的 FeatureLayer
对象,开启并设置 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 显示出来的要素不一样,效果图如下。
再撸点
为被过滤排除的要素配置样式
默认情况下,当图层开启过滤时,只要符合过滤条件的要素才会显示出来,但如果我们也想显示不符合过滤条件的要素时,可以给 FeatureLayerView
的 effect
属性设置值。该属性需要设置 filter
和 excludedEffect
分别代表过滤条件和被过滤排除要素的显示样式(使用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
方法获取到屏幕坐标之后进行查找要素。当 view
和 FeatureLayerView
加载完成, 鼠标移到时,我们可以使用 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
查看。