geopackage-sdk/src/main/java/mil/nga/geopackage/db/metadata/GeometryMetadataDataSource.java
public Cursor query(long geoPackageId, String tableName, GeometryEnvelope envelope) {
        StringBuilder selection = new StringBuilder();
        selection.append(GeometryMetadata.COLUMN_GEOPACKAGE_ID).append(" = ? AND ")
                .append(GeometryMetadata.COLUMN_TABLE_NAME).append(" = ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_X).append(" <= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_X).append(" >= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_Y).append(" <= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_Y).append(" >= ?");
        int args = 6;
        if (envelope.hasZ()) {
            args += 2;
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_Z).append(" <= ?");
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_Z).append(" >= ?");
        }
        if (envelope.hasM()) {
            args += 2;
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_M).append(" <= ?");
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_M).append(" >= ?");
        }

        double minX = envelope.getMinX() - tolerance;
        double maxX = envelope.getMaxX() + tolerance;
        double minY = envelope.getMinY() - tolerance;
        double maxY = envelope.getMaxY() + tolerance;

        String[] selectionArgs = new String[args];
        int argCount = 0;
        selectionArgs[argCount++] = String.valueOf(geoPackageId);
        selectionArgs[argCount++] = tableName;
        selectionArgs[argCount++] = String.valueOf(maxX);
        selectionArgs[argCount++] = String.valueOf(minX);
        selectionArgs[argCount++] = String.valueOf(maxY);
        selectionArgs[argCount++] = String.valueOf(minY);
        if (envelope.hasZ()) {
            double minZ = envelope.getMinZ() - tolerance;
            double maxZ = envelope.getMaxZ() + tolerance;
            selectionArgs[argCount++] = String.valueOf(maxZ);
            selectionArgs[argCount++] = String.valueOf(minZ);
        }
        if (envelope.hasM()) {
            double minM = envelope.getMinM() - tolerance;
            double maxM = envelope.getMaxM() + tolerance;
            selectionArgs[argCount++] = String.valueOf(maxM);
            selectionArgs[argCount++] = String.valueOf(minM);
        }
        Cursor cursor = db.query(
                GeometryMetadata.TABLE_NAME,
                GeometryMetadata.COLUMNS, selection.toString(), selectionArgs, null, null, null);
        return cursor;
    }
public Cursor query(long geoPackageId, String tableName, GeometryEnvelope envelope) {
        StringBuilder selection = new StringBuilder();
        selection.append(GeometryMetadata.COLUMN_GEOPACKAGE_ID).append(" = ? AND ")
                .append(GeometryMetadata.COLUMN_TABLE_NAME).append(" = ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_X).append(" <= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_X).append(" >= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_Y).append(" <= ?");
        selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_Y).append(" >= ?");
        int args = 6;
        if (envelope.hasZ()) {
            args += 2;
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_Z).append(" <= ?");
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_Z).append(" >= ?");
        }
        if (envelope.hasM()) {
            args += 2;
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MIN_M).append(" <= ?");
            selection.append(" AND ").append(GeometryMetadata.COLUMN_MAX_M).append(" >= ?");
        }

        double minX = envelope.getMinX() - tolerance;
        double maxX = envelope.getMaxX() + tolerance;
        double minY = envelope.getMinY() - tolerance;
        double maxY = envelope.getMaxY() + tolerance;

        String[] selectionArgs = new String[args];
        int argCount = 0;
        selectionArgs[argCount++] = String.valueOf(geoPackageId);
        selectionArgs[argCount++] = tableName;
        selectionArgs[argCount++] = String.valueOf(maxX);
        selectionArgs[argCount++] = String.valueOf(minX);
        selectionArgs[argCount++] = String.valueOf(maxY);
        selectionArgs[argCount++] = String.valueOf(minY);
        if (envelope.hasZ()) {
            double minZ = envelope.getMinZ() - tolerance;
            double maxZ = envelope.getMaxZ() + tolerance;
            selectionArgs[argCount++] = String.valueOf(maxZ);
            selectionArgs[argCount++] = String.valueOf(minZ);
        }
        if (envelope.hasM()) {
            double minM = envelope.getMinM() - tolerance;
            double maxM = envelope.getMaxM() + tolerance;
            selectionArgs[argCount++] = String.valueOf(maxM);
            selectionArgs[argCount++] = String.valueOf(minM);
        }
        Cursor cursor = db.query(
                GeometryMetadata.TABLE_NAME,
                GeometryMetadata.COLUMNS, selection.toString(), selectionArgs, null, null, null);
        return cursor;
    }
Query for all table geometry metadata matching the envelope

@param geoPackageId GeoPackage id
@param tableName    table name
@param envelope     geometry envelope
@return cursor that must be closed