Skip to content

Commit

Permalink
SQLite Exec R-tree support
Browse files Browse the repository at this point in the history
  • Loading branch information
bosborn committed Mar 8, 2024
1 parent 135c5ba commit d7e245f
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Adheres to [Semantic Versioning](http://semver.org/).
* Set User Custom DAO contents
* Feature Tiles geodesic draw support
* Feature Index Manager, RTree Index, Feature Table Index, and Manual query geodesic support
* SQLite Exec R-tree support

## [6.6.4](https://github.com/ngageoint/geopackage-java/releases/tag/6.6.4) (11-29-2023)

Expand Down
3 changes: 3 additions & 0 deletions script/sqlite-exec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ Commands:
projection - desired projection as 'authority:code' or 'epsg_code'
m - manually query unindexed tables
extensions [name] - List GeoPackage extensions (all or LIKE table name)
rtree [-d] <name>
- Create, recreate, or drop a feature table R-tree
d - drop the R-tree if it exists
geometry <name> [-p projection] [ids]
- Display feature table geometries as Well-Known Text
projection - desired display projection as 'authority:code' or 'epsg_code'
Expand Down
141 changes: 134 additions & 7 deletions src/main/java/mil/nga/geopackage/io/SQLExec.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import mil.nga.geopackage.dgiwg.GeoPackageFileName;
import mil.nga.geopackage.extension.coverage.CoverageData;
import mil.nga.geopackage.extension.rtree.RTreeIndexExtension;
import mil.nga.geopackage.extension.rtree.RTreeIndexTableDao;
import mil.nga.geopackage.features.columns.GeometryColumns;
import mil.nga.geopackage.features.user.FeatureDao;
import mil.nga.geopackage.features.user.FeatureRow;
Expand Down Expand Up @@ -240,6 +241,11 @@ public class SQLExec {
*/
public static final String COMMAND_EXTENSIONS = "extensions";

/**
* GeoPackage R-tree command
*/
public static final String COMMAND_RTREE = "rtree";

/**
* GeoPackage geometry command
*/
Expand Down Expand Up @@ -318,7 +324,12 @@ public class SQLExec {
/**
* Bounds manual argument
*/
public static final String BOUNDS_ARGUMENT_MANUAL = "m";
public static final String ARGUMENT_BOUNDS_MANUAL = "m";

/**
* R-tree drop argument
*/
public static final String ARGUMENT_RTREE_DROP = "d";

/**
* Blobs column pattern
Expand Down Expand Up @@ -858,6 +869,13 @@ private static void commandPrompt(GeoPackage database, Integer maxRows,
COMMAND_ALL_ROWS, maxColumnWidth,
maxLinesPerRow, history);

} else if (sqlLineLower.startsWith(COMMAND_RTREE)) {

rtree(database, sqlBuilder, history,
sqlLine.substring(
COMMAND_RTREE.length(),
sqlLine.length()));

} else if (sqlLineLower
.startsWith(COMMAND_GEOMETRY)) {

Expand Down Expand Up @@ -1185,26 +1203,32 @@ private static void printHelp(GeoPackage database) {
"\t projection - desired projection as 'authority:code' or 'epsg_code'");
System.out.println("\t" + COMMAND_BOUNDS + " [" + ARGUMENT_PREFIX
+ ARGUMENT_PROJECTION + " projection] [" + ARGUMENT_PREFIX
+ BOUNDS_ARGUMENT_MANUAL + "] [name]");
+ ARGUMENT_BOUNDS_MANUAL + "] [name]");
System.out.println(
"\t - Determine the bounds of the entire GeoPackage or single table name");
System.out.println(
"\t projection - desired projection as 'authority:code' or 'epsg_code'");
System.out.println("\t "
+ BOUNDS_ARGUMENT_MANUAL
+ ARGUMENT_BOUNDS_MANUAL
+ " - manually query unindexed tables");
System.out.println("\t" + COMMAND_TABLE_BOUNDS + " ["
+ ARGUMENT_PREFIX + ARGUMENT_PROJECTION + " projection] ["
+ ARGUMENT_PREFIX + BOUNDS_ARGUMENT_MANUAL + "] [name]");
+ ARGUMENT_PREFIX + ARGUMENT_BOUNDS_MANUAL + "] [name]");
System.out.println(
"\t - Determine the bounds (using only table metadata) of the entire GeoPackage or single table name");
System.out.println(
"\t projection - desired projection as 'authority:code' or 'epsg_code'");
System.out.println("\t "
+ BOUNDS_ARGUMENT_MANUAL
+ ARGUMENT_BOUNDS_MANUAL
+ " - manually query unindexed tables");
System.out.println("\t" + COMMAND_EXTENSIONS
+ " [name] - List GeoPackage extensions (all or LIKE table name)");
System.out.println("\t" + COMMAND_RTREE + " [" + ARGUMENT_PREFIX
+ ARGUMENT_RTREE_DROP + "] <name>");
System.out.println(
"\t - Create, recreate, or drop a feature table R-tree");
System.out.println("\t " + ARGUMENT_RTREE_DROP
+ " - drop the R-tree if it exists");
System.out.println(
"\t" + COMMAND_GEOMETRY + " <name> [-p projection] [ids]");
System.out.println(
Expand Down Expand Up @@ -2195,6 +2219,7 @@ private static void geoPackageTableInfo(GeoPackage database,
+ tableName + "';",
COMMAND_ALL_ROWS, maxColumnWidth, maxLinesPerRow,
history, false);
rtreeInfo(database, tableName);
break;
case TILES:
executeSQL(database, sqlBuilder,
Expand Down Expand Up @@ -2300,6 +2325,20 @@ private static void tableInfo(GeoPackage database, StringBuilder sqlBuilder,

}

/**
* Print feature R-tree info for a single table
*
* @param database
* database
* @param tableName
* table name
*/
private static void rtreeInfo(GeoPackage database, String tableName) {
RTreeIndexExtension extension = new RTreeIndexExtension(database);
System.out.println();
System.out.println("R-tree indexed: " + extension.has(tableName));
}

/**
* Print tile matrix info for a single table
*
Expand Down Expand Up @@ -2348,6 +2387,94 @@ private static void tileMatrix(GeoPackage database,
history, false, true);
}

/**
* R-tree create and drop
*
* @param database
* database
* @param sqlBuilder
* SQL builder
* @param history
* history
* @param args
* write blob arguments
* @throws SQLException
* upon error
* @throws IOException
* upon error
*/
private static void rtree(GeoPackage database, StringBuilder sqlBuilder,
List<String> history, String args)
throws SQLException, IOException {

String[] parts = args.trim().split("\\s+");

boolean valid = true;
String tableName = null;
boolean drop = false;

for (int i = 0; valid && i < parts.length; i++) {

String arg = parts[i];

if (arg.startsWith(ARGUMENT_PREFIX)) {

String argument = arg.substring(ARGUMENT_PREFIX.length());

switch (argument) {

case ARGUMENT_RTREE_DROP:
drop = true;
break;

default:
valid = false;
System.out.println("Error: Unsupported arg: '" + arg + "'");
}

} else {
if (tableName == null) {
tableName = arg;
if (!database.isFeatureTable(tableName)) {
valid = false;
if (tableName.isEmpty()) {
System.out.println("Error: Feature table required");
} else {
System.out.println("Error: '" + tableName
+ "' is not a feature table");
}
}
} else {
valid = false;
System.out.println("Error: Unexpected additional argument '"
+ arg + "' for R-tree");
}
}
}

if (valid) {
RTreeIndexExtension extension = new RTreeIndexExtension(database);
RTreeIndexTableDao dao = extension.getTableDao(tableName);
boolean exists = dao.has();
System.out.println();
if (exists) {
dao.delete();
System.out.println(
"R-tree dropped for table '" + tableName + "'");
}
if (!drop) {
dao.create();
System.out.println(
"R-tree created for table '" + tableName + "'");
} else if (!exists) {
System.out.println("No R-tree exists to drop for table '"
+ tableName + "'");
}
}

resetCommandPrompt(sqlBuilder);
}

/**
* Print or update geometries
*
Expand Down Expand Up @@ -2669,7 +2796,7 @@ private static void reproject(GeoPackage database, StringBuilder sqlBuilder,
} else {
valid = false;
System.out.println("Error: Unexpected additional argument '"
+ arg + "' for multiple id query");
+ arg + "' for reprojection");
}
}
}
Expand Down Expand Up @@ -2867,7 +2994,7 @@ private static void bounds(GeoPackage database, StringBuilder sqlBuilder,
}
break;

case BOUNDS_ARGUMENT_MANUAL:
case ARGUMENT_BOUNDS_MANUAL:
if (type == BoundsType.CONTENTS) {
valid = false;
System.out.println(
Expand Down

0 comments on commit d7e245f

Please sign in to comment.