From db48ac149fc62da6cf52d013a00f375c37a2198d Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Tue, 18 Nov 2025 11:37:06 -0500 Subject: [PATCH 1/9] Add logging ot geopackage read --- src/NGen.cpp | 10 ++++++---- src/geopackage/ngen_sqlite.cpp | 1 + src/geopackage/read.cpp | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/NGen.cpp b/src/NGen.cpp index 1333733031..c2f9045851 100644 --- a/src/NGen.cpp +++ b/src/NGen.cpp @@ -467,9 +467,10 @@ int main(int argc, char* argv[]) { #if NGEN_WITH_SQLITE3 try { nexus_collection = ngen::geopackage::read(nexusDataFile, "nexus", nexus_subset_ids); - } catch (...) { + } catch (const std::exception &e) { // Handle all exceptions - std::string msg = "Geopackage error occurred reading nexuses: " + nexusDataFile; + std::string msg = "Geopackage error occurred reading nexuses: " + nexusDataFile + + "\nError: " + e.what(); LOG(msg,LogLevel::FATAL); throw std::runtime_error(msg); } @@ -498,9 +499,10 @@ int main(int argc, char* argv[]) { try { catchment_collection = ngen::geopackage::read(catchmentDataFile, "divides", catchment_subset_ids); - } catch (...) { + } catch (const std::exception &e) { // Handle all exceptions - std::string msg = "Geopackage error occurred reading divides: " + catchmentDataFile; + std::string msg = "Geopackage error occurred reading divides: " + catchmentDataFile + + "\nError: " + e.what(); LOG(msg,LogLevel::FATAL); throw std::runtime_error(msg); } diff --git a/src/geopackage/ngen_sqlite.cpp b/src/geopackage/ngen_sqlite.cpp index 0bf28bb608..1e829c4ca7 100644 --- a/src/geopackage/ngen_sqlite.cpp +++ b/src/geopackage/ngen_sqlite.cpp @@ -211,6 +211,7 @@ auto database::query( const boost::span binds ) -> iterator { + LOG(LogLevel::INFO, "Raw query statement: " + statement); sqlite3_stmt* stmt = nullptr; const int code = sqlite3_prepare_v2( connection(), diff --git a/src/geopackage/read.cpp b/src/geopackage/read.cpp index 5cb5d9626c..f4795a2750 100644 --- a/src/geopackage/read.cpp +++ b/src/geopackage/read.cpp @@ -27,9 +27,11 @@ std::shared_ptr ngen::geopackage::read( // Check for malicious/invalid layer input check_table_name(layer); + LOG(LogLevel::INFO, "Creating gpkg connection"); ngen::sqlite::database db{gpkg_path}; // Check if layer exists + LOG(LogLevel::INFO, "Checking if layer exists."); if (!db.contains(layer)) { // Since the layer doesn't exist, we need to output some additional // debug information with the error. In this case, we add ALL the tables @@ -75,6 +77,7 @@ std::shared_ptr ngen::geopackage::read( // the IDs together. std::string joined_ids = ""; if (!ids.empty()) { + LOG(LogLevel::INFO, "Joining %d IDs", (int)ids.size()); joined_ids = " WHERE "+id_column+" IN (?"; for (size_t i = 1; i < ids.size(); i++) { joined_ids += ", ?"; @@ -83,6 +86,7 @@ std::shared_ptr ngen::geopackage::read( } // Get number of features + LOG(LogLevel::INFO, "Querying count"); auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, ids); query_get_layer_count.next(); const int layer_feature_count = query_get_layer_count.get(0); @@ -102,15 +106,18 @@ std::shared_ptr ngen::geopackage::read( #endif // Get layer feature metadata (geometry column name + type) + LOG(LogLevel::INFO, "Querying geom column"); auto query_get_layer_geom_meta = db.query("SELECT column_name FROM gpkg_geometry_columns WHERE table_name = ?", layer); query_get_layer_geom_meta.next(); const std::string layer_geometry_column = query_get_layer_geom_meta.get(0); // Get layer + LOG(LogLevel::INFO, "Getting layer reference"); auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, ids); query_get_layer.next(); // build features out of layer query + LOG(LogLevel::INFO, "Building features list"); std::vector features; features.reserve(layer_feature_count); while(!query_get_layer.done()) { @@ -123,6 +130,7 @@ std::shared_ptr ngen::geopackage::read( features.push_back(feature); query_get_layer.next(); } + LOG(LogLevel::INFO, "Done with sql stuff"); // get layer bounding box from features // From 4e62fd902aeb6729c6ad7004f33dbf1df32a599c Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Tue, 18 Nov 2025 11:39:10 -0500 Subject: [PATCH 2/9] Report number of found binds --- src/geopackage/ngen_sqlite.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/geopackage/ngen_sqlite.cpp b/src/geopackage/ngen_sqlite.cpp index 1e829c4ca7..77402988d0 100644 --- a/src/geopackage/ngen_sqlite.cpp +++ b/src/geopackage/ngen_sqlite.cpp @@ -226,6 +226,7 @@ auto database::query( } if (!binds.empty()) { + LOG(LogLevel::INFO, "Number of binds identified: %d", (int)binds.size()); for (int i = 0; i < binds.size(); i++) { const int bind_code = sqlite3_bind_text(stmt, i + 1, binds[i].c_str(), -1, SQLITE_TRANSIENT); if (bind_code != SQLITE_OK) { From f282a3f2b64d65a6e790c1ae548dee09259b0b2a Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Tue, 18 Nov 2025 11:44:14 -0500 Subject: [PATCH 3/9] Show expanded query --- src/geopackage/ngen_sqlite.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/geopackage/ngen_sqlite.cpp b/src/geopackage/ngen_sqlite.cpp index 77402988d0..20afdb6533 100644 --- a/src/geopackage/ngen_sqlite.cpp +++ b/src/geopackage/ngen_sqlite.cpp @@ -226,13 +226,14 @@ auto database::query( } if (!binds.empty()) { - LOG(LogLevel::INFO, "Number of binds identified: %d", (int)binds.size()); for (int i = 0; i < binds.size(); i++) { const int bind_code = sqlite3_bind_text(stmt, i + 1, binds[i].c_str(), -1, SQLITE_TRANSIENT); if (bind_code != SQLITE_OK) { throw sqlite_error{"sqlite3_bind_text", code}; } } + const char *expanded = sqlite3_expanded_sql(stmt); + LOG(LogLevel::INFO, "Final query statement after binds: " + statement); } return iterator{stmt_t{stmt}}; From d096f883c6375631a6fae6bf2f2eab5b567baf8c Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 19 Nov 2025 10:35:57 -0500 Subject: [PATCH 4/9] forcing form local --- Dockerfile | 4 ++-- src/geopackage/ngen_sqlite.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d0a43acffe..566765bc3e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,10 @@ # Stage: Base – Common Setup ############################## ARG NGEN_FORCING_IMAGE_TAG=latest -FROM ghcr.io/ngwpc/ngen-bmi-forcing:${NGEN_FORCING_IMAGE_TAG} AS base +#FROM ghcr.io/ngwpc/ngen-bmi-forcing:${NGEN_FORCING_IMAGE_TAG} AS base # Uncomment when building locally -#FROM ngen-bmi-forcing AS base +FROM ngen-bmi-forcing AS base # cannot remove LANG even though https://bugs.python.org/issue19846 is fixed # last attempted removal of LANG broke many users: diff --git a/src/geopackage/ngen_sqlite.cpp b/src/geopackage/ngen_sqlite.cpp index 20afdb6533..b332043c5a 100644 --- a/src/geopackage/ngen_sqlite.cpp +++ b/src/geopackage/ngen_sqlite.cpp @@ -233,7 +233,7 @@ auto database::query( } } const char *expanded = sqlite3_expanded_sql(stmt); - LOG(LogLevel::INFO, "Final query statement after binds: " + statement); + LOG(LogLevel::INFO, "Final query statement after binds: %s", expanded); } return iterator{stmt_t{stmt}}; From 9048e888e8246a825c2c8e7428c3fce212729535 Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 19 Nov 2025 10:50:36 -0500 Subject: [PATCH 5/9] loop to read --- Dockerfile | 4 ++-- src/geopackage/read.cpp | 34 +++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 566765bc3e..d0a43acffe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,10 @@ # Stage: Base – Common Setup ############################## ARG NGEN_FORCING_IMAGE_TAG=latest -#FROM ghcr.io/ngwpc/ngen-bmi-forcing:${NGEN_FORCING_IMAGE_TAG} AS base +FROM ghcr.io/ngwpc/ngen-bmi-forcing:${NGEN_FORCING_IMAGE_TAG} AS base # Uncomment when building locally -FROM ngen-bmi-forcing AS base +#FROM ngen-bmi-forcing AS base # cannot remove LANG even though https://bugs.python.org/issue19846 is fixed # last attempted removal of LANG broke many users: diff --git a/src/geopackage/read.cpp b/src/geopackage/read.cpp index f4795a2750..ba77cb11eb 100644 --- a/src/geopackage/read.cpp +++ b/src/geopackage/read.cpp @@ -26,6 +26,11 @@ std::shared_ptr ngen::geopackage::read( { // Check for malicious/invalid layer input check_table_name(layer); + std::vector features; + double min_x = std::numeric_limits::infinity(); + double min_y = std::numeric_limits::infinity(); + double max_x = -std::numeric_limits::infinity(); + double max_y = -std::numeric_limits::infinity(); LOG(LogLevel::INFO, "Creating gpkg connection"); ngen::sqlite::database db{gpkg_path}; @@ -68,6 +73,12 @@ std::shared_ptr ngen::geopackage::read( } } + int limit = 900; + boost::span id_span(ids); + for (int i = 0; i < ids.size(); i += limit) { + int span_size = (i + limit >= ids.size()) ? (ids.size() - limit) : limit; + boost::span sub_ids = id_span.subspan(i, limit); + // Layer exists, getting statement for it // // this creates a string in the form: @@ -76,10 +87,10 @@ std::shared_ptr ngen::geopackage::read( // This is safer than trying to concatenate // the IDs together. std::string joined_ids = ""; - if (!ids.empty()) { - LOG(LogLevel::INFO, "Joining %d IDs", (int)ids.size()); + if (!sub_ids.empty()) { + LOG(LogLevel::INFO, "Joining %d IDs", (int)sub_ids.size()); joined_ids = " WHERE "+id_column+" IN (?"; - for (size_t i = 1; i < ids.size(); i++) { + for (size_t i = 1; i < sub_ids.size(); i++) { joined_ids += ", ?"; } joined_ids += ")"; @@ -87,16 +98,16 @@ std::shared_ptr ngen::geopackage::read( // Get number of features LOG(LogLevel::INFO, "Querying count"); - auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, ids); + auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, sub_ids); query_get_layer_count.next(); const int layer_feature_count = query_get_layer_count.get(0); #ifndef NGEN_QUIET // output debug info on what is read exactly read_ss << "Reading " << layer_feature_count << " features from layer " << layer << " using ID column `"<< id_column << "`"; - if (!ids.empty()) { + if (!sub_ids.empty()) { read_ss << " (id subset:"; - for (auto& id : ids) { + for (auto& id : sub_ids) { read_ss << " " << id; } read_ss << ")"; @@ -113,13 +124,12 @@ std::shared_ptr ngen::geopackage::read( // Get layer LOG(LogLevel::INFO, "Getting layer reference"); - auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, ids); + auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, sub_ids); query_get_layer.next(); // build features out of layer query LOG(LogLevel::INFO, "Building features list"); - std::vector features; - features.reserve(layer_feature_count); + features.reserve(features.size() + layer_feature_count); while(!query_get_layer.done()) { geojson::Feature feature = build_feature( query_get_layer, @@ -138,10 +148,6 @@ std::shared_ptr ngen::geopackage::read( // however, it is in the SRS of the GPKG. By creating // the bbox after the features are built, the projection // is already done. This also should be fairly cheap to do. - double min_x = std::numeric_limits::infinity(); - double min_y = std::numeric_limits::infinity(); - double max_x = -std::numeric_limits::infinity(); - double max_y = -std::numeric_limits::infinity(); for (const auto& feature : features) { const auto& bbox = feature->get_bounding_box(); min_x = bbox[0] < min_x ? bbox[0] : min_x; @@ -150,6 +156,8 @@ std::shared_ptr ngen::geopackage::read( max_y = bbox[3] > max_y ? bbox[3] : max_y; } +} + auto fc = std::make_shared( std::move(features), std::vector({min_x, min_y, max_x, max_y}) From f6a3b2b08227c20308597852bbfc1cc6c9302a9e Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 19 Nov 2025 10:52:09 -0500 Subject: [PATCH 6/9] set span size --- src/geopackage/read.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geopackage/read.cpp b/src/geopackage/read.cpp index ba77cb11eb..2c056cf657 100644 --- a/src/geopackage/read.cpp +++ b/src/geopackage/read.cpp @@ -77,7 +77,7 @@ std::shared_ptr ngen::geopackage::read( boost::span id_span(ids); for (int i = 0; i < ids.size(); i += limit) { int span_size = (i + limit >= ids.size()) ? (ids.size() - limit) : limit; - boost::span sub_ids = id_span.subspan(i, limit); + boost::span sub_ids = id_span.subspan(i, span_size); // Layer exists, getting statement for it // From ec95aa3dbf50fbef9a3f31aced8ce01902178727 Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 19 Nov 2025 12:57:22 -0500 Subject: [PATCH 7/9] Account for zero IDs --- src/geopackage/read.cpp | 157 ++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 78 deletions(-) diff --git a/src/geopackage/read.cpp b/src/geopackage/read.cpp index 2c056cf657..1287d16673 100644 --- a/src/geopackage/read.cpp +++ b/src/geopackage/read.cpp @@ -73,90 +73,91 @@ std::shared_ptr ngen::geopackage::read( } } - int limit = 900; + // execute sub-queries if the number of IDs gets too long + int bind_limit = 900; boost::span id_span(ids); - for (int i = 0; i < ids.size(); i += limit) { - int span_size = (i + limit >= ids.size()) ? (ids.size() - limit) : limit; - boost::span sub_ids = id_span.subspan(i, span_size); - - // Layer exists, getting statement for it - // - // this creates a string in the form: - // WHERE id IN (?, ?, ?, ...) - // so that it can be bound by SQLite. - // This is safer than trying to concatenate - // the IDs together. - std::string joined_ids = ""; - if (!sub_ids.empty()) { - LOG(LogLevel::INFO, "Joining %d IDs", (int)sub_ids.size()); - joined_ids = " WHERE "+id_column+" IN (?"; - for (size_t i = 1; i < sub_ids.size(); i++) { - joined_ids += ", ?"; + for (int i = 0; i < ids.size() || (i == 0 && ids.size() == 0); i += bind_limit) { + int span_size = (i + bind_limit >= ids.size()) ? (ids.size() - i) : bind_limit; + boost::span sub_ids = id_span.subspan(i, span_size); + + // Layer exists, getting statement for it + // + // this creates a string in the form: + // WHERE id IN (?, ?, ?, ...) + // so that it can be bound by SQLite. + // This is safer than trying to concatenate + // the IDs together. + std::string joined_ids = ""; + if (!sub_ids.empty()) { + LOG(LogLevel::INFO, "Joining %d IDs", (int)sub_ids.size()); + joined_ids = " WHERE "+id_column+" IN (?"; + for (size_t i = 1; i < sub_ids.size(); i++) { + joined_ids += ", ?"; + } + joined_ids += ")"; } - joined_ids += ")"; - } - // Get number of features - LOG(LogLevel::INFO, "Querying count"); - auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, sub_ids); - query_get_layer_count.next(); - const int layer_feature_count = query_get_layer_count.get(0); - - #ifndef NGEN_QUIET - // output debug info on what is read exactly - read_ss << "Reading " << layer_feature_count << " features from layer " << layer << " using ID column `"<< id_column << "`"; - if (!sub_ids.empty()) { - read_ss << " (id subset:"; - for (auto& id : sub_ids) { - read_ss << " " << id; + // Get number of features + LOG(LogLevel::INFO, "Querying count"); + auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, sub_ids); + query_get_layer_count.next(); + const int layer_feature_count = query_get_layer_count.get(0); + + #ifndef NGEN_QUIET + // output debug info on what is read exactly + read_ss << "Reading " << layer_feature_count << " features from layer " << layer << " using ID column `"<< id_column << "`"; + if (!sub_ids.empty()) { + read_ss << " (id subset:"; + for (auto& id : sub_ids) { + read_ss << " " << id; + } + read_ss << ")"; } - read_ss << ")"; - } - read_ss << std::endl; - LOG(read_ss.str(), LogLevel::DEBUG); read_ss.str(""); - #endif - - // Get layer feature metadata (geometry column name + type) - LOG(LogLevel::INFO, "Querying geom column"); - auto query_get_layer_geom_meta = db.query("SELECT column_name FROM gpkg_geometry_columns WHERE table_name = ?", layer); - query_get_layer_geom_meta.next(); - const std::string layer_geometry_column = query_get_layer_geom_meta.get(0); - - // Get layer - LOG(LogLevel::INFO, "Getting layer reference"); - auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, sub_ids); - query_get_layer.next(); - - // build features out of layer query - LOG(LogLevel::INFO, "Building features list"); - features.reserve(features.size() + layer_feature_count); - while(!query_get_layer.done()) { - geojson::Feature feature = build_feature( - query_get_layer, - id_column, - layer_geometry_column - ); - - features.push_back(feature); + read_ss << std::endl; + LOG(read_ss.str(), LogLevel::DEBUG); read_ss.str(""); + #endif + + // Get layer feature metadata (geometry column name + type) + LOG(LogLevel::INFO, "Querying geom column"); + auto query_get_layer_geom_meta = db.query("SELECT column_name FROM gpkg_geometry_columns WHERE table_name = ?", layer); + query_get_layer_geom_meta.next(); + const std::string layer_geometry_column = query_get_layer_geom_meta.get(0); + + // Get layer + LOG(LogLevel::INFO, "Getting layer reference"); + auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, sub_ids); query_get_layer.next(); - } - LOG(LogLevel::INFO, "Done with sql stuff"); - - // get layer bounding box from features - // - // GeoPackage contains a bounding box in the SQLite DB, - // however, it is in the SRS of the GPKG. By creating - // the bbox after the features are built, the projection - // is already done. This also should be fairly cheap to do. - for (const auto& feature : features) { - const auto& bbox = feature->get_bounding_box(); - min_x = bbox[0] < min_x ? bbox[0] : min_x; - min_y = bbox[1] < min_y ? bbox[1] : min_y; - max_x = bbox[2] > max_x ? bbox[2] : max_x; - max_y = bbox[3] > max_y ? bbox[3] : max_y; - } -} + // build features out of layer query + LOG(LogLevel::INFO, "Building features list"); + features.reserve(features.size() + layer_feature_count); + while(!query_get_layer.done()) { + geojson::Feature feature = build_feature( + query_get_layer, + id_column, + layer_geometry_column + ); + + features.push_back(feature); + query_get_layer.next(); + } + LOG(LogLevel::INFO, "Done with sql stuff"); + + // get layer bounding box from features + // + // GeoPackage contains a bounding box in the SQLite DB, + // however, it is in the SRS of the GPKG. By creating + // the bbox after the features are built, the projection + // is already done. This also should be fairly cheap to do. + for (const auto& feature : features) { + const auto& bbox = feature->get_bounding_box(); + min_x = bbox[0] < min_x ? bbox[0] : min_x; + min_y = bbox[1] < min_y ? bbox[1] : min_y; + max_x = bbox[2] > max_x ? bbox[2] : max_x; + max_y = bbox[3] > max_y ? bbox[3] : max_y; + } + + } auto fc = std::make_shared( std::move(features), From d9cd08d37775f7b0a01647fc028187c9210ba693 Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 19 Nov 2025 13:34:14 -0500 Subject: [PATCH 8/9] Clean up messy logs and code use for testing --- src/geopackage/ngen_sqlite.cpp | 3 --- src/geopackage/read.cpp | 17 +++++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/geopackage/ngen_sqlite.cpp b/src/geopackage/ngen_sqlite.cpp index b332043c5a..0bf28bb608 100644 --- a/src/geopackage/ngen_sqlite.cpp +++ b/src/geopackage/ngen_sqlite.cpp @@ -211,7 +211,6 @@ auto database::query( const boost::span binds ) -> iterator { - LOG(LogLevel::INFO, "Raw query statement: " + statement); sqlite3_stmt* stmt = nullptr; const int code = sqlite3_prepare_v2( connection(), @@ -232,8 +231,6 @@ auto database::query( throw sqlite_error{"sqlite3_bind_text", code}; } } - const char *expanded = sqlite3_expanded_sql(stmt); - LOG(LogLevel::INFO, "Final query statement after binds: %s", expanded); } return iterator{stmt_t{stmt}}; diff --git a/src/geopackage/read.cpp b/src/geopackage/read.cpp index 1287d16673..c4031a00a4 100644 --- a/src/geopackage/read.cpp +++ b/src/geopackage/read.cpp @@ -27,16 +27,17 @@ std::shared_ptr ngen::geopackage::read( // Check for malicious/invalid layer input check_table_name(layer); std::vector features; + if (ids.size() > 0) + features.reserve(ids.size()); double min_x = std::numeric_limits::infinity(); double min_y = std::numeric_limits::infinity(); double max_x = -std::numeric_limits::infinity(); double max_y = -std::numeric_limits::infinity(); - LOG(LogLevel::INFO, "Creating gpkg connection"); + LOG(LogLevel::DEBUG, "Establishing connection to geopackage %s.", gpkg_path.c_str()); ngen::sqlite::database db{gpkg_path}; // Check if layer exists - LOG(LogLevel::INFO, "Checking if layer exists."); if (!db.contains(layer)) { // Since the layer doesn't exist, we need to output some additional // debug information with the error. In this case, we add ALL the tables @@ -73,7 +74,7 @@ std::shared_ptr ngen::geopackage::read( } } - // execute sub-queries if the number of IDs gets too long + // execute sub-queries if the number of IDs gets too long or once if ids.size() == 0 int bind_limit = 900; boost::span id_span(ids); for (int i = 0; i < ids.size() || (i == 0 && ids.size() == 0); i += bind_limit) { @@ -89,7 +90,6 @@ std::shared_ptr ngen::geopackage::read( // the IDs together. std::string joined_ids = ""; if (!sub_ids.empty()) { - LOG(LogLevel::INFO, "Joining %d IDs", (int)sub_ids.size()); joined_ids = " WHERE "+id_column+" IN (?"; for (size_t i = 1; i < sub_ids.size(); i++) { joined_ids += ", ?"; @@ -98,7 +98,6 @@ std::shared_ptr ngen::geopackage::read( } // Get number of features - LOG(LogLevel::INFO, "Querying count"); auto query_get_layer_count = db.query("SELECT COUNT(*) FROM " + layer + joined_ids, sub_ids); query_get_layer_count.next(); const int layer_feature_count = query_get_layer_count.get(0); @@ -118,19 +117,18 @@ std::shared_ptr ngen::geopackage::read( #endif // Get layer feature metadata (geometry column name + type) - LOG(LogLevel::INFO, "Querying geom column"); auto query_get_layer_geom_meta = db.query("SELECT column_name FROM gpkg_geometry_columns WHERE table_name = ?", layer); query_get_layer_geom_meta.next(); const std::string layer_geometry_column = query_get_layer_geom_meta.get(0); // Get layer - LOG(LogLevel::INFO, "Getting layer reference"); + LOG(LogLevel::DEBUG, "Reading %d features from layer %s.", layer_feature_count, layer.c_str()); auto query_get_layer = db.query("SELECT * FROM " + layer + joined_ids, sub_ids); query_get_layer.next(); // build features out of layer query - LOG(LogLevel::INFO, "Building features list"); - features.reserve(features.size() + layer_feature_count); + if (ids.size() == 0) + features.reserve(layer_feature_count); while(!query_get_layer.done()) { geojson::Feature feature = build_feature( query_get_layer, @@ -141,7 +139,6 @@ std::shared_ptr ngen::geopackage::read( features.push_back(feature); query_get_layer.next(); } - LOG(LogLevel::INFO, "Done with sql stuff"); // get layer bounding box from features // From bb47f2301108362ae227f7388301dbf7afe4be7e Mon Sep 17 00:00:00 2001 From: Ian Todd Date: Wed, 3 Dec 2025 11:33:51 -0500 Subject: [PATCH 9/9] Test UEB branch --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 4a3187d404..e7cf59b075 100644 --- a/.gitmodules +++ b/.gitmodules @@ -58,7 +58,7 @@ [submodule "extern/ueb-bmi"] path = extern/ueb-bmi url = https://github.com/NGWPC/ueb_bmi.git - branch = development + branch = idt-ueb-inclusive-end-step [submodule "extern/lstm"] path = extern/lstm url = https://github.com/NGWPC/lstm.git