全部产品

查询时空对象

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)所包含的空间对象(餐馆、船舶、车辆等)

//获取DataStore
DataStore ds = DataStoreFinder.getDataStore(params);
//设置查询条件
String schema = "schmaName";
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谓词将所有对象过滤出来

    //获取DataStore
    DataStore ds = DataStoreFinder.getDataStore(params);
    //设置查询条件
    String schema = "schmaName";
    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));
    //获取查询结果
    SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);

时空查询

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

Lindorm 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之后

Lindorm Ganos支持的时间表达方式有多种:

Time / Time

由起始时间和结束时间定义的区间

Duration / Time

在Time之前的时间区间

Time / Duration

在Time之后的时间区间

  • 案例:如用户想查询位于(120E,30N,130E,40N)之中,时间介于2014-01-01T11:45:00与2014-01-01T12:15:00之间的车辆轨迹,那么需要将空间查询和时间查询结合在一起,如下:

//设置查询条件
String schema = "schmaName";
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);

属性查询

  • 比较运算符包括: =,<>,>,>=,<,<=,如要选取人口大于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 schema = "schemaName";
String filter = "name = 'bob'";
Query query = new Query(schema, ECQL.toFilter(filter));
//获取查询结果
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);

指定返回列名

用户可以通过配置Query对象参数指定具体返回哪些列,如:

//指定返回字段名
String[] returnFields={"geom"};
//设置查询条件
String schema = "schmaName";
String stFilter = "bbox(geom, 120,30,130,40)"
Query query = new Query(schema, ECQL.toFilter(stFilter));
query.setPropertyNames(returnFields);
//获取查询结果集
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);

指定排序方式

用户可以通过构建SortBy对象参数指定具体返回哪些列,如:

String sortField="name" //指定排序字段名
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
SortBy[] sort = new SortBy[]{ff.sort(sortField, order)};
query.setSortBy(sort);
SimpleFeatureCollection features=ds.getFeatureSource(schema).getFeatures(query);