55
66C++11 wrapper classes for GDAL/OGR.
77
8- Version 1.3 .0
8+ Version 1.4 .0
99
1010https://github.com/joto/gdalcpp
1111
12- Copyright 2015-2021 Jochen Topf <jochen@topf.org>
12+ Copyright 2015-2026 Jochen Topf <jochen@topf.org>
1313
1414Boost Software License - Version 1.0 - August 17th, 2003
1515
@@ -42,30 +42,22 @@ DEALINGS IN THE SOFTWARE.
4242#include < ogr_api.h>
4343#include < ogrsf_frmts.h>
4444
45- #include < cstdint>
4645#include < algorithm>
46+ #include < cstdint>
4747#include < memory>
4848#include < stdexcept>
4949#include < string>
5050#include < utility>
5151#include < vector>
5252
53- #if defined( _MSC_VER)
53+ #ifdef _MSC_VER
5454# define GDALCPP_EXPORT __declspec (dllexport)
5555#else
5656# define GDALCPP_EXPORT __attribute__ ((visibility(" default" )))
5757#endif
5858
5959namespace gdalcpp {
6060
61- #if GDAL_VERSION_MAJOR >= 2
62- using gdal_driver_type = GDALDriver;
63- using gdal_dataset_type = GDALDataset;
64- #else
65- using gdal_driver_type = OGRSFDriver;
66- using gdal_dataset_type = OGRDataSource;
67- #endif
68-
6961 /* *
7062 * Exception thrown for all errors in this class.
7163 */
@@ -93,23 +85,23 @@ namespace gdalcpp {
9385 m_error (error) {
9486 }
9587
96- const std::string& driver () const noexcept {
88+ [[nodiscard]] const std::string& driver () const noexcept {
9789 return m_driver;
9890 }
9991
100- const std::string& dataset () const noexcept {
92+ [[nodiscard]] const std::string& dataset () const noexcept {
10193 return m_dataset;
10294 }
10395
104- const std::string& layer () const noexcept {
96+ [[nodiscard]] const std::string& layer () const noexcept {
10597 return m_layer;
10698 }
10799
108- const std::string& field () const noexcept {
100+ [[nodiscard]] const std::string& field () const noexcept {
109101 return m_field;
110102 }
111103
112- OGRErr error () const noexcept {
104+ [[nodiscard]] OGRErr error () const noexcept {
113105 return m_error;
114106 }
115107
@@ -118,73 +110,61 @@ namespace gdalcpp {
118110 namespace detail {
119111
120112 struct init_wrapper {
121- #if GDAL_VERSION_MAJOR >= 2
122113 init_wrapper () noexcept {
123114 GDALAllRegister ();
124115 }
125- #else
126- init_wrapper () noexcept {
127- OGRRegisterAll ();
128- }
129- ~init_wrapper () noexcept {
130- OGRCleanupAll ();
131- }
132- #endif
133116 }; // struct init_wrapper
134117
135118 struct init_library {
136119
137120 init_library () {
138- static init_wrapper iw;
121+ static init_wrapper const iw;
139122 }
140123
141124 }; // struct init_library
142125
143126 class Driver : private init_library {
144127
145- gdal_driver_type * m_driver;
128+ GDALDriver * m_driver;
146129
147130 public:
148131
149132 Driver (const std::string& driver_name) :
150- init_library (),
151- #if GDAL_VERSION_MAJOR >= 2
152133 m_driver (GetGDALDriverManager()->GetDriverByName (driver_name.c_str())) {
153- #else
154- m_driver (OGRSFDriverRegistrar::GetRegistrar ()->GetDriverByName (driver_name.c_str ())) {
155- #endif
156134 if (!m_driver) {
157135 throw gdal_error{std::string{" unknown driver: '" } + driver_name + " '" ,
158136 OGRERR_NONE ,
159137 driver_name};
160138 }
161139 }
162140
163- gdal_driver_type & get () const noexcept {
141+ [[nodiscard]] GDALDriver & get () const noexcept {
164142 return *m_driver;
165143 }
166144
167- }; // struct Driver
145+ }; // class Driver
168146
169- struct Options {
147+ class Options {
170148
171149 std::vector<std::string> m_options;
172- std::unique_ptr<const char *[]> m_ptrs;
150+ std::unique_ptr<char *[]> m_ptrs;
151+
152+ public:
173153
174154 Options (const std::vector<std::string>& options) :
175155 m_options (options),
176- m_ptrs (new const char *[options.size() + 1 ]) {
177- std::transform (m_options.begin (), m_options.end (), m_ptrs.get (), [&](const std::string& s) {
156+ m_ptrs (new char *[options.size() + 1 ]) {
157+ std::transform (m_options.begin (), m_options.end (), m_ptrs.get (), [&](std::string& s) {
178158 return s.data ();
179159 });
180160 m_ptrs[options.size ()] = nullptr ;
181161 }
182162
183- char ** get () const noexcept {
184- return const_cast < char **>( m_ptrs.get () );
163+ [[nodiscard]] char ** get () const noexcept {
164+ return m_ptrs.get ();
185165 }
186166
187- }; // struct Options
167+ }; // class Options
188168
189169 } // namespace detail
190170
@@ -234,11 +214,11 @@ namespace gdalcpp {
234214 m_spatial_reference(spatial_reference) {
235215 }
236216
237- OGRSpatialReference& get () noexcept {
217+ [[nodiscard]] OGRSpatialReference& get () noexcept {
238218 return m_spatial_reference;
239219 }
240220
241- const OGRSpatialReference& get () const noexcept {
221+ [[nodiscard]] const OGRSpatialReference& get () const noexcept {
242222 return m_spatial_reference;
243223 }
244224
@@ -248,12 +228,8 @@ namespace gdalcpp {
248228
249229 struct gdal_dataset_deleter {
250230
251- void operator ()(gdal_dataset_type* ds) {
252- #if GDAL_VERSION_MAJOR >= 2
231+ void operator ()(GDALDataset* ds) {
253232 GDALClose (ds);
254- #else
255- OGRDataSource::DestroyDataSource (ds);
256- #endif
257233 }
258234
259235 }; // struct gdal_dataset_deleter
@@ -262,7 +238,7 @@ namespace gdalcpp {
262238 std::string m_dataset_name;
263239 detail::Options m_options;
264240 SRS m_srs;
265- std::unique_ptr<gdal_dataset_type , gdal_dataset_deleter> m_dataset;
241+ std::unique_ptr<GDALDataset , gdal_dataset_deleter> m_dataset;
266242 uint64_t m_edit_count = 0 ;
267243 uint64_t m_max_edit_count = 0 ;
268244
@@ -273,11 +249,7 @@ namespace gdalcpp {
273249 m_dataset_name (dataset_name),
274250 m_options (options),
275251 m_srs (srs),
276- #if GDAL_VERSION_MAJOR >= 2
277252 m_dataset (detail::Driver(driver_name).get().Create(dataset_name.c_str(), 0 , 0 , 0 , GDT_Unknown, m_options.get())) {
278- #else
279- m_dataset (detail::Driver (driver_name).get ().CreateDataSource (dataset_name.c_str (), m_options.get ())) {
280- #endif
281253 if (!m_dataset) {
282254 throw gdal_error{std::string{" failed to create dataset '" } + dataset_name + " '" ,
283255 OGRERR_NONE ,
@@ -295,24 +267,24 @@ namespace gdalcpp {
295267 }
296268 }
297269
298- const std::string& driver_name () const noexcept {
270+ [[nodiscard]] const std::string& driver_name () const noexcept {
299271 return m_driver_name;
300272 }
301273
302- const std::string& dataset_name () const noexcept {
274+ [[nodiscard]] const std::string& dataset_name () const noexcept {
303275 return m_dataset_name;
304276 }
305277
306- gdal_dataset_type & get () const noexcept {
278+ [[nodiscard]] GDALDataset & get () const noexcept {
307279 return *m_dataset;
308280 }
309281
310- SRS & srs () noexcept {
282+ [[nodiscard]] SRS & srs () noexcept {
311283 return m_srs;
312284 }
313285
314286 void exec (const char * sql) {
315- const auto result = m_dataset->ExecuteSQL (sql, nullptr , nullptr );
287+ OGRLayer * const result = m_dataset->ExecuteSQL (sql, nullptr , nullptr );
316288 if (result) {
317289 m_dataset->ReleaseResultSet (result);
318290 }
@@ -323,26 +295,12 @@ namespace gdalcpp {
323295 }
324296
325297 Dataset& start_transaction () {
326- #if GDAL_VERSION_MAJOR >= 2
327298 m_dataset->StartTransaction ();
328- #else
329- OGRLayer* layer = m_dataset->GetLayer (0 );
330- if (layer) {
331- layer->StartTransaction ();
332- }
333- #endif
334299 return *this ;
335300 }
336301
337302 Dataset& commit_transaction () {
338- #if GDAL_VERSION_MAJOR >= 2
339303 m_dataset->CommitTransaction ();
340- #else
341- OGRLayer* layer = m_dataset->GetLayer (0 );
342- if (layer) {
343- layer->CommitTransaction ();
344- }
345- #endif
346304 m_edit_count = 0 ;
347305 return *this ;
348306 }
@@ -377,14 +335,14 @@ namespace gdalcpp {
377335 class Layer {
378336
379337 detail::Options m_options;
380- Dataset& m_dataset;
338+ Dataset* m_dataset;
381339 OGRLayer* m_layer;
382340
383341 public:
384342
385343 Layer (Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type, const std::vector<std::string>& options = {}) :
386344 m_options (options),
387- m_dataset (dataset),
345+ m_dataset (& dataset),
388346 m_layer (dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) {
389347 if (!m_layer) {
390348 throw gdal_error{std::string{" failed to create layer '" } + layer_name + " '" ,
@@ -395,19 +353,19 @@ namespace gdalcpp {
395353 }
396354 }
397355
398- OGRLayer& get () noexcept {
356+ [[nodiscard]] OGRLayer& get () noexcept {
399357 return *m_layer;
400358 }
401359
402- const OGRLayer& get () const noexcept {
360+ [[nodiscard]] const OGRLayer& get () const noexcept {
403361 return *m_layer;
404362 }
405363
406- Dataset& dataset () const noexcept {
407- return m_dataset;
364+ [[nodiscard]] Dataset& dataset () const noexcept {
365+ return * m_dataset;
408366 }
409367
410- const char * name () const {
368+ [[nodiscard]] const char * name () const {
411369 return m_layer->GetName ();
412370 }
413371
@@ -419,8 +377,8 @@ namespace gdalcpp {
419377 if (m_layer->CreateField (&field) != OGRERR_NONE ) {
420378 throw gdal_error{std::string{" failed to create field '" } + field_name + " ' in layer '" + name () + " '" ,
421379 OGRERR_NONE ,
422- m_dataset. driver_name (),
423- m_dataset. dataset_name (),
380+ m_dataset-> driver_name (),
381+ m_dataset-> dataset_name (),
424382 name (),
425383 field_name};
426384 }
@@ -441,30 +399,10 @@ namespace gdalcpp {
441399 }
442400
443401 Layer& start_transaction () {
444- #if GDAL_VERSION_MAJOR < 2
445- const auto result = m_layer->StartTransaction ();
446- if (result != OGRERR_NONE ) {
447- throw gdal_error{std::string{" starting transaction on layer '" } + name () + " ' failed" ,
448- result,
449- m_dataset.driver_name (),
450- m_dataset.dataset_name (),
451- name ()};
452- }
453- #endif
454402 return *this ;
455403 }
456404
457405 Layer& commit_transaction () {
458- #if GDAL_VERSION_MAJOR < 2
459- const auto result = m_layer->CommitTransaction ();
460- if (result != OGRERR_NONE ) {
461- throw gdal_error{std::string{" committing transaction on layer '" } + name () + " ' failed" ,
462- result,
463- m_dataset.driver_name (),
464- m_dataset.dataset_name (),
465- name ()};
466- }
467- #endif
468406 return *this ;
469407 }
470408
@@ -480,28 +418,28 @@ namespace gdalcpp {
480418
481419 }; // struct ogr_feature_deleter
482420
483- Layer& m_layer;
421+ Layer* m_layer;
484422 std::unique_ptr<OGRFeature, ogr_feature_deleter> m_feature;
485423
486424 public:
487425
488426 Feature (Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) :
489- m_layer (layer),
490- m_feature (OGRFeature::CreateFeature(m_layer. get().GetLayerDefn())) {
427+ m_layer (& layer),
428+ m_feature (OGRFeature::CreateFeature(m_layer-> get ().GetLayerDefn())) {
491429 if (!m_feature) {
492430 throw std::bad_alloc{};
493431 }
494432 const auto result = m_feature->SetGeometryDirectly (geometry.release ());
495433 if (result != OGRERR_NONE ) {
496- throw gdal_error{std::string{" setting feature geometry in layer '" } + m_layer. name () + " ' failed" ,
434+ throw gdal_error{std::string{" setting feature geometry in layer '" } + m_layer-> name () + " ' failed" ,
497435 result,
498- m_layer. dataset ().driver_name (),
499- m_layer. dataset ().dataset_name ()};
436+ m_layer-> dataset ().driver_name (),
437+ m_layer-> dataset ().dataset_name ()};
500438 }
501439 }
502440
503441 void add_to_layer () {
504- m_layer. create_feature (m_feature.get ());
442+ m_layer-> create_feature (m_feature.get ());
505443 }
506444
507445 template <typename T>
0 commit comments