使用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);