diff --git a/gdalgeometry.cpp b/gdalgeometry.cpp index 8fe25318..9164a4d0 100644 --- a/gdalgeometry.cpp +++ b/gdalgeometry.cpp @@ -593,7 +593,7 @@ Layer::~Layer() } } -Layer& Layer::operator=(Layer&& other) +Layer& Layer::operator=(Layer&& other) noexcept { _layer = other._layer; other._layer = nullptr; @@ -622,23 +622,41 @@ std::optional Layer::epsg() const return std::optional(); } -void Layer::set_projection(SpatialReference& srs) +void Layer::set_active_projection(SpatialReference& srs) { const int geomCount = _layer->GetLayerDefn()->GetGeomFieldCount(); for (int i = 0; i < geomCount; ++i) { - _layer->GetLayerDefn()->GetGeomFieldDefn(i)->SetSpatialRef(srs.get()); + check_error(_layer->SetActiveSRS(i, srs.get()), "Failed to set the active projection"); } } -void Layer::set_projection_from_epsg(int32_t epsg) +void Layer::set_active_projection_from_epsg(int32_t epsg) { SpatialReference srs(epsg); + set_active_projection(srs); +} + +void Layer::set_projection(SpatialReference& srs) +{ const int geomCount = _layer->GetLayerDefn()->GetGeomFieldCount(); + + if (_layer->TestCapability(OLCAlterGeomFieldDefn) == 0) { + throw RuntimeError("Layer does not support altering geometry field definitions"); + } + for (int i = 0; i < geomCount; ++i) { - _layer->GetLayerDefn()->GetGeomFieldDefn(i)->SetSpatialRef(srs.get()); + OGRGeomFieldDefn def(_layer->GetLayerDefn()->GetGeomFieldDefn(i)); + def.SetSpatialRef(srs.get()); + check_error(_layer->AlterGeomFieldDefn(i, &def, ALTER_GEOM_FIELD_DEFN_SRS_FLAG), "Failed to alter geometry field"); } } +void Layer::set_projection_from_epsg(int32_t epsg) +{ + SpatialReference srs(epsg); + set_projection(srs); +} + std::optional Layer::projection() const { if (auto* srs = _layer->GetSpatialRef(); srs != nullptr) { diff --git a/include/infra/gdalgeometry.h b/include/infra/gdalgeometry.h index ad1e7f31..0ba798b5 100644 --- a/include/infra/gdalgeometry.h +++ b/include/infra/gdalgeometry.h @@ -1032,10 +1032,15 @@ class Layer Layer(Layer&&); ~Layer(); - Layer& operator=(Layer&&); + Layer& operator=(Layer&&) noexcept; Layer& operator=(const Layer&); std::optional epsg() const; + + // Changes the layers project while working with but will not persist this change after reopening the layer + void set_active_projection(SpatialReference& srs); + void set_active_projection_from_epsg(int32_t epsg); + //! Make sure the spatial reference stays in scope while using the layer! void set_projection(SpatialReference& srs); void set_projection_from_epsg(int32_t epsg);