Ganos的数据查询采用GeoTools Query对象来完成,Query中的查询条件是通过构建CQL查询语句来实现的。同时Query还有更多强大的功能,可以指定返回的属性列、对某一属性进行排序等。返回的数据是以SimpleFeatureCollection对象存在,可以通过迭代器遍历所有的SimpleFeature,进而解析出需要的数据。
构造查询条件
查询条件也称之为过滤器(Filter),采用CQL语言描述。CQL功能类似SQL语句的WHERE子句,根据这些条件可以过滤数据。
空间查询
空间查询支持如下谓词,表中的Expression表示WKT表示的空间对象(点、线、面):
语法 | 描述 |
---|---|
INTERSECTS(Expression , Expression) | 判断两个空间对象是否相交,例如两条道路是否相交。 |
DISJOINT(Expression , Expression) | 判断两个空间对象是否相离。 |
CONTAINS(Expression , Expression) | 判断第一个空间对象是否包含第二个空间对象。 |
WITHIN(Expression , Expression) | 与CONTAINS谓词相反,判断第一个对象是否被第二个空间对象包含。 |
TOUCHES(Expression , Expression) | 判断两要素是否相接,即至少有一个公共点要素。 |
CROSSES(Expression , Expression) | 判断两个空间要素是否相交,要求仅有部分交集而不是完全包含。 |
BBOX(Expression , Xmin , Ymin , Xmax , Ymax [ , CRS ]) | 空间对象[Expression]是否与[Xmin,Ymin,Xmax,Ymax]所组成的四边形相交。 |
可选的CRS是空间参考系,包含SRS代码的字符串(例如,EPSG:1234。默认使用查询图层的CRS)。
- 案例1:获取某个空间范围(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);
-
案例2:获取周边5公里范围内的所有车辆。
- 首先将周边5公里的范围构造成空间对象(面),假设为(46.9 48.9, 47.1 48.9, 47.1 49.1, 46.9 49.1, 46.9 48.9)。
- 使用contains谓词将所有对象过滤出来```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)
时空查询
HBase Ganos支持的时间查询谓词如下,表中的Expression为时间列名,Time为字符串。表示的时间UTC:
语法 | 描述 |
---|---|
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之后的时间区间 |
示例:如用户想查询位于(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.00
Query query = new Query(schema, ECQL.toFilter(stFilter));
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);
说明
- 比较运算符包括:=,<>,>,>=,<,<=,如要选取人口大于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)范围内的城市。
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);