LuciadCPillar support for GeoPackage

There is basic support for the decoding of GeoPackage data.

The GeoPackageModelDecoder::discoverTables method provides a list of all decodable tables in a GeoPackage file. You can then individually decode those tables with a second method call, depending on the data type they contain.

Decoding features

For feature decoding details, see the GeoPackageModelDecoder::decode method documentation.

Decoding tiles

You can open GeoPackage files that contain tiles in a tile matrix set representing a quad-tree. See the method documentation of GeoPackageModelDecoder::decode for details.

Decoding example

Program (C++): Decoding GeoPackage data
const std::string source = "test/resources/Data/GeoPackage/states10.gpkg";
luciad::expected<std::vector<GeoPackageTableMetadata>, ErrorInfo> tablesExpected = GeoPackageModelDecoder::discoverTables(source);
if (!tablesExpected.has_value()) {
  std::cout << "Failed to load GeoPackage file " << source << ": " << tablesExpected.error().getMessage() << std::endl;
  return;
}

const std::vector<GeoPackageTableMetadata>& tables = tablesExpected.value();
std::cout << "The GeoPackage file contains " << tables.size() << " table(s):" << std::endl;

for (const GeoPackageTableMetadata& table : tables) {
  std::cout << " * Table '" << table.getName() << "' ";
  if (table.getType() == GeoPackageTableMetadata::TableType::Features) {
    luciad::expected<std::shared_ptr<Model>, ErrorInfo> modelExpected = GeoPackageModelDecoder::decode(source, table.getName());
    if (modelExpected.has_value()) {
      auto model = std::dynamic_pointer_cast<IFeatureModel>(*modelExpected);
      if (model != nullptr) {
        uint32_t count = 0;
        std::unique_ptr<IFeatureQueryCallback> callback = IFeatureQueryCallback::create([&](const Feature& /*f*/) {
          count++;
          return true;
        });
        model->query(FeatureQuery::all(), *callback);
        std::cout << "contains " << count << " features.";
      }
    } else {
      ErrorInfo errorInfo = modelExpected.error();
      std::cout << "could not be decoded: " << errorInfo.getMessage();
    }
  } else {
    std::cout << "contains raster data.";
  }
  std::cout << std::endl;
}