In order to perform spatio-temporal query, spatial data and temporal data should be indexed and spatio-temporal operations should be supported. Supporting these capabilities can be achieved via adapting the way that Alejandro Rodriguez developed Data Stream API 2.0). The goal of this project is
Note that the ontology for Spatial information and query is based on the GeoSPARQL proposal by Oracle . It needs to be updated with the current draft of OGC GeoSPARQL.
The Figure 1 shows the Spatio-Temporal composite context that supports spatio-temporal queries. The composite context will analyze the query and store temporal data and temporal data to database tables that supports temporal index and spatial index.
Figure 1. Spatio-temporal Composite Context
Here are how the spatio-temporal query is treated and handled:
The PostGIS, spatial extension for PostgreSQL dbms is used for spatial database. Since PostGIS follows the OGC spec, the name of spatial SQL functions defined in PostGIS are same as predicates we are using in this development.
Note that temporal query will be performed first then the spatial query will be performed later. Because of the design and implementation of DSAPI, the spatial query will be performed with triple matcher instead of Union query. And it will be the performance bottleneck.
The design is implemented by extending Postgresql implementation of StreamingContext and override methods:
If there is “ogc:hasWKT” predicate, then write WKT geometry to the PostGIS table
// hasWKT predicate needs to write geometry to spatial db if (t.getPredicate().equals(HAS_WKT) && t.getObject() != null) { // writing geometry to spatial db insertGeom.setString(1, "u" + t.getSubject().getUri().toString()); insertGeom.setString(2, getPolygon(t.getObject())); insertGeom.executeUpdate(); } |
If the predicate is “ogc:within”, then do geospatial query. Otherwise, perform regular triple-matching
Wrap the sql statement for non-spatial pattern with spatial sql statement
private String addSpatialQuery(Unifier spatialUnifier, PreparedStatement statement, int numCol) { String polygon = spatialUnifier.getPatterns().get(0).getObject() .toString(); String sql = "SELECT "; for (int i = 0; i < numCol; i++ ) { if (i == 0) sql = sql + "a.c" + i + " as c" + i + ","; else sql = sql + "a.c" + i + " as c" + i + ",a.c" + i + "_typ as c" + i + "_typ,"; } sql = sql.substring(0, sql.length() - 1) + " FROM (" + statement.toString() + ") as a " + "LEFT JOIN " + GEOMETRY_TABLE + " as b " + "ON a.c0 = b.uri " + "where ST_Within(b.the_geom, ST_GeomFromText('" + polygon + "'," + WGS84 + ")) and a.c0 = b.uri"; return sql; } |
As mentioned above about the performance bottleneck, the spatial unifier is not used efficiently. In order to overcome this problem, the temporal query needs to be combined with normal query. In other words, the temporal query needs to be translated into SQL statement and combined with other SQL statement for normal query.
Assumption:
Here are the example unifier query and expected SQL statement to be generated:
columns: ?s, ?flavor, ?temp pattern 1: ?s urn:flavor "pistachio" pattern 3: ?s urn:flavor ?flavor pattern 4: ?s["37".."39"] urn:temp ?temp |
select distinct (select sym from sym where uid=p0.sub) as c0, tok1.token_id as c0_frame_id, tok1.start as c0_time, (select sym from sym where uid=p1.obj) as c1, (select sym from sym where uid=p1.typ) as c1_typ, (select sym from sym where uid=p2.obj) as c2, (select sym from sym where uid=p2.typ) as c2_typ from tup p0 join tup p1 on p1.sub=p0.sub and p1.pre=(select uid from sym where md5(sym)=md5('uurn:flavor')) join tup p2 on p2.sub=p0.sub and p2.pre=(select uid from sym where md5(sym)=md5('uurn:temperature')) join tokens tok1 on tok1.uid=p1.sub and tok1.start >= 37 and tok1.end <= 39 where p0.pre=(select uid from sym where md5(sym)=md5('uurn:flavor')) and p0.obj=(select uid from sym where md5(sym)=md5('lpistachio')); |