全部产品

查询时空对象

更新时间:2019-08-12 10:02:01

查询时空对象

Ganos的数据查询采用GeoTools Query对象来完成,Query中的查询条件是通过构建CQL查询语句来实现的。同时Query还有更多强大的功能,可以指定返回的属性列、对某一属性进行排序等。
返回的数据是以SimpleFeatureCollection对象存在,可以通过迭代器遍历所有的SimpleFeature,进而解析出需要的数据。
下面会分步介绍详细流程,所有介绍的流程均可参考「快速入门」代码示例GanosClient类。

构造查询条件

查询条件也称之为过滤器(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)所包含的空间对象(餐馆、船舶、车辆等):
  1. DataStore ds = DataStoreFinder.getDataStore(params);
  2. SimpleFeatureType schema=...
  3. String stFilter = "bbox(geom, 120,30,130,40)"
  4. Query query = new Query(schema, ECQL.toFilter(stFilter));
  5. 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)

Query query = new Query(schema, ECQL.toFilter(stFilter));

  1. <a name="aLbWC"></a>
  2. ### 时空查询
  3. 除了空间查询场景以外,还存在大量的时空查询需求。如查询过去2小时内,位于(20E,30N,130E,40N)范围内所有的车辆轨迹。<br />HBase Ganos支持的**时间查询**谓词如下,表中的「Expression」为时间列名,「Time」为字符串表示的时间(UTC):
  4. | 语法 | 描述 |
  5. | --- | --- |
  6. | Expression BEFORE Time | 时间在Time之前 |
  7. | Expression BEFORE OR DURING Time Period | 时间在 Time Period之前或包含在 Time Period之中 |
  8. | Expression DURING Time Period | 时间在Time Period之中 |
  9. | Expression DURING OR AFTER Time Period | 时间在Time Period之中或之后 |
  10. | Expression AFTER Time | 时间在Time Period之后 |
  11. HBase Ganos支持的时间表达方式有多种:
  12. | 语法 | 描述 |
  13. | --- | --- |
  14. | Time / Time | 由起始时间和结束时间定义的区间 |
  15. | Duration / Time | 在Time之前的时间区间 |
  16. | Time / Duration | 在Time之后的时间区间 |
  17. - 案例:如用户想查询位于(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);

  1. <a name="QjYho"></a>
  2. ### 属性查询
  3. - 比较运算符包括: =,<>,>,>=,<,<=,如要选取人口大于1500万的城市,条件为PERSONS>15000000,其中PERSONS为人口数量的字段,后面不再单独说明。
  4. - BETWEEN表示从一个范围到另一个范围,如PERSONS BETWEEN 1000000 AND 3000000。
  5. - 比较运算符支持文本值,可在运算符=的右侧指定文本值,如 CITY_NAME='Beijing',表示选择北京市;也可以使用LIKE操作符,与SQL中的用法一样,如 CITY_NAME LIKE 'N%'会选择所有以N开头的城市。
  6. - 对两个属性进行比较,如 MALE > FEMALE,选择男性多余女性的城市。
  7. - 算术表达式可以使用 +, -, *, /构成,如过滤条件 UNEMPLOY/(EMPLOYED + UNEMPLOY) > 0.07选择所有失业率大于7%的城市。
  8. - 使用IN操作符,可选择属性在给定值范围内的,与SQL用法相同,如 ID IN ('cities.1', 'cities.12'),或查找名字在给定值内的城市,可使用 CITY_NAME IN ('Beijing','Shanghai', 'Guangzhou')。
  9. - 可使用Geoserver中的任何过滤函数,如 strToLowerCase(CITY_NAME) like '%m%',表示名字中包含m的城市,不区分M的大小写。
  10. - 几何过滤,使用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);

  1. 上例查询中对name字段的值做了限制。
  2. <a name="qnVJz"></a>
  3. ### 指定返回列名
  4. 用户可以通过配置Query对象参数指定具体返回哪些列,如:

String[] returnFields=… //指定返回字段名

Query query = new Query(schema, ECQL.toFilter(ecqlPredicate));

query.setPropertyNames(returnFields);

SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);

  1. <a name="9dRCr"></a>
  2. ### 指定排序方式
  3. 用户可以通过构建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);```