使用Ganos API进行时空查询时,首先需要构建一个org.geotools.data.Query对象,并指定过滤条件、返回列名,排序等相关参数,然后通过DataStore提交Ganos集群运行,最后查询结果会以SimpleFeature集合的形式返回给用户。
CQL通用查询语言
Query对象中的查询条件是通过构建CQL查询语句进行的。CQL(Common Query Language,通用查询语言)是OGC为目录Web服务规范创建的查询语言,不像基于XML的编码语言,CQL使用我们更熟悉的文本语法编写,具有更好的可读性和适应性。
- 比较运算符包括:
=
,<>
,>
,>=
,<
,<=
,如要选取人口大于1500万的城市,条件为PERSONS>15000000
,其中PERSONS为人口数量的字段,后面不再单独说明。 - BETWEEN表示从一个范围到另一个范围,例如:
PERSONS BETWEEN 1000000 AND 3000000
。 - 比较运算符支持文本值,可在运算符的右侧指定文本值,例如:
CITY_NAME='Beijing'
,表示选择北京市。也可以使用LIKE操作符,与SQL中的用法一样,例如:CITY_NAME LIKE 'N%'
,表示查询所有以N开头的城市。 - 对两个属性进行比较,例如:
MALE > FEMALE
,表示查询男性比女性多的城市。 - 算术表达式可以使用
+
,-
,*
,/
构成,例如:过滤条件为UNEMPLOY/(EMPLOYED + UNEMPLOY) > 0.07
,表示查询所有失业率大于7%的城市。 - 使用IN操作符,可选择属性在给定值范围内的,与SQL用法相同,如ID IN ('cities.1', 'cities.12'),或查找名字在给定值内的城市,可使用CITY_NAME IN ('Beijing','Shanghai', 'Guangzhou')。
- 可使用Geoserver中的任何过滤函数,如strToLowerCase(CITY_NAME) like '%m%',表示名字中包含m的城市,不区分M的大小写。
- 几何过滤,使用BBOX,如BBOX(the_geom, -90, 40, -60, 45)表示选择在(-90, 40, -60, 45)范围内的城市。 关于CQL的详细介绍请参见ECQL参考。
空间关系查询
CQL中定义的空间关系查询谓词如下表所示:
语法 | 描述 |
---|---|
INTERSECTS(Expression , Expression) | 判断两个空间要素是否相交。 |
DISJOINT(Expression , Expression) | 判断两个空间要素是否相离。 |
CONTAINS(Expression , Expression) | 判断第一个要素是否在拓扑关系上包含第二个要素。 |
WITHIN(Expression , Expression) | 判断第一个要素是否在拓扑关系上被包含在第二个要素之中。 |
TOUCHES(Expression , Expression) | 判断两要素是否相接,即至少有一个公共点要素。 |
CROSSES(Expression , Expression) | 判断两个空间要素是否相交,要求仅有部分交集而不是完全包含。 |
EQUALS(Expression , Expression) | 判断两个空间要素是否相等。 |
BBOX ( Expression , Number , Number , Number , Number [ , CRS ]) | 测试空间要素是否与由其最小和最大X和Y值指定的边界框相交。可选的CRS是包含SRS代码的字符串,例如,'EPSG:1234'。默认使用查询图层的CRS。 |
比如获取所有位于空间范围:(120E,30N,130E,40N)中的所有要素:
DataStore ds = DataStoreFinder.getDataStore(params);
SimpleFeatureType schema=...
String stFilter = "bbox(geom, 120,30,130,40)"
Query query = new Query(schema, ECQL.toFilter(stFilter));
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);
或者获取(46.9 48.9, 47.1 48.9, 47.1 49.1, 46.9 49.1, 46.9 48.9)构建的多边形中的所有元素:
String stFilter = "contains('POLYGON ((46.9 48.9, 47.1 48.9, 47.1 49.1, 46.9 49.1, 46.9 48.9))', geom)
Query query = new Query(schema, ECQL.toFilter(stFilter));
时空查询
HBase Ganos支持的时间查询谓词如下:
语法 | 语法 |
---|---|
Expression BEFORE Time | 时间在Time之前。 |
Expression BEFORE OR DURING Time Period | 时间在 Time Period之前或包含在 Time Period之中。 |
Expression DURING Time Period | 时间在Time Period之中。 |
Expression DURING OR AFTER Time Period | 时间在Time Period之中或之后。 |
Expression AFTER Time | 时间在Time Period之后。 |
HBase Ganos支持的时间表达方式有多种:
语法 | 描述 |
---|---|
Time / Time | 由起始时间和结束时间定义的区间。 |
Duration / Time | 在Time之前的时间区间。 |
Time / Duration | 在Time之后的时间区间。 |
说明 目前HBase Ganos还不支持单独时间查询,需要配合空间查询一起进行。
如果您想查询位于(120E,30N,130E,40N)之中,时间介于2014-01-01T11:45:00与2014-01-01T12:15:00之间的要素:
String stFilter = "bbox(geom, 120,30,130,40) AND dtg DURING 2014-01-01T11:45:00.000Z/2014-01-01T12:15:00.000Z";
Query query = new Query(schema, ECQL.toFilter(stFilter));
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);
属性查询
当用户指定针对某一属性字段创建索引之后,就可以对该列进行属性查询:
String filter = " name = 'bob'"
val q = new Query(sft.getTypeName, ECQL.toFilter(filter))
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);
上例查询中对name字段的值做了限制。
指定返回列名
您可以通过配置Query对象参数指定具体返回哪些列。
String[] returnFields=... //指定返回字段名
Query query = new Query(schema, ECQL.toFilter(ecqlPredicate));
query.setPropertyNames(returnFields);
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);
指定排序方式
您可以通过构建SortBy对象参数指定具体返回哪些列。
String sortField=... //指定排序字段名
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
SortBy[] sort = new SortBy[]{ff.sort(sortField, order)};
query.setSortBy(sort);
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);