Geotools中关于filter和ECQL的介绍

文章目录
  1. 1. filter和ECQL的介绍
  2. 2. 实现的原理

filter和ECQL的介绍

在geotools中有datastore就需要对应数据源的查询这边是基于opengis定义的接口来定义现在先看下

filter这个类的介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface Filter {

//使用Filter.INCLUDE过滤集合将会返回原始集合。
IncludeFilter INCLUDE = new IncludeFilter();

//使用Filter.EXCLUDE过滤集合将会返回空集合。
ExcludeFilter EXCLUDE = new ExcludeFilter();


//给定一个对象,确定此过滤器对象所表示的测试是否通过。如果测试通过,则返回true,否则返回false
boolean evaluate(Object object);

//接受一个访问者(FilterVisitor)。实现所有子接口必须具有以下内容的方法:
//visitor.visit(this, extraData);
Object accept(FilterVisitor visitor, Object extraData);
}

下面是使用Filter查询Geometry类型为Point且位于指定矩形区域内的要素的示例代码:

1
2
3
4
5
6
7
8
//创建一个矩形过滤器
Filter filter = FF.and(
FF.equal(FF.property("geometry").getType(), FF.literal("Point")),
FF.bbox("geometry", -180, -90, 180, 90, "EPSG:4326")
);

//应用过滤器获取要素集合
SimpleFeatureCollection features = featureSource.getFeatures(filter);

ECQL对应filter跟一步封装我们只需要传入参数和对应方法,用一个字符串来传入即可,它基于OGC标准并支持更多的查询操作。与Filter不同的是,ECQL使用类SQL语法编写查询表达式,并可以执行更复杂的查询,例如计算距离或使用正则表达式匹配属性值。下面是使用ECQL查询两个图层之间距离小于指定值的示例代码:

1
2
3
4
5
//创建一个ECQL查询表达式
String query = "DWITHIN(geometry, POINT(0 0), 100, meters)";

//应用查询获取要素集合
SimpleFeatureCollection features = featureSource.getFeatures(ECQL.toFilter(query));

需要注意的是,ECQL的语法相对复杂

实现的原理

很简单的逻辑对于不同的数据源其实很多方法是不一样的对应数据库也许有对应的函数,对应shp文件这种也许我们只能在内存中操作,对应gpkg这种也许有其他的方式来计算

对应filter通常有两种

  • 一种是属性的判断 类似< > = like 这种
  • 第二种是 geometry 判断拓扑关系 相交,包含,相切,相离 还有可能是运行 切割或者分离

所以这里有定义一个抽象类来定义了要参考

AbstractFilterVisitor: FilterVisitor 的抽象实现类,提供了一些通用的方法,例如visit(Filter)和visitNullFilter()等。

DefaultFilterVisitor :FilterVisitor的默认实现类,提供了对所有Filter对象的访问方法,例如visit(EqualsFilter)、visit(GreaterThanFilter)等。

ECQLFilterVisitor :FilterVisitor的ECQL实现类,用于解析ECQL表达式。ECQLFilterVisitor提供了一组visit方法,用于访问ECQL表达式中的不同类型的Filter对象。

SQLFilterVisitor :FilterVisitor的SQL实现类,用于将Filter对象转换为SQL语句。SQLFilterVisitor提供了一组visit方法,用于访问不同类型的Filter对象,并将其转换为SQL语句。

ComparisonFilter : 这是一个用于比较的过滤器类,它根据给定条件对值进行比较。常见的例子包括大于、小于、等于等比较操作符。使用该类可以方便快捷地进行数据筛选和排序。

LogicFilter: 这是一个用于逻辑运算的过滤器类,它可以将多个过滤器连接起来,并根据给定的逻辑关系进行组合。例如,可以使用 And 或 Or 运算符将两个或更多的过滤器连接在一起,以实现复杂的查询需求。

举例子来看一读取gpkg数据来看

对应空间查询最后走到GeoPkgDialect下的simpleSpatialSearch来拼接SQL查询拓扑关系

里面有filter.accept()来判断

1280X1280

最后还是走到JDBCDataStore下的selectSQLPS方法下执行对应的sql来实现的查询

output

在geotools中会多次走到重复的方法,会有一定的误导作用主要是反射和部分结构设计导致的,需要我们在特定实现的类上面打断点会好很多