package mil.nga.giat.geowave.core.geotime.store.query;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
import mil.nga.giat.geowave.core.geotime.GeometryUtils;
import mil.nga.giat.geowave.core.geotime.index.dimension.TimeDefinition;
import mil.nga.giat.geowave.core.geotime.store.filter.SpatialQueryFilter.CompareOperation;
import mil.nga.giat.geowave.core.index.sfc.data.NumericRange;
/**
* The Spatial Temporal Query class represents a query in three dimensions. The
* constraint that is applied represents an intersection operation on the query
* geometry AND a date range intersection based on startTime and endTime.
*
*
*/
public class SpatialTemporalQuery extends
SpatialQuery
{
protected SpatialTemporalQuery() {}
public SpatialTemporalQuery(
final Date startTime,
final Date endTime,
final Geometry queryGeometry ) {
super(
createSpatialTemporalConstraints(
startTime,
endTime,
queryGeometry),
queryGeometry);
}
public SpatialTemporalQuery(
final TemporalConstraints constraints,
final Geometry queryGeometry ) {
super(
createSpatialTemporalConstraints(
constraints,
queryGeometry),
queryGeometry);
}
/**
* If more then on polygon is supplied in the geometry, then the range of
* time is partnered with each polygon constraint. Note: By default we are
* using same compareOp for 1D Time filtering as the compareOp of the
* Spatial query by calling getBaseCompareOp()
*
* @param startTime
* @param endTime
* @param queryGeometry
* @param compareOp
*/
public SpatialTemporalQuery(
final Date startTime,
final Date endTime,
final Geometry queryGeometry,
final CompareOperation compareOp ) {
super(
createSpatialTemporalConstraints(
startTime,
endTime,
queryGeometry),
queryGeometry,
compareOp,
compareOp.getBaseCompareOp());
}
/**
* Applies the set of temporal constraints to the boundaries of the provided
* polygon. If a multi-polygon is provided, then all matching combinations
* between temporal ranges and polygons are explored.
*
* @param constraints
* @param queryGeometry
* @param compareOp
*/
public SpatialTemporalQuery(
final TemporalConstraints constraints,
final Geometry queryGeometry,
final CompareOperation compareOp ) {
super(
createSpatialTemporalConstraints(
constraints,
queryGeometry),
queryGeometry,
compareOp);
}
public static ConstraintSet createConstraints(
final TemporalRange temporalRange,
final boolean isDefault ) {
return new ConstraintSet(
TimeDefinition.class,
new ConstraintData(
new NumericRange(
temporalRange.getStartTime().getTime(),
temporalRange.getEndTime().getTime()),
isDefault));
}
public static Constraints createConstraints(
final TemporalConstraints temporalConstraints,
final boolean isDefault ) {
final List<ConstraintSet> constraints = new ArrayList<ConstraintSet>();
for (final TemporalRange range : temporalConstraints.getRanges()) {
constraints.add(new ConstraintSet(
TimeDefinition.class,
new ConstraintData(
new NumericRange(
range.getStartTime().getTime(),
range.getEndTime().getTime()),
isDefault)));
}
return new Constraints(
constraints);
}
/**
* Supports multi-polygons and multiple temporal bounds. Creates all
* matchings between polygon and temporal bounds.
*
* @param startTime
* @param endTime
* @param queryGeometry
* @return
*/
private static Constraints createSpatialTemporalConstraints(
final TemporalConstraints temporalConstraints,
final Geometry queryGeometry ) {
final Constraints geoConstraints = GeometryUtils.basicConstraintsFromGeometry(queryGeometry);
final Constraints timeConstraints = createConstraints(
temporalConstraints,
false);
return geoConstraints.merge(timeConstraints);
}
/**
* Supports multi-polygons. Applies 'temporal bounds' to each geometric
* constraint.
*
* @param startTime
* @param endTime
* @param queryGeometry
* @return
*/
private static Constraints createSpatialTemporalConstraints(
final Date startTime,
final Date endTime,
final Geometry queryGeometry ) {
final Constraints geoConstraints = GeometryUtils.basicConstraintsFromGeometry(queryGeometry);
return geoConstraints.merge(new Constraints(
new ConstraintSet(
TimeDefinition.class,
new ConstraintData(
new NumericRange(
startTime.getTime(),
endTime.getTime()),
false))));
}
}