use of mil.nga.geopackage.features.user.FeatureResultSet in project joa by sebastianfrey.
the class GeoPackageService method getItems.
/**
* Return all items of a collection from a given service.
*
* @param serviceId
* @param collectionId
* @return
*/
@Override
public GeoPackageItems getItems(String serviceId, String collectionId, FeatureQuery query) throws Exception {
GeoPackageItems items = new GeoPackageItems().serviceId(serviceId).collectionId(collectionId).queryString(query.getQueryString()).offset(query.getOffset()).limit(query.getLimit());
try (GeoPackage gpkg = loadService(serviceId)) {
FeatureDao featureDao = loadCollection(gpkg, collectionId);
GeoPackageQueryResult result = new GeoPackageQuery(featureDao, query).execute();
String geometryType = null;
switch(featureDao.getGeometryType()) {
case POINT:
geometryType = "Point";
break;
case LINESTRING:
geometryType = "LineString";
break;
case POLYGON:
geometryType = "Polygon";
break;
case MULTIPOINT:
geometryType = "MultiPoint";
break;
case MULTILINESTRING:
geometryType = "MultiLineString";
break;
case MULTIPOLYGON:
geometryType = "MultiPolygon";
break;
default:
break;
}
items.numberMatched(result.getCount()).geometryType(geometryType).idColumn(featureDao.getIdColumnName());
GeometryEnvelope bbox = null;
FeatureResultSet featureResultSet = result.getFeatureResultSet();
try {
while (featureResultSet.moveToNext()) {
FeatureRow featureRow = featureResultSet.getRow();
Feature feature = createFeature(featureRow);
if (feature != null) {
items.feature(feature);
}
GeometryEnvelope envelope = createEnvelope(featureRow);
if (envelope != null) {
if (bbox == null) {
bbox = envelope.copy();
} else {
bbox = bbox.union(envelope);
}
}
}
} finally {
featureResultSet.close();
}
if (bbox != null) {
if (bbox.is3D()) {
items.bbox(List.of(bbox.getMinX(), bbox.getMinY(), bbox.getMinZ(), bbox.getMaxX(), bbox.getMaxY(), bbox.getMaxZ()));
} else {
items.bbox(List.of(bbox.getMinX(), bbox.getMinY(), bbox.getMaxX(), bbox.getMaxY()));
}
}
}
return items;
}
use of mil.nga.geopackage.features.user.FeatureResultSet in project joa by sebastianfrey.
the class GeoPackageService method getItem.
/**
* Return a specific item by its id from a given service.
*
* @param serviceId
* @param collectionId
* @return
*/
@Override
public GeoPackageItem getItem(String serviceId, String collectionId, Long featureId) {
try (GeoPackage gpkg = loadService(serviceId)) {
FeatureDao featureDao = loadCollection(gpkg, collectionId);
FeatureResultSet featureResultSet = featureDao.queryForId(featureId);
try {
while (featureResultSet.moveToNext()) {
FeatureRow featureRow = featureResultSet.getRow();
Feature feature = createFeature(featureRow);
return new GeoPackageItem().serviceId(serviceId).collectionId(collectionId).feature(feature);
}
} finally {
featureResultSet.close();
}
}
throw new NotFoundException("Feature with ID '" + featureId + "' does not exist.");
}
use of mil.nga.geopackage.features.user.FeatureResultSet in project geopackage-java by ngageoint.
the class FeatureIndexManager method queryForChunk.
/**
* Query for feature index results, starting at the offset and returning no
* more than the limit
*
* @param distinct
* distinct rows
* @param columns
* columns
* @param where
* where clause
* @param whereArgs
* where arguments
* @param orderBy
* order by
* @param limit
* chunk limit
* @param offset
* chunk query offset
*
* @return feature index results, close when done
* @since 6.2.0
*/
public FeatureIndexResults queryForChunk(boolean distinct, String[] columns, String where, String[] whereArgs, String orderBy, int limit, long offset) {
FeatureIndexResults results = null;
for (FeatureIndexType type : getLocation()) {
try {
switch(type) {
case GEOPACKAGE:
FeatureResultSet geoPackageResultSet = featureTableIndex.queryFeaturesForChunk(distinct, columns, where, whereArgs, orderBy, limit, offset);
results = new FeatureIndexFeatureResults(geoPackageResultSet);
break;
case RTREE:
FeatureResultSet rTreeResultSet = rTreeIndexTableDao.queryFeaturesForChunk(distinct, columns, where, whereArgs, orderBy, limit, offset);
results = new FeatureIndexFeatureResults(rTreeResultSet);
break;
default:
throw new GeoPackageException("Unsupported feature index type: " + type);
}
break;
} catch (Exception e) {
if (continueOnError) {
LOGGER.log(Level.SEVERE, "Failed to query from feature index: " + type, e);
} else {
throw e;
}
}
}
if (results == null) {
FeatureResultSet featureResultSet = manualFeatureQuery.queryForChunk(distinct, columns, where, whereArgs, orderBy, limit, offset);
results = new FeatureIndexFeatureResults(featureResultSet);
}
return results;
}
use of mil.nga.geopackage.features.user.FeatureResultSet in project geopackage-java by ngageoint.
the class FeatureIndexManager method query.
/**
* Query for feature index results within the Geometry Envelope
*
* @param distinct
* distinct rows
* @param columns
* columns
* @param envelope
* geometry envelope
* @param where
* where clause
* @param whereArgs
* where arguments
* @return feature index results, close when done
* @since 4.0.0
*/
public FeatureIndexResults query(boolean distinct, String[] columns, GeometryEnvelope envelope, String where, String[] whereArgs) {
FeatureIndexResults results = null;
for (FeatureIndexType type : getLocation()) {
try {
switch(type) {
case GEOPACKAGE:
FeatureResultSet geoPackageResultSet = featureTableIndex.queryFeatures(distinct, columns, envelope, where, whereArgs);
results = new FeatureIndexFeatureResults(geoPackageResultSet);
break;
case RTREE:
FeatureResultSet rTreeResultSet = rTreeIndexTableDao.queryFeatures(distinct, columns, envelope, where, whereArgs);
results = new FeatureIndexFeatureResults(rTreeResultSet);
break;
default:
throw new GeoPackageException("Unsupported feature index type: " + type);
}
break;
} catch (Exception e) {
if (continueOnError) {
LOGGER.log(Level.SEVERE, "Failed to query from feature index: " + type, e);
} else {
throw e;
}
}
}
if (results == null) {
results = manualFeatureQuery.query(distinct, columns, envelope, where, whereArgs);
}
return results;
}
use of mil.nga.geopackage.features.user.FeatureResultSet in project geopackage-java by ngageoint.
the class FeatureIndexManagerUtils method testIndex.
private static void testIndex(GeoPackage geoPackage, FeatureIndexType type, boolean includeEmpty) throws SQLException {
// Test indexing each feature table
List<String> featureTables = geoPackage.getFeatureTables();
for (String featureTable : featureTables) {
FeatureDao featureDao = geoPackage.getFeatureDao(featureTable);
FeatureIndexManager featureIndexManager = new FeatureIndexManager(geoPackage, featureDao);
featureIndexManager.setContinueOnError(false);
featureIndexManager.setIndexLocation(type);
featureIndexManager.deleteAllIndexes();
// Determine how many features have geometry envelopes or geometries
int expectedCount = 0;
FeatureRow testFeatureRow = null;
FeatureResultSet featureResultSet = featureDao.query();
while (featureResultSet.moveToNext()) {
FeatureRow featureRow = featureResultSet.getRow();
if (featureRow.getGeometryEnvelope() != null) {
expectedCount++;
// queries later
if (testFeatureRow == null) {
testFeatureRow = featureRow;
} else if (Math.random() < (1.0 / featureResultSet.getCount())) {
testFeatureRow = featureRow;
}
} else if (includeEmpty) {
expectedCount++;
}
}
featureResultSet.close();
TestCase.assertFalse(featureIndexManager.isIndexed());
TestCase.assertNull(featureIndexManager.getLastIndexed());
Date currentDate = new Date();
// Test indexing
TestGeoPackageProgress progress = new TestGeoPackageProgress();
featureIndexManager.setProgress(progress);
int indexCount = featureIndexManager.index();
TestCase.assertEquals(expectedCount, indexCount);
TestCase.assertEquals(featureDao.count(), progress.getProgress());
TestCase.assertNotNull(featureIndexManager.getLastIndexed());
Date lastIndexed = featureIndexManager.getLastIndexed();
TestCase.assertTrue(lastIndexed.getTime() > currentDate.getTime());
TestCase.assertTrue(featureIndexManager.isIndexed());
TestCase.assertEquals(expectedCount, featureIndexManager.count());
// Test re-indexing, both ignored and forced
TestCase.assertEquals(0, featureIndexManager.index());
TestCase.assertEquals(expectedCount, featureIndexManager.index(true));
TestCase.assertTrue(featureIndexManager.getLastIndexed().getTime() > lastIndexed.getTime());
// Query for all indexed geometries
int resultCount = 0;
FeatureIndexResults featureIndexResults = featureIndexManager.query();
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, null, includeEmpty);
resultCount++;
}
featureIndexResults.close();
TestCase.assertEquals(expectedCount, resultCount);
// Query for all indexed geometries with columns
resultCount = 0;
featureIndexResults = featureIndexManager.query(featureDao.getIdAndGeometryColumnNames());
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, null, includeEmpty);
resultCount++;
}
featureIndexResults.close();
TestCase.assertEquals(expectedCount, resultCount);
// Test the query by envelope
GeometryEnvelope envelope = testFeatureRow.getGeometryEnvelope();
final double difference = .000001;
envelope.setMinX(envelope.getMinX() - difference);
envelope.setMaxX(envelope.getMaxX() + difference);
envelope.setMinY(envelope.getMinY() - difference);
envelope.setMaxY(envelope.getMaxY() + difference);
if (envelope.hasZ()) {
envelope.setMinZ(envelope.getMinZ() - difference);
envelope.setMaxZ(envelope.getMaxZ() + difference);
}
if (envelope.hasM()) {
envelope.setMinM(envelope.getMinM() - difference);
envelope.setMaxM(envelope.getMaxM() + difference);
}
resultCount = 0;
boolean featureFound = false;
TestCase.assertTrue(featureIndexManager.count(envelope) >= 1);
featureIndexResults = featureIndexManager.query(envelope);
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, envelope, includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
resultCount = 0;
featureFound = false;
featureIndexResults = featureIndexManager.query(featureDao.getIdAndGeometryColumnNames(), envelope);
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, envelope, includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
// Test the query by envelope with id iteration
resultCount = 0;
featureFound = false;
TestCase.assertTrue(featureIndexManager.count(envelope) >= 1);
featureIndexResults = featureIndexManager.query(envelope);
for (long featureRowId : featureIndexResults.ids()) {
FeatureRow featureRow = featureDao.queryForIdRow(featureRowId);
validateFeatureRow(featureIndexManager, featureRow, envelope, includeEmpty);
if (featureRowId == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
// Pick a projection different from the feature dao and project the
// bounding box
BoundingBox boundingBox = new BoundingBox(envelope.getMinX() - 1, envelope.getMinY() - 1, envelope.getMaxX() + 1, envelope.getMaxY() + 1);
Projection projection = null;
if (!featureDao.getProjection().equals(ProjectionConstants.AUTHORITY_EPSG, ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM)) {
projection = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
} else {
projection = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WEB_MERCATOR);
}
GeometryTransform transform = GeometryTransform.create(featureDao.getProjection(), projection);
BoundingBox transformedBoundingBox = boundingBox.transform(transform);
// Test the query by projected bounding box
resultCount = 0;
featureFound = false;
TestCase.assertTrue(featureIndexManager.count(transformedBoundingBox, projection) >= 1);
featureIndexResults = featureIndexManager.query(transformedBoundingBox, projection);
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
resultCount = 0;
featureFound = false;
featureIndexResults = featureIndexManager.query(featureDao.getIdAndGeometryColumnNames(), transformedBoundingBox, projection);
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
// Test query by criteria
FeatureTable table = featureDao.getTable();
List<FeatureColumn> columns = table.getColumns();
Map<String, Number> numbers = new HashMap<>();
Map<String, String> strings = new HashMap<>();
for (FeatureColumn column : columns) {
if (column.isPrimaryKey() || column.isGeometry()) {
continue;
}
GeoPackageDataType dataType = column.getDataType();
switch(dataType) {
case DOUBLE:
case FLOAT:
case INT:
case INTEGER:
case TINYINT:
case SMALLINT:
case MEDIUMINT:
case REAL:
numbers.put(column.getName(), null);
break;
case TEXT:
strings.put(column.getName(), null);
break;
default:
}
}
for (String number : numbers.keySet()) {
Object value = testFeatureRow.getValue(number);
numbers.put(number, (Number) value);
}
for (String string : strings.keySet()) {
String value = testFeatureRow.getValueString(string);
strings.put(string, value);
}
for (Entry<String, Number> number : numbers.entrySet()) {
String column = number.getKey();
double value = number.getValue().doubleValue();
String where = column + " >= ? AND " + column + " <= ?";
String[] whereArgs = new String[] { String.valueOf(value - 0.001), String.valueOf(value + 0.001) };
long count = featureIndexManager.count(where, whereArgs);
TestCase.assertTrue(count >= 1);
featureIndexResults = featureIndexManager.query(where, whereArgs);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, ((Number) featureRow.getValue(column)).doubleValue());
}
featureIndexResults.close();
featureIndexResults = featureIndexManager.query(new String[] { column }, where, whereArgs);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, ((Number) featureRow.getValue(column)).doubleValue());
}
featureIndexResults.close();
resultCount = 0;
featureFound = false;
count = featureIndexManager.count(transformedBoundingBox, projection, where, whereArgs);
TestCase.assertTrue(count >= 1);
featureIndexResults = featureIndexManager.query(transformedBoundingBox, projection, where, whereArgs);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, ((Number) featureRow.getValue(column)).doubleValue());
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
resultCount = 0;
featureFound = false;
featureIndexResults = featureIndexManager.query(new String[] { featureDao.getGeometryColumnName(), column, featureDao.getIdColumnName() }, transformedBoundingBox, projection, where, whereArgs);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, ((Number) featureRow.getValue(column)).doubleValue());
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
}
for (Entry<String, String> string : strings.entrySet()) {
String column = string.getKey();
String value = string.getValue();
Map<String, Object> fieldValues = new HashMap<>();
fieldValues.put(column, value);
long count = featureIndexManager.count(fieldValues);
TestCase.assertTrue(count >= 1);
featureIndexResults = featureIndexManager.query(fieldValues);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, featureRow.getValueString(column));
}
featureIndexResults.close();
featureIndexResults = featureIndexManager.query(new String[] { column }, fieldValues);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, featureRow.getValueString(column));
}
featureIndexResults.close();
resultCount = 0;
featureFound = false;
count = featureIndexManager.count(transformedBoundingBox, projection, fieldValues);
TestCase.assertTrue(count >= 1);
featureIndexResults = featureIndexManager.query(transformedBoundingBox, projection, fieldValues);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, featureRow.getValueString(column));
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
resultCount = 0;
featureFound = false;
featureIndexResults = featureIndexManager.query(new String[] { column, featureDao.getIdColumnName(), featureDao.getGeometryColumnName() }, transformedBoundingBox, projection, fieldValues);
TestCase.assertEquals(count, featureIndexResults.count());
for (FeatureRow featureRow : featureIndexResults) {
TestCase.assertEquals(value, featureRow.getValueString(column));
validateFeatureRow(featureIndexManager, featureRow, boundingBox.buildEnvelope(), includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
}
// Update a Geometry and update the index of a single feature row
Point point = new Point(5, 5);
GeoPackageGeometryData geometryData = GeoPackageGeometryData.create(featureDao.getSrsId(), point);
testFeatureRow.setGeometry(geometryData);
TestCase.assertEquals(1, featureDao.update(testFeatureRow));
Date lastIndexedBefore = featureIndexManager.getLastIndexed();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
TestCase.assertTrue(featureIndexManager.index(testFeatureRow));
Date lastIndexedAfter = featureIndexManager.getLastIndexed();
TestCase.assertTrue(lastIndexedAfter.after(lastIndexedBefore));
// Verify the index was updated for the feature row
envelope = point.getEnvelope();
resultCount = 0;
featureFound = false;
TestCase.assertTrue(featureIndexManager.count(envelope) >= 1);
featureIndexResults = featureIndexManager.query(envelope);
for (FeatureRow featureRow : featureIndexResults) {
validateFeatureRow(featureIndexManager, featureRow, envelope, includeEmpty);
if (featureRow.getId() == testFeatureRow.getId()) {
featureFound = true;
}
resultCount++;
}
featureIndexResults.close();
TestCase.assertTrue(featureFound);
TestCase.assertTrue(resultCount >= 1);
featureIndexManager.close();
}
// Delete the extensions
boolean everyOther = false;
for (String featureTable : featureTables) {
FeatureDao featureDao = geoPackage.getFeatureDao(featureTable);
FeatureIndexManager featureIndexManager = new FeatureIndexManager(geoPackage, featureDao);
featureIndexManager.setIndexLocation(type);
TestCase.assertTrue(featureIndexManager.isIndexed());
// Test deleting a single geometry index
if (everyOther) {
FeatureResultSet featureResultSet = featureDao.query();
while (featureResultSet.moveToNext()) {
FeatureRow featureRow = featureResultSet.getRow();
if (featureRow.getGeometryEnvelope() != null) {
featureResultSet.close();
TestCase.assertTrue(featureIndexManager.deleteIndex(featureRow));
break;
}
}
featureResultSet.close();
}
featureIndexManager.deleteIndex();
TestCase.assertFalse(featureIndexManager.isIndexed());
everyOther = !everyOther;
featureIndexManager.close();
}
}
Aggregations