主题
查询和过滤简介
字数统计: 3k 字
阅读时长: 约 7 分钟
当前版本: 4.29
本主题介绍查询和过滤数据的多种使用场景。服务器数据或客户端数据都可以执行查询和过滤操作。
我们首先要知道哪些图层允许查询和过滤子集。为此,我们必须了解服务器端与客户端图层以及 Layer 和 LayerView 。
服务器端和客户端图层
允许查询和过滤图层可分为服务器端图层和客户端图层。
服务器端图层 在加载时仅获取所需要素。之后会根据请求从服务器获取对应的要素。这种类型的图层有:FeatureLayer、OGCFeatureLayer、SceneLayer 和 StreamLayer。它们在创建对象时, url
属性是对应服务地址。
客户端图层 是一次获取所有要素,并在加载时将要素存储在客户端。加载完这些图层后,将不再发起服务器请求。这类图层有:CSVLayer、GeoJSONLayer 和 WFSLayer。它们在创建对象时, url
的值是 csv 或 geojson 文件或 WFS 服务的地址。客户端图层还包括从客户端图形数组创建 FeatureLayer的情况,设置源属性创建图层。
图层和图层视图
在 MapView 和 SceneView 中添加图层的同时,都会创建一个图层视图 LayerView。LayerView 在视图中负责渲染要素。它提供了多种方法和属性,方便开发者在客户端视图中查询、过滤和高亮显示图形。
下表罗列了用户在视图添加图层时的简要过程。
步骤 | 服务器端图层 | 客户端图层 |
---|---|---|
图层 | FeatureLayer、OGCFeatureLayer、SceneLayer 和 StreamLayer | CSVLayer、GeoJSONLayer、WFSLayer 和客户端 FeatureLayer |
初始化 | 设置 url 属性创建图层对象,url 值为服务器端要素、场景或流服务地址。js const layer = new FeatureLayer({ url: "service url" }); view.map.add(layer); | CSVLayer、GeoJSONLayer 和 WFSLayer 通过设置 url 属性创建对象。客户端 FeatureLayer 通过设置 源 属性创建对象。 const layer = new CSVLayer({ url: "csv file url" }); view.map.add(layer); |
获取对象初次加载 | 仅从服务器获取所需的要素,后续按需加载。 | 一次获取所有要素,并将要素存储在客户端。 |
初始化图层视图 | FeatureLayer、OGCFeatureLayer、SceneLayer 和 StreamLayer 的图层视图分别是 FeatureLayerView、OGCFeatureLayerView、SceneLayerView 和 StreamLayerView ,初始化后可以绘制要素。 view.whenLayerView(layer).then(function(layerView){ // now we have access to the layerView, an // object representing the layer in the view }); | CSVLayer、GeoJSONLayer、FeatureLayer 和 WFSLayer 的图层视图分别是 CSVLayerView、GeoJSONLayerView、FeatureLayerView 和 WFSLayerView ,初始化后可以绘制要素。view.whenLayerView(layer).then(function(layerView){ // now we have access to the layerView, an // object representing the layer in the view }); |
是否有后续的服务请求 | 是。根据需要发出请求要素。 | 否,如果加载后不刷新图层。是。刷新图层时,服务器端有数据更新。 |
下图直观地展示了图层和图层视图可查询的要素范围对比情况。如图所示,图层涵盖的要素范围远大于程序的初始范围,而图层视图是在图层加载后生成,它能访问的是应用程序初始范围内的可见要素。图层对象提供了针对所有要素的属性和方法,而图层视图上的操作只针对视图可视范围内的要素有效。图中还显示了图层和图层视图中可用要素个数的对比。图层视图的要素数要少得多,因为它返回的是视图初始范围内的要素,而图层里返回的是所有要素个数。

查询
API提供了三种查询方式:属性查询、空间查询和统计查询。此文档有关于每种查询类型的详细介绍。图层和图层视图都可以执行查询。
服务器端查询
在服务器端图层上调用 query...
发出的是服务器端查询。查询的范围是要素服务中所有要素。
js
(Feature|Scene)Layer // queries all features in the service
.queryFeatures() // queries all features and returns a FeatureSet
.queryExtent() // queries all features returns extent of features that satisfy query
.queryFeatureCount() // queries all features and returns count of features
.queryObjectIds() // queries all features and returns objectIds array of features
客户端查询
在客户端图层或 layerView 上调用 query...
时执行的是客户端查询。查询范围是图层或图层视图内的所有可用要素。
js
(Feature|CSV|GeoJSON|WFS)Layer // queries all features in the layer
(Feature|CSV|GeoJSON|OGCFeature|Scene|Stream)LayerView // queries available features in view
.queryFeatures() // queries features and returns a FeatureSet
.queryExtent() // queries features returns extent of features that satisfy query
.queryFeatureCount() // queries features and returns count of features
.queryObjectIds() // queries features and returns objectIds array of features
使用客户端查询还是服务器端查询?
对比项 | 服务器端查询 | 客户端查询 |
---|---|---|
速度和响应能力 | 需要发出网络请求,与客户端查询相比,速度较慢 | 快 |
几何精度 | 高。保留了几何精度。通过几何图形查询精确结果时很重要。 | 客户端图层空间查询时,精度高。图层视图查询,精度则低,因为绘制时会有概化,不太精确,而且随着用户缩放地图也会发生变化。类似的例子有:计算所选图形的面积、计算多边形中包含了哪些点。 |
是否查询每个要素 | 是。对所有要素执行查询。结果数量过多时,可以执行分页查询。 | CSVLayer、GeoJSONLayer 和客户端 FeatureLayer,是查询所有要素。但对于 layerViews,则为否,因为它仅查询客户端可用要素。 |
图层视图查询的小技巧
在图层初始化时,将查询字段添加到 outFields 中,确保客户端能访问到这些字段。默认情况下,图层视图只请求图层渲染、标注和高程信息所需的必要字段。
程序加载后,必须等到 layerView 对象的 updating 属性变为
false
后才能执行图层视图查询,因为这时候要素才能加载完成。如果需要在初始化时执行查询,可以调用 reactiveUtils.whenOnce方法。如果每次视图范围发生变化时都需要查询图层视图,那么必须等到 layerView 的 updating 属性变为
false
,以确保图层视图已完成该范围内的要素获取。客户端属性值区分大小写。
此教程演示了如何查询 FeatureLayer 和 FeatureLayerView。
过滤
过滤影响图层中要素的可用性或图层视图中要素的可见性。视图中只显示满足过滤器要求的要素。过滤可以在服务器端或客户端进行。
服务器端过滤
所有类型的图层都提供了 definitionExpression 属性。在服务器端图层上设置 definitionExpression
将触发网络请求,获取满足该表达式的要素。对于大数据量要素过滤非常有用。如果在图层加载后再设置过滤条件,视图会自动刷新并显示满足新表达式的要素。
js
// fetch all features that satisfy requirements from the service
(Feature|Scene|Stream)Layer
.definitionExpression = "type = 'metal'";
客户端过滤
客户端图层的 definitionExpression
控制显示哪些要素,符合 definitionExpression 的要素将会被显示。definitionExpression属性对客户端所有要素有效。
js
// only display features that satisfy the requirements in the layer
(Feature|CSV|GeoJSON|WFS)Layer
.definitionExpression = "mag > 5";
图层一旦设置了 definitionExpression
,图层视图的所有查询和过滤都要遵循 definitionExpression
条件。 也就是只有满足 definitionExpression
条件的要素才会被图层视图进行二次查询和过滤。
LayerView 提供了 filter
操作,实现过滤绘制要素的功能。FeatureFilter 允许您在 layerView 中显示满足过滤器要求的要素。由于过滤器应用于 layerView,因此在客户端针对可用于绘制的要素会发生这种情况。
js
(Feature|CSV|GeoJSON|OFCFeature|Scene|Stream|WFS)LayerView
// only display features that satisfy the requirements in the layer
.filter = new FeatureFilter({
where: "age > 25";
});
可基于属性、时间和几何来应用过滤器。此教程演示了如何在 FeatureLayer 上执行查询和过滤。
对于 SceneLayers,可通过在图层上直接设置过滤器来对要素应用过滤。SceneFilter 允许您在图层中显示满足过滤器要求的要素,并将这些信息保存在 WebScene 或 SceneLayer 中。尽管过滤器应用于图层,但过滤仍在客户端进行。
js
// only display features that satisfy the requirements in the layer
SceneLayer.filter = new SceneFilter({
geometries: [polygon1, polygon2],
spatialRelationship: "contains"
});
SceneFilters 接受几何列表和某个 spatialRelationship。
您还可以将 FeatureEffect 应用于 FeatureLayer、CSVLayer、GeoJSONLayer、OGCFeatureLayer、StreamLayer 和 WFSLayer,或应用于 FeatureLayerView、CSVLayerView、GeoJSONLayerView、OGCFeatureLayerView、StreamLayerView 或 WFSLayerView,以突出感兴趣要素。在图层或 layerView 上设置过滤器时,可以指定不同的效果。includedEffect 将应用于符合过滤器要求的那些要素。excludedEffect 则应用于不符合过滤器要求的那些要素。
js
(Feature|CSV|GeoJSON|OFCFeature|Stream|WFS)LayerView
// gray out features that fall outside of the 3 mile buffer of the mouse's location
// by setting feature effect on excluded features
.featureEffect = new FeatureEffect({
filter: new FeatureFilter({
geometry: filterGeometry,
spatialRelationship: "intersects",
distance: 3,
units: "miles"
}),
excludedEffect: "grayscale(100%) opacity(30%)"
});
js
(Feature|CSV|GeoJSON|OFCFeature|Stream|WFS)LayerView
// Apply a drop-shadow feature effect to the features that have population greater than one million,
// while applying blur and brightness effects to the features that are excluded from filter criteria.
// The resulting map will make it easier to spot areas with population greater than one million.
.featureEffect = new FeatureEffect({
filter: new FeatureFilter({
where: "POPULATION > 1000000"
}),
includedEffect: "drop-shadow(3px, 3px, 3px, black)",
excludedEffect: "blur(1px) brightness(65%)"
});