云数据库 HBase 查询时空对象

By | 2021年4月22日

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)

### 时空查询
除了空间查询场景以外,还存在大量的时空查询需求。如查询过去2小时内,位于(20E,30N,130E,40N)范围内所有的车辆轨迹。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(quer
            

上例查询中对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);

请关注公众号获取更多资料

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注