use of org.locationtech.geowave.core.geotime.store.query.ExplicitSpatialTemporalQuery in project geowave by locationtech.
the class SpatialTemporalQueryIT method testQueryGivenDateRange.
private void testQueryGivenDateRange(final VectorQueryBuilder bldr, final String name, final Set<String> fidExpectedResults, final Date startOfQuery, final Date endOfQuery, final String adapterId, final String startTimeAttribute, final String endTimeAttribute) throws CQLException, IOException {
final String cqlPredicate = "BBOX(\"geo\",-1,-1,1,1) AND \"" + startTimeAttribute + "\" <= '" + CQL_DATE_FORMAT.format(endOfQuery) + "' AND \"" + endTimeAttribute + "\" >= '" + CQL_DATE_FORMAT.format(startOfQuery) + "'";
final Set<String> fidResults = new HashSet<>();
try (CloseableIterator<SimpleFeature> it = dataStore.query(bldr.constraints(new ExplicitSpatialTemporalQuery(startOfQuery, endOfQuery, new GeometryFactory().toGeometry(new Envelope(-1, 1, -1, 1)))).build())) {
while (it.hasNext()) {
final SimpleFeature feature = it.next();
fidResults.add(feature.getID());
}
}
assertFidsMatchExpectation(name, fidExpectedResults, fidResults);
final Set<String> geotoolsFidResults = new HashSet<>();
// now make sure geotools results match
try (final SimpleFeatureIterator features = geowaveGtDataStore.getFeatureSource(adapterId).getFeatures(ECQL.toFilter(cqlPredicate)).features()) {
while (features.hasNext()) {
final SimpleFeature feature = features.next();
geotoolsFidResults.add(feature.getID());
}
}
assertFidsMatchExpectation(name, fidExpectedResults, geotoolsFidResults);
}
use of org.locationtech.geowave.core.geotime.store.query.ExplicitSpatialTemporalQuery in project geowave by locationtech.
the class SpatialTemporalQueryIT method testTimeRangeDuplicateDeletion.
@Test
public void testTimeRangeDuplicateDeletion() throws IOException {
// create an internal data adapter wrapper for use in methods below
final short typeId = ((BaseDataStore) dataStore).getAdapterId(timeRangeAdapter.getTypeName());
// setup the vector query builder
final VectorQueryBuilder bldr = VectorQueryBuilder.newBuilder();
bldr.indexName(YEAR_INDEX.getName());
bldr.setTypeNames(new String[] { timeRangeAdapter.getTypeName() });
// Create the query over the range (1970-1974)
currentGeotoolsIndex = YEAR_INDEX;
final Calendar cal = getInitialYearCalendar();
cal.set(Calendar.YEAR, DUPLICATE_DELETION_YEAR_MIN);
Date startOfQuery = cal.getTime();
cal.set(Calendar.YEAR, DUPLICATE_DELETION_YEAR_MAX);
Date endOfQuery = cal.getTime();
final ExplicitSpatialTemporalQuery fullRangeQuery = new ExplicitSpatialTemporalQuery(startOfQuery, endOfQuery, new GeometryFactory().toGeometry(new Envelope(-1, 1, -1, 1)));
// Create query for selecting items that should still exist
// after the deletion query is performed
// (i.e. we didn't actually delete something we weren't supposed to)
cal.set(Calendar.YEAR, MULTI_YEAR_MIN);
startOfQuery = cal.getTime();
cal.set(Calendar.YEAR, MULTI_YEAR_MAX);
endOfQuery = cal.getTime();
final ExplicitSpatialTemporalQuery sanityQuery = new ExplicitSpatialTemporalQuery(startOfQuery, endOfQuery, new GeometryFactory().toGeometry(new Envelope(-1, 1, -1, 1)));
// Create deletion query to remove a single entry (1970-1971). Even
// though we are requesting to delete within a single year, this should
// remove all duplicates
cal.set(Calendar.YEAR, DUPLICATE_DELETION_YEAR_MIN);
startOfQuery = cal.getTime();
cal.set(Calendar.YEAR, DUPLICATE_DELETION_YEAR_MIN + 1);
endOfQuery = cal.getTime();
final ExplicitSpatialTemporalQuery deletionQuery = new ExplicitSpatialTemporalQuery(startOfQuery, endOfQuery, new GeometryFactory().toGeometry(new Envelope(-1, 1, -1, 1)));
// Sanity count number of entries that have nothing to do with
// the deletion query (after the deletion we will query again and see
// if count == sanity_count, we also want to make sure we don't delete
// any of the 'untouched' duplicates for the entries as well.
long sanity_count = 0;
long sanity_duplicates = 0;
DuplicateCountCallback<SimpleFeature> dupeCounter = new DuplicateCountCallback<>();
try (CloseableIterator<?> dataIt = ((BaseDataStore) dataStore).query(bldr.constraints(sanityQuery).build(), dupeCounter)) {
while (dataIt.hasNext()) {
sanity_count++;
dataIt.next();
}
dataIt.close();
}
sanity_duplicates = dupeCounter.getDuplicateCount();
// there should be four entries with duplicates 1980-1987, 1987-1995,
// 1980-1995, 1970-1974
final long numExpectedEntries = 4;
// there should be four duplicates for the range 1970-1974 (one for each
// year after 1970)
final long numExpectedDuplicates = (DUPLICATE_DELETION_YEAR_MAX - DUPLICATE_DELETION_YEAR_MIN);
final PersistentAdapterStore adapterStore = dataStoreOptions.createAdapterStore();
// check and count the number of entries with duplicates
DuplicateEntryCountValue dupeEntryCount = InternalStatisticsHelper.getDuplicateCounts(YEAR_INDEX, Collections.singletonList(typeId), adapterStore, ((BaseDataStore) dataStore).getStatisticsStore());
Assert.assertEquals(numExpectedEntries, dupeEntryCount.getValue().longValue());
// check and count the duplicates for 1970-1974
dupeCounter = new DuplicateCountCallback<>();
try (CloseableIterator<?> dataIt = ((BaseDataStore) dataStore).query(bldr.constraints(fullRangeQuery).build(), dupeCounter)) {
while (dataIt.hasNext()) {
dataIt.next();
}
dataIt.close();
}
Assert.assertEquals(numExpectedDuplicates, dupeCounter.getDuplicateCount());
// perform the delete for a single year (1970-1971)
dataStore.delete(bldr.constraints(deletionQuery).build());
// if the delete works there should be no more duplicates for this
// entry...
dupeCounter = new DuplicateCountCallback<>();
try (CloseableIterator<?> dataIt = ((BaseDataStore) dataStore).query(bldr.constraints(fullRangeQuery).build(), dupeCounter)) {
while (dataIt.hasNext()) {
dataIt.next();
}
dataIt.close();
}
Assert.assertEquals(0, dupeCounter.getDuplicateCount());
// ..and it should not count the entry as having any duplicates i.e. the
// number of entries with duplicates should match the sanity query count
// 3(1980-1987, 1987-1995, 1980-1990)
dupeEntryCount = InternalStatisticsHelper.getDuplicateCounts(YEAR_INDEX, Collections.singletonList(typeId), adapterStore, ((BaseDataStore) dataStore).getStatisticsStore());
// if delete works, it should not count the entry as having any
// duplicates and the number of entries with duplicates should match the
// sanity query count 3(1980-1987, 1987-1995, 1980-1990)
Assert.assertEquals(sanity_count, dupeEntryCount.getValue().longValue());
// finally check we didn't accidentally delete any duplicates of the
// sanity query range
dupeCounter = new DuplicateCountCallback<>();
try (CloseableIterator<?> dataIt = ((BaseDataStore) dataStore).query(bldr.constraints(sanityQuery).build(), dupeCounter)) {
while (dataIt.hasNext()) {
dataIt.next();
}
}
Assert.assertEquals(sanity_duplicates, dupeCounter.getDuplicateCount());
}
use of org.locationtech.geowave.core.geotime.store.query.ExplicitSpatialTemporalQuery in project geowave by locationtech.
the class TestUtils method featureToQuery.
public static QueryConstraints featureToQuery(final SimpleFeature savedFilter, final Pair<String, String> optimalCqlQueryGeometryAndTimeField, final String crsCode, final boolean useDuring) {
final Geometry filterGeometry = (Geometry) savedFilter.getDefaultGeometry();
final Object startObj = savedFilter.getAttribute(TEST_FILTER_START_TIME_ATTRIBUTE_NAME);
final Object endObj = savedFilter.getAttribute(TEST_FILTER_END_TIME_ATTRIBUTE_NAME);
if ((startObj != null) && (endObj != null)) {
// if we can resolve start and end times, make it a spatial temporal
// query
Date startDate = null, endDate = null;
if (startObj instanceof Calendar) {
startDate = ((Calendar) startObj).getTime();
} else if (startObj instanceof Date) {
startDate = (Date) startObj;
}
if (endObj instanceof Calendar) {
endDate = ((Calendar) endObj).getTime();
} else if (endObj instanceof Date) {
endDate = (Date) endObj;
}
if ((startDate != null) && (endDate != null)) {
if (optimalCqlQueryGeometryAndTimeField != null) {
final FilterFactory2 factory = CommonFactoryFinder.getFilterFactory2();
Filter timeConstraint;
if (useDuring) {
timeConstraint = TimeUtils.toDuringFilter(startDate.getTime(), endDate.getTime(), optimalCqlQueryGeometryAndTimeField.getRight());
} else {
timeConstraint = TimeUtils.toFilter(startDate.getTime(), endDate.getTime(), optimalCqlQueryGeometryAndTimeField.getRight(), optimalCqlQueryGeometryAndTimeField.getRight());
}
final And expression = factory.and(GeometryUtils.geometryToSpatialOperator(filterGeometry, optimalCqlQueryGeometryAndTimeField.getLeft(), GeometryUtils.getDefaultCRS()), timeConstraint);
return new OptimalCQLQuery(expression);
}
return new SpatialTemporalQuery(new ExplicitSpatialTemporalQuery(startDate, endDate, filterGeometry, crsCode));
}
}
if (optimalCqlQueryGeometryAndTimeField != null) {
return new OptimalCQLQuery(GeometryUtils.geometryToSpatialOperator(filterGeometry, optimalCqlQueryGeometryAndTimeField.getLeft(), GeometryUtils.getDefaultCRS()));
}
// otherwise just return a spatial query
return new SpatialQuery(new ExplicitSpatialQuery(filterGeometry, crsCode));
}
Aggregations