LuciadCPillar offers support for the editing of feature data in GeoPackage files. Program: Editing GeoPackage data shows you a code example, which is further explained in the remainder of the article.
Code sample
const std::string source = "test/resources/Data/GeoPackage/cities125.gpkg"; std::shared_ptr<GeoPackageDataSource> datasource = GeoPackageDataSource::newBuilder().source(source).build(); GeoPackageModelDecoderOptions options = GeoPackageModelDecoderOptions::newBuilder().editable(true).build(); luciad::expected<std::shared_ptr<Model>, ErrorInfo> modelExpected = GeoPackageModelDecoder::decode(datasource, options); if (modelExpected.has_value()) { auto model = std::dynamic_pointer_cast<IFeatureModel>(*modelExpected); if (model != nullptr) { std::shared_ptr<FeatureModelUpdate> modelUpdate = FeatureModelUpdate::newBuilder().removeFeature(8).build(); model->getUpdater()->update(modelUpdate); if (const std::optional<FeatureSaveErrorInfo>& error = model->getPersistenceManager()->saveChanges()) { if (const auto& generalError = error->getGeneralError()) { std::cout << "saveChanges failed: " << generalError->getMessage(); } for (const auto& featureId : error->getFeatureIds()) { std::cout << "saveChanges failed on feature: " << featureId << ": " << error->getFeatureError(featureId); } } } } else { ErrorInfo errorInfo = modelExpected.error(); std::cout << "could not be decoded: " << errorInfo.getMessage(); }
Enabling editing
A decoded GeoPackage feature model is read-only by default. To obtain an editable IFeatureModel
, you must pass
GeoPackageModelDecoderOptions
set to allow editing to the GeoPackageModelDecoder::decode
method.
Editing the GeoPackage model
You can edit the IFeatureModel
through its IFeatureModelUpdater
,
which you can get with IFeatureModel::getUpdater
.
The IFeatureModelUpdater::update
method accepts a
FeatureModelUpdate
object that contains one or several
FeatureChanges
to change the model.
Saving changes
Changes aren’t immediately written to the GeoPackage file, but kept in memory initially. You need the
FeatureModelPersistenceManager
to save pending changes. You can get it using the IFeatureModel::getPersistenceManager
method.
To save the changes, call the FeatureModelPersistenceManager::saveChanges
method. You can also view and discard in-memory changes with that same class.
For more information about saving changes to feature models, see Working with feature models with save support.
Limitations
There are some limitations to the GeoPackage editing functionality. You can encode only features with geometries that can
be decoded. For a list
of these, see the documentation of the GeoPackageModelDecoder
.
In addition, the GeoPackage itself can add extra limitations. When you’re editing, only the feature table changes, and the corresponding RTree tables if they’re used. The table metadata doesn’t change.
Thus, the following constraints may apply:
-
You can only add geometries that require extensions if those extensions are present.
-
The "geometry_type_name" can limit allowed geometry types.
-
If measure values are mandatory, you can’t add or update features.
You can remove these limitations by changing the feature metadata of the GeoPackage. For more information on these limitations, see the GeoPackage specification.