Query spatiotemporal objects

Updated at:

GanosBase uses GeoTools Query objects to query data. Build query conditions as CQL (Common Query Language) filter expressions — similar to a SQL WHERE clause — then pass the Query object to retrieve a SimpleFeatureCollection. Use an iterator to traverse the returned SimpleFeature objects and extract the data you need.

All query examples use the same pattern:

DataStore ds = DataStoreFinder.getDataStore(params);
String schema = "schemaName";
String filter = "<CQL filter expression>";
Query query = new Query(schema, ECQL.toFilter(filter));
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Property queries

Property filters are the simplest query type. They support the following operators:

OperatorDescriptionExample
=, <>, >, >=, <, <=Comparison operatorsPERSONS > 15000000 selects cities with a population greater than 15,000,000
BETWEEN ... AND ...Range filterPERSONS BETWEEN 1000000 AND 3000000
LIKEPattern matching (same as SQL)CITY_NAME LIKE 'N%' selects cities whose names start with N
= with a quoted stringText equalityCITY_NAME = 'Beijing'
Attribute vs. attributeProperty comparisonMALE > FEMALE selects cities where the male population exceeds the female population
+, -, *, /Arithmetic expressionsUNEMPLOY / (EMPLOYED + UNEMPLOY) > 0.07 selects cities with an unemployment rate above 7%
INSet membershipCITY_NAME IN ('Beijing', 'Shanghai', 'Guangzhou')
GeoServer filter functionsFunction expressionsstrToLowerCase(CITY_NAME) LIKE '%m%' selects cities whose names contain m regardless of case
BBOXBounding box filterBBOX(the_geom, -90, 40, -60, 45) selects cities within the geographic range

Example: Filter records by attribute value

DataStore ds = DataStoreFinder.getDataStore(params);
String schema = "schemaName";
String filter = "name = 'bob'";
Query query = new Query(schema, ECQL.toFilter(filter));
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Spatial queries

Spatial queries filter data based on the geometric relationship between two spatial objects. Each spatial object is expressed in Well-Known Text (WKT) format.

In the following table, square brackets [...] denote optional parameters.
SyntaxDescription
INTERSECTS(Expression, Expression)Tests whether two geometries intersect. The converse of DISJOINT.
DISJOINT(Expression, Expression)Tests whether two geometries are disjoint (no overlap). The converse of INTERSECTS.
CONTAINS(Expression, Expression)Tests whether the first geometry contains the second. The converse of WITHIN.
WITHIN(Expression, Expression)Tests whether the first geometry is within the second. The converse of CONTAINS.
TOUCHES(Expression, Expression)Tests whether the boundaries of two geometries intersect while their interiors do not.
CROSSES(Expression, Expression)Tests whether two geometries partially intersect (not complete containment).
BBOX(Expression, Xmin, Ymin, Xmax, Ymax [, CRS])Tests whether the geometry intersects the rectangle defined by [Xmin, Ymin, Xmax, Ymax]. The optional CRS parameter specifies the coordinate reference system as a Spatial Reference System (SRS) code string, for example 'EPSG:1234'. Defaults to the CRS of the query layer.

Example: Query objects within a bounding box

Retrieve all spatial objects (such as restaurants, ships, or vehicles) within the geographic range of 120°E–130°E, 30°N–40°N:

DataStore ds = DataStoreFinder.getDataStore(params);
String schema = "schemaName";
String filter = "bbox(geom, 120,30,130,40)";
Query query = new Query(schema, ECQL.toFilter(filter));
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Example: Query vehicles within a 5 km radius

First, express the 5 km radius as a WKT polygon. Then apply the CONTAINS predicate to filter all matching objects:

DataStore ds = DataStoreFinder.getDataStore(params);
String schema = "schemaName";
String filter = "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(filter));
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Spatiotemporal queries

Combine a spatial predicate with a temporal predicate to filter data by both location and time. GanosBase supports the following time predicates, where Expression is the name of the time column and Time is a UTC timestamp string.

Temporal predicates

SyntaxDescription
Expression BEFORE TimeMatches records where the time is before Time.
Expression BEFORE OR DURING Time PeriodMatches records where the time is before or within Time Period.
Expression DURING Time PeriodMatches records where the time falls within Time Period.
Expression DURING OR AFTER Time PeriodMatches records where the time is within or after Time Period.
Expression AFTER TimeMatches records where the time is after Time.

Time period formats

SyntaxDescription
Time / TimeAn interval defined by a start time and an end time.
Duration / TimeA time interval ending at Time.
Time / DurationA time interval starting at Time.

Example: Query vehicle trajectories within a geographic range and time window

Retrieve vehicle trajectories within 120°E–130°E, 30°N–40°N that occurred between 2014-01-01T11:45:00 UTC and 2014-01-01T12:15:00 UTC:

String schema = "schemaName";
String filter = "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(filter));
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Specify returned columns

Configure Query.setPropertyNames() to return only specific columns:

String[] returnFields = {"geom"};
String schema = "schemaName";
String filter = "bbox(geom, 120,30,130,40)";
Query query = new Query(schema, ECQL.toFilter(filter));
query.setPropertyNames(returnFields);
SimpleFeatureCollection features = ds.getFeatureSource(schema).getFeatures(query);

Specify sort order

Build a SortBy object using FilterFactory2 and pass it to Query.setSortBy():

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