Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrgeomfielddefn.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  The OGRGeomFieldDefn class implementation.
5
 * Author:   Even Rouault, <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "cpl_port.h"
14
#include "ogr_api.h"
15
16
#include <cstring>
17
18
#include "cpl_conv.h"
19
#include "cpl_error.h"
20
#include "ogr_core.h"
21
#include "ogr_feature.h"
22
#include "ogr_p.h"
23
#include "ogr_spatialref.h"
24
#include "ogr_srs_api.h"
25
#include "ograpispy.h"
26
27
/************************************************************************/
28
/*                          OGRGeomFieldDefn()                          */
29
/************************************************************************/
30
31
/**
32
 * \brief Constructor.
33
 *
34
 * @param pszNameIn the name of the new field.
35
 * @param eGeomTypeIn the type of the new field.
36
 *
37
 */
38
39
OGRGeomFieldDefn::OGRGeomFieldDefn(const char *pszNameIn,
40
                                   OGRwkbGeometryType eGeomTypeIn)
41
42
0
{
43
0
    Initialize(pszNameIn, eGeomTypeIn);
44
0
}
45
46
/************************************************************************/
47
/*                          OGRGeomFieldDefn()                          */
48
/************************************************************************/
49
50
/**
51
 * \brief Constructor.
52
 *
53
 * Create by cloning an existing geometry field definition.
54
 *
55
 * @param poPrototype the geometry field definition to clone.
56
 *
57
 */
58
59
OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn *poPrototype)
60
0
    : OGRGeomFieldDefn(*poPrototype)
61
62
0
{
63
0
}
64
65
/************************************************************************/
66
/*                          OGR_GFld_Create()                           */
67
/************************************************************************/
68
/**
69
 * \brief Create a new field geometry definition.
70
 *
71
 * This function is the same as the CPP method
72
 * OGRGeomFieldDefn::OGRGeomFieldDefn().
73
 *
74
 * @param pszName the name of the new field definition.
75
 * @param eType the type of the new field definition.
76
 * @return handle to the new field definition.
77
 *
78
 */
79
80
OGRGeomFieldDefnH OGR_GFld_Create(const char *pszName, OGRwkbGeometryType eType)
81
82
0
{
83
0
    return OGRGeomFieldDefn::ToHandle(new OGRGeomFieldDefn(pszName, eType));
84
0
}
85
86
/************************************************************************/
87
/*                             Initialize()                             */
88
/************************************************************************/
89
90
//! @cond Doxygen_Suppress
91
void OGRGeomFieldDefn::Initialize(const char *pszNameIn,
92
                                  OGRwkbGeometryType eTypeIn)
93
94
0
{
95
0
    pszName = CPLStrdup(pszNameIn);
96
0
    eGeomType = eTypeIn;
97
0
}
98
99
//! @endcond
100
101
/************************************************************************/
102
/*                         ~OGRGeomFieldDefn()                          */
103
/************************************************************************/
104
105
OGRGeomFieldDefn::~OGRGeomFieldDefn()
106
107
0
{
108
0
    CPLFree(pszName);
109
110
0
    if (nullptr != poSRS)
111
0
        const_cast<OGRSpatialReference *>(poSRS)->Release();
112
0
}
113
114
/************************************************************************/
115
/*                 OGRGeomFieldDefn::OGRGeomFieldDefn()                 */
116
/************************************************************************/
117
118
/**
119
 * @brief Copy constructor
120
 * @param oOther the OGRGeomFieldDefn to copy.
121
 * @since GDAL 3.11
122
 */
123
OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther)
124
0
    : pszName(CPLStrdup(oOther.pszName)), eGeomType(oOther.eGeomType),
125
0
      poSRS(nullptr), bIgnore(oOther.bIgnore), bNullable(oOther.bNullable),
126
0
      m_bSealed(false), m_oCoordPrecision(oOther.m_oCoordPrecision)
127
0
{
128
0
    if (auto poSrcSRS = oOther.GetSpatialRef())
129
0
    {
130
0
        poSRS = poSrcSRS->Clone();
131
0
    }
132
0
}
133
134
/************************************************************************/
135
/*                 OGRGeomFieldDefn::OGRGeomFieldDefn()                 */
136
/************************************************************************/
137
138
/**
139
 * @brief Move constructor
140
 * @param oOther the OGRGeomFieldDefn to move.
141
 * @since GDAL 3.13
142
 */
143
OGRGeomFieldDefn::OGRGeomFieldDefn(OGRGeomFieldDefn &&oOther)
144
0
    : pszName(oOther.pszName), eGeomType(oOther.eGeomType), poSRS(oOther.poSRS),
145
0
      bIgnore(oOther.bIgnore), bNullable(oOther.bNullable),
146
0
      m_bSealed(oOther.m_bSealed), m_oCoordPrecision(oOther.m_oCoordPrecision)
147
0
{
148
0
    oOther.pszName = nullptr;
149
0
    oOther.poSRS = nullptr;
150
0
}
151
152
/************************************************************************/
153
/*                    OGRGeomFieldDefn::operator=()                     */
154
/************************************************************************/
155
156
/**
157
 * Copy assignment operator
158
 * @param oOther the OGRGeomFieldDefn to copy.
159
 * @return a reference to the current object.
160
 * @since GDAL 3.11
161
 */
162
OGRGeomFieldDefn &OGRGeomFieldDefn::operator=(const OGRGeomFieldDefn &oOther)
163
0
{
164
0
    if (&oOther != this)
165
0
    {
166
0
        CPLFree(pszName);
167
0
        pszName = CPLStrdup(oOther.pszName);
168
0
        eGeomType = oOther.eGeomType;
169
0
        if (oOther.poSRS)
170
0
            const_cast<OGRSpatialReference *>(oOther.poSRS)->Reference();
171
0
        if (poSRS)
172
0
            const_cast<OGRSpatialReference *>(poSRS)->Dereference();
173
0
        poSRS = oOther.poSRS;
174
0
        bNullable = oOther.bNullable;
175
0
        m_oCoordPrecision = oOther.m_oCoordPrecision;
176
0
        m_bSealed = oOther.m_bSealed;
177
0
        bIgnore = oOther.bIgnore;
178
0
    }
179
0
    return *this;
180
0
}
181
182
/************************************************************************/
183
/*                    OGRGeomFieldDefn::operator=()                     */
184
/************************************************************************/
185
186
/**
187
 * Move assignment operator
188
 * @param oOther the OGRGeomFieldDefn to move.
189
 * @return a reference to the current object.
190
 * @since GDAL 3.13
191
 */
192
OGRGeomFieldDefn &OGRGeomFieldDefn::operator=(OGRGeomFieldDefn &&oOther)
193
0
{
194
0
    if (&oOther != this)
195
0
    {
196
0
        std::swap(pszName, oOther.pszName);
197
0
        eGeomType = oOther.eGeomType;
198
0
        std::swap(poSRS, oOther.poSRS);
199
0
        bNullable = oOther.bNullable;
200
0
        m_oCoordPrecision = oOther.m_oCoordPrecision;
201
0
        m_bSealed = oOther.m_bSealed;
202
0
        bIgnore = oOther.bIgnore;
203
0
    }
204
0
    return *this;
205
0
}
206
207
/************************************************************************/
208
/*                          OGR_GFld_Destroy()                          */
209
/************************************************************************/
210
/**
211
 * \brief Destroy a geometry field definition.
212
 *
213
 * @param hDefn handle to the geometry field definition to destroy.
214
 *
215
 */
216
217
void OGR_GFld_Destroy(OGRGeomFieldDefnH hDefn)
218
219
0
{
220
0
    VALIDATE_POINTER0(hDefn, "OGR_GFld_Destroy");
221
222
0
    delete OGRGeomFieldDefn::FromHandle(hDefn);
223
0
}
224
225
/************************************************************************/
226
/*                              SetName()                               */
227
/************************************************************************/
228
229
/**
230
 * \brief Reset the name of this field.
231
 *
232
 * This method is the same as the C function OGR_GFld_SetName().
233
 *
234
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
235
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
236
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
237
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
238
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
239
 *
240
 * @param pszNameIn the new name to apply.
241
 *
242
 */
243
244
void OGRGeomFieldDefn::SetName(const char *pszNameIn)
245
246
0
{
247
0
    if (m_bSealed)
248
0
    {
249
0
        CPLError(CE_Failure, CPLE_AppDefined,
250
0
                 "OGRGeomFieldDefn::SetName() not allowed on a sealed object");
251
0
        return;
252
0
    }
253
0
    if (pszName != pszNameIn)
254
0
    {
255
0
        CPLFree(pszName);
256
0
        pszName = CPLStrdup(pszNameIn);
257
0
    }
258
0
}
259
260
/************************************************************************/
261
/*                          OGR_GFld_SetName()                          */
262
/************************************************************************/
263
/**
264
 * \brief Reset the name of this field.
265
 *
266
 * This function is the same as the CPP method OGRGeomFieldDefn::SetName().
267
 *
268
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
269
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
270
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
271
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
272
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
273
 *
274
 * @param hDefn handle to the geometry field definition to apply the
275
 * new name to.
276
 * @param pszName the new name to apply.
277
 *
278
 */
279
280
void OGR_GFld_SetName(OGRGeomFieldDefnH hDefn, const char *pszName)
281
282
0
{
283
0
    VALIDATE_POINTER0(hDefn, "OGR_GFld_SetName");
284
285
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetName(pszName);
286
0
}
287
288
/************************************************************************/
289
/*                             GetNameRef()                             */
290
/************************************************************************/
291
292
/**
293
 * \fn const char *OGRGeomFieldDefn::GetNameRef();
294
 *
295
 * \brief Fetch name of this field.
296
 *
297
 * This method is the same as the C function OGR_GFld_GetNameRef().
298
 *
299
 * @return pointer to an internal name string that should not be freed or
300
 * modified.
301
 *
302
 */
303
304
/************************************************************************/
305
/*                        OGR_GFld_GetNameRef()                         */
306
/************************************************************************/
307
/**
308
 * \brief Fetch name of this field.
309
 *
310
 * This function is the same as the CPP method OGRGeomFieldDefn::GetNameRef().
311
 *
312
 * @param hDefn handle to the geometry field definition.
313
 * @return the name of the geometry field definition.
314
 *
315
 */
316
317
const char *OGR_GFld_GetNameRef(OGRGeomFieldDefnH hDefn)
318
319
0
{
320
0
    VALIDATE_POINTER1(hDefn, "OGR_GFld_GetNameRef", "");
321
322
0
#ifdef OGRAPISPY_ENABLED
323
0
    if (bOGRAPISpyEnabled)
324
0
        OGRAPISpy_GFld_GetXXXX(hDefn, "GetNameRef");
325
0
#endif
326
327
0
    return OGRGeomFieldDefn::FromHandle(hDefn)->GetNameRef();
328
0
}
329
330
/************************************************************************/
331
/*                              GetType()                               */
332
/************************************************************************/
333
334
/**
335
 * \fn OGRwkbGeometryType OGRGeomFieldDefn::GetType() const;
336
 *
337
 * \brief Fetch geometry type of this field.
338
 *
339
 * This method is the same as the C function OGR_GFld_GetType().
340
 *
341
 * @return field geometry type.
342
 *
343
 */
344
345
/************************************************************************/
346
/*                          OGR_GFld_GetType()                          */
347
/************************************************************************/
348
/**
349
 * \brief Fetch geometry type of this field.
350
 *
351
 * This function is the same as the CPP method OGRGeomFieldDefn::GetType().
352
 *
353
 * @param hDefn handle to the geometry field definition to get type from.
354
 * @return field geometry type.
355
 *
356
 */
357
358
OGRwkbGeometryType OGR_GFld_GetType(OGRGeomFieldDefnH hDefn)
359
360
0
{
361
0
    VALIDATE_POINTER1(hDefn, "OGR_GFld_GetType", wkbUnknown);
362
363
0
#ifdef OGRAPISPY_ENABLED
364
0
    if (bOGRAPISpyEnabled)
365
0
        OGRAPISpy_GFld_GetXXXX(hDefn, "GetType");
366
0
#endif
367
368
0
    OGRwkbGeometryType eType = OGRGeomFieldDefn::FromHandle(hDefn)->GetType();
369
0
    if (OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag())
370
0
    {
371
0
        eType = OGR_GT_GetLinear(eType);
372
0
    }
373
0
    return eType;
374
0
}
375
376
/************************************************************************/
377
/*                              SetType()                               */
378
/************************************************************************/
379
380
/**
381
 * \brief Set the geometry type of this field.
382
 * This should never be done to an OGRGeomFieldDefn
383
 * that is already part of an OGRFeatureDefn.
384
 *
385
 * This method is the same as the C function OGR_GFld_SetType().
386
 *
387
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
388
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
389
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
390
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
391
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
392
 *
393
 * @param eTypeIn the new field geometry type.
394
 *
395
 */
396
397
void OGRGeomFieldDefn::SetType(OGRwkbGeometryType eTypeIn)
398
399
0
{
400
0
    if (m_bSealed)
401
0
    {
402
0
        CPLError(CE_Failure, CPLE_AppDefined,
403
0
                 "OGRGeomFieldDefn::SetType() not allowed on a sealed object");
404
0
        return;
405
0
    }
406
0
    eGeomType = eTypeIn;
407
0
}
408
409
/************************************************************************/
410
/*                          OGR_GFld_SetType()                          */
411
/************************************************************************/
412
/**
413
 * \brief Set the geometry type of this field.
414
 * This should never be done to an OGRGeomFieldDefn
415
 * that is already part of an OGRFeatureDefn.
416
 *
417
 * This function is the same as the CPP method OGRGeomFieldDefn::SetType().
418
 *
419
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
420
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
421
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
422
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
423
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
424
 *
425
 * @param hDefn handle to the geometry field definition to set type to.
426
 * @param eType the new field geometry type.
427
 *
428
 */
429
430
void OGR_GFld_SetType(OGRGeomFieldDefnH hDefn, OGRwkbGeometryType eType)
431
432
0
{
433
0
    VALIDATE_POINTER0(hDefn, "OGR_GFld_SetType");
434
435
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetType(eType);
436
0
}
437
438
/************************************************************************/
439
/*                             IsIgnored()                              */
440
/************************************************************************/
441
442
/**
443
 * \fn int OGRGeomFieldDefn::IsIgnored() const;
444
 *
445
 * \brief Return whether this field should be omitted when fetching features
446
 *
447
 * This method is the same as the C function OGR_GFld_IsIgnored().
448
 *
449
 * @return ignore state
450
 *
451
 */
452
453
/************************************************************************/
454
/*                         OGR_GFld_IsIgnored()                         */
455
/************************************************************************/
456
457
/**
458
 * \brief Return whether this field should be omitted when fetching features
459
 *
460
 * This method is the same as the C++ method OGRGeomFieldDefn::IsIgnored().
461
 *
462
 * @param hDefn handle to the geometry field definition
463
 * @return ignore state
464
 *
465
 */
466
467
int OGR_GFld_IsIgnored(OGRGeomFieldDefnH hDefn)
468
0
{
469
0
    VALIDATE_POINTER1(hDefn, "OGR_GFld_IsIgnored", FALSE);
470
471
0
    return OGRGeomFieldDefn::FromHandle(hDefn)->IsIgnored();
472
0
}
473
474
/************************************************************************/
475
/*                             SetIgnored()                             */
476
/************************************************************************/
477
478
/**
479
 * \fn void OGRGeomFieldDefn::SetIgnored( int ignore );
480
 *
481
 * \brief Set whether this field should be omitted when fetching features
482
 *
483
 * This method is the same as the C function OGR_GFld_SetIgnored().
484
 *
485
 * This method should not be called on a object returned with
486
 * OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead, the
487
 * OGRLayer::SetIgnoredFields() method should be called.
488
 *
489
 * @param ignore ignore state
490
 *
491
 */
492
493
/************************************************************************/
494
/*                        OGR_GFld_SetIgnored()                         */
495
/************************************************************************/
496
497
/**
498
 * \brief Set whether this field should be omitted when fetching features
499
 *
500
 * This method is the same as the C++ method OGRGeomFieldDefn::SetIgnored().
501
 *
502
 * This method should not be called on a object returned with
503
 * OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead, the
504
 * OGRLayer::SetIgnoredFields() method should be called.
505
 *
506
 * @param hDefn handle to the geometry field definition
507
 * @param ignore ignore state
508
 *
509
 */
510
511
void OGR_GFld_SetIgnored(OGRGeomFieldDefnH hDefn, int ignore)
512
0
{
513
0
    VALIDATE_POINTER0(hDefn, "OGR_GFld_SetIgnored");
514
515
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetIgnored(ignore);
516
0
}
517
518
/************************************************************************/
519
/*                           GetSpatialRef()                            */
520
/************************************************************************/
521
/**
522
 * \brief Fetch spatial reference system of this field.
523
 *
524
 * This method is the same as the C function OGR_GFld_GetSpatialRef().
525
 *
526
 * @return field spatial reference system.
527
 *
528
 */
529
530
const OGRSpatialReference *OGRGeomFieldDefn::GetSpatialRef() const
531
0
{
532
0
    return poSRS;
533
0
}
534
535
/************************************************************************/
536
/*                       OGR_GFld_GetSpatialRef()                       */
537
/************************************************************************/
538
539
/**
540
 * \brief Fetch spatial reference system of this field.
541
 *
542
 * This function is the same as the C++ method
543
 * OGRGeomFieldDefn::GetSpatialRef().
544
 *
545
 * @param hDefn handle to the geometry field definition
546
 *
547
 * @return a reference to the field spatial reference system.
548
 * It should not be modified.
549
 *
550
 */
551
552
OGRSpatialReferenceH OGR_GFld_GetSpatialRef(OGRGeomFieldDefnH hDefn)
553
0
{
554
0
    VALIDATE_POINTER1(hDefn, "OGR_GFld_GetSpatialRef", nullptr);
555
556
0
#ifdef OGRAPISPY_ENABLED
557
0
    if (bOGRAPISpyEnabled)
558
0
        OGRAPISpy_GFld_GetXXXX(hDefn, "GetSpatialRef");
559
0
#endif
560
561
0
    return OGRSpatialReference::ToHandle(const_cast<OGRSpatialReference *>(
562
0
        OGRGeomFieldDefn::FromHandle(hDefn)->GetSpatialRef()));
563
0
}
564
565
/************************************************************************/
566
/*                           SetSpatialRef()                            */
567
/************************************************************************/
568
569
/**
570
 * \brief Set the spatial reference of this field.
571
 *
572
 * This method is the same as the C function OGR_GFld_SetSpatialRef().
573
 *
574
 * This method drops the reference of the previously set SRS object and
575
 * acquires a new reference on the passed object (if non-NULL).
576
 *
577
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
578
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
579
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
580
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
581
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
582
 *
583
 * @param poSRSIn the new SRS to apply.
584
 *
585
 */
586
void OGRGeomFieldDefn::SetSpatialRef(const OGRSpatialReference *poSRSIn)
587
0
{
588
589
0
    if (m_bSealed)
590
0
    {
591
0
        CPLError(
592
0
            CE_Failure, CPLE_AppDefined,
593
0
            "OGRGeomFieldDefn::SetSpatialRef() not allowed on a sealed object");
594
0
        return;
595
0
    }
596
597
0
    if (poSRS == poSRSIn)
598
0
    {
599
0
        return;
600
0
    }
601
602
0
    if (poSRS != nullptr)
603
0
        const_cast<OGRSpatialReference *>(poSRS)->Release();
604
605
0
    poSRS = poSRSIn;
606
607
0
    if (poSRS != nullptr)
608
0
        const_cast<OGRSpatialReference *>(poSRS)->Reference();
609
0
}
610
611
/************************************************************************/
612
/*                       OGR_GFld_SetSpatialRef()                       */
613
/************************************************************************/
614
615
/**
616
 * \brief Set the spatial reference of this field.
617
 *
618
 * This function is the same as the C++ method
619
 * OGRGeomFieldDefn::SetSpatialRef().
620
 *
621
 * This function drops the reference of the previously set SRS object and
622
 * acquires a new reference on the passed object (if non-NULL).
623
 *
624
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
625
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
626
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
627
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
628
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
629
 *
630
 * @param hDefn handle to the geometry field definition
631
 * @param hSRS the new SRS to apply.
632
 *
633
 */
634
635
void OGR_GFld_SetSpatialRef(OGRGeomFieldDefnH hDefn, OGRSpatialReferenceH hSRS)
636
0
{
637
0
    VALIDATE_POINTER0(hDefn, "OGR_GFld_SetSpatialRef");
638
639
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetSpatialRef(
640
0
        reinterpret_cast<OGRSpatialReference *>(hSRS));
641
0
}
642
643
/************************************************************************/
644
/*                               IsSame()                               */
645
/************************************************************************/
646
647
/**
648
 * \brief Test if the geometry field definition is identical to the other one.
649
 *
650
 * @param poOtherFieldDefn the other field definition to compare to.
651
 * @return TRUE if the geometry field definition is identical to the other one.
652
 *
653
 */
654
655
int OGRGeomFieldDefn::IsSame(const OGRGeomFieldDefn *poOtherFieldDefn) const
656
0
{
657
0
    if (!(strcmp(GetNameRef(), poOtherFieldDefn->GetNameRef()) == 0 &&
658
0
          GetType() == poOtherFieldDefn->GetType() &&
659
0
          IsNullable() == poOtherFieldDefn->IsNullable() &&
660
0
          m_oCoordPrecision.dfXYResolution ==
661
0
              poOtherFieldDefn->m_oCoordPrecision.dfXYResolution &&
662
0
          m_oCoordPrecision.dfZResolution ==
663
0
              poOtherFieldDefn->m_oCoordPrecision.dfZResolution &&
664
0
          m_oCoordPrecision.dfMResolution ==
665
0
              poOtherFieldDefn->m_oCoordPrecision.dfMResolution))
666
0
        return FALSE;
667
0
    const OGRSpatialReference *poMySRS = GetSpatialRef();
668
0
    const OGRSpatialReference *poOtherSRS = poOtherFieldDefn->GetSpatialRef();
669
0
    return ((poMySRS == poOtherSRS) ||
670
0
            (poMySRS != nullptr && poOtherSRS != nullptr &&
671
0
             poMySRS->IsSame(poOtherSRS)));
672
0
}
673
674
/************************************************************************/
675
/*                             IsNullable()                             */
676
/************************************************************************/
677
678
/**
679
 * \fn int OGRGeomFieldDefn::IsNullable() const
680
 *
681
 * \brief Return whether this geometry field can receive null values.
682
 *
683
 * By default, fields are nullable.
684
 *
685
 * Even if this method returns FALSE (i.e not-nullable field), it doesn't mean
686
 * that OGRFeature::IsFieldSet() will necessary return TRUE, as fields can be
687
 * temporary unset and null/not-null validation is usually done when
688
 * OGRLayer::CreateFeature()/SetFeature() is called.
689
 *
690
 * Note that not-nullable geometry fields might also contain 'empty' geometries.
691
 *
692
 * This method is the same as the C function OGR_GFld_IsNullable().
693
 *
694
 * @return TRUE if the field is authorized to be null.
695
 */
696
697
/************************************************************************/
698
/*                        OGR_GFld_IsNullable()                         */
699
/************************************************************************/
700
701
/**
702
 * \brief Return whether this geometry field can receive null values.
703
 *
704
 * By default, fields are nullable.
705
 *
706
 * Even if this method returns FALSE (i.e not-nullable field), it doesn't mean
707
 * that OGRFeature::IsFieldSet() will necessary return TRUE, as fields can be
708
 * temporary unset and null/not-null validation is usually done when
709
 * OGRLayer::CreateFeature()/SetFeature() is called.
710
 *
711
 * Note that not-nullable geometry fields might also contain 'empty' geometries.
712
 *
713
 * This method is the same as the C++ method OGRGeomFieldDefn::IsNullable().
714
 *
715
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
716
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
717
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
718
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
719
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
720
 *
721
 * @param hDefn handle to the field definition
722
 * @return TRUE if the field is authorized to be null.
723
 */
724
725
int OGR_GFld_IsNullable(OGRGeomFieldDefnH hDefn)
726
0
{
727
0
    return OGRGeomFieldDefn::FromHandle(hDefn)->IsNullable();
728
0
}
729
730
/************************************************************************/
731
/*                            SetNullable()                             */
732
/************************************************************************/
733
734
/**
735
 * \fn void OGRGeomFieldDefn::SetNullable( int bNullableIn );
736
 *
737
 * \brief Set whether this geometry field can receive null values.
738
 *
739
 * By default, fields are nullable, so this method is generally called with
740
 * FALSE to set a not-null constraint.
741
 *
742
 * Drivers that support writing not-null constraint will advertise the
743
 * GDAL_DCAP_NOTNULL_GEOMFIELDS driver metadata item.
744
 *
745
 * This method is the same as the C function OGR_GFld_SetNullable().
746
 *
747
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
748
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
749
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn(). Instead,
750
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
751
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
752
 *
753
 * @param bNullableIn FALSE if the field must have a not-null constraint.
754
 */
755
void OGRGeomFieldDefn::SetNullable(int bNullableIn)
756
0
{
757
0
    if (m_bSealed)
758
0
    {
759
0
        CPLError(
760
0
            CE_Failure, CPLE_AppDefined,
761
0
            "OGRGeomFieldDefn::SetNullable() not allowed on a sealed object");
762
0
        return;
763
0
    }
764
0
    bNullable = bNullableIn;
765
0
}
766
767
/************************************************************************/
768
/*                        OGR_GFld_SetNullable()                        */
769
/************************************************************************/
770
771
/**
772
 * \brief Set whether this geometry field can receive null values.
773
 *
774
 * By default, fields are nullable, so this method is generally called with
775
 * FALSE to set a not-null constraint.
776
 *
777
 * Drivers that support writing not-null constraint will advertise the
778
 * GDAL_DCAP_NOTNULL_GEOMFIELDS driver metadata item.
779
 *
780
 * This method is the same as the C++ method OGRGeomFieldDefn::SetNullable().
781
 *
782
 * @param hDefn handle to the field definition
783
 * @param bNullableIn FALSE if the field must have a not-null constraint.
784
 */
785
786
void OGR_GFld_SetNullable(OGRGeomFieldDefnH hDefn, int bNullableIn)
787
0
{
788
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetNullable(bNullableIn);
789
0
}
790
791
/************************************************************************/
792
/*                       GetCoordinatePrecision()                       */
793
/************************************************************************/
794
795
/**
796
 * \fn int OGRGeomFieldDefn::GetCoordinatePrecision() const
797
 *
798
 * \brief Return the coordinate precision associated to this geometry field.
799
 *
800
 * This method is the same as the C function OGR_GFld_GetCoordinatePrecision().
801
 *
802
 * @return the coordinate precision
803
 * @since GDAL 3.9
804
 */
805
806
/************************************************************************/
807
/*                  OGR_GFld_GetCoordinatePrecision()                   */
808
/************************************************************************/
809
810
/**
811
 * \brief Return the coordinate precision associated to this geometry field.
812
 *
813
 * This method is the same as the C++ method OGRGeomFieldDefn::GetCoordinatePrecision()
814
 *
815
 * @param hDefn handle to the field definition
816
 * @return the coordinate precision
817
 * @since GDAL 3.9
818
 */
819
820
OGRGeomCoordinatePrecisionH
821
OGR_GFld_GetCoordinatePrecision(OGRGeomFieldDefnH hDefn)
822
0
{
823
0
    return const_cast<OGRGeomCoordinatePrecision *>(
824
0
        &(OGRGeomFieldDefn::FromHandle(hDefn)->GetCoordinatePrecision()));
825
0
}
826
827
/************************************************************************/
828
/*                       SetCoordinatePrecision()                       */
829
/************************************************************************/
830
831
/**
832
 * \brief Set coordinate precision associated to this geometry field.
833
 *
834
 * This method is the same as the C function OGR_GFld_SetCoordinatePrecision().
835
 *
836
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
837
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
838
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn().
839
 *
840
 * @param prec Coordinate precision
841
 * @since GDAL 3.9
842
 */
843
void OGRGeomFieldDefn::SetCoordinatePrecision(
844
    const OGRGeomCoordinatePrecision &prec)
845
0
{
846
0
    if (m_bSealed)
847
0
    {
848
0
        CPLError(CE_Failure, CPLE_AppDefined,
849
0
                 "OGRGeomFieldDefn::SetCoordinatePrecision() not allowed on a "
850
0
                 "sealed object");
851
0
        return;
852
0
    }
853
0
    m_oCoordPrecision = prec;
854
0
}
855
856
/************************************************************************/
857
/*                  OGR_GFld_SetCoordinatePrecision()                   */
858
/************************************************************************/
859
860
/**
861
 * \brief Set coordinate precision associated to this geometry field.
862
 *
863
 * This method is the same as the C++ method OGRGeomFieldDefn::SetCoordinatePrecision()
864
 *
865
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
866
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
867
 * object returned with OGRLayer::GetLayerDefn() const->GetGeomFieldDefn().
868
 *
869
 * @param hDefn handle to the field definition.  Must not be NULL.
870
 * @param hGeomCoordPrec Coordinate precision. Must not be NULL.
871
 * @since GDAL 3.9
872
 */
873
void OGR_GFld_SetCoordinatePrecision(OGRGeomFieldDefnH hDefn,
874
                                     OGRGeomCoordinatePrecisionH hGeomCoordPrec)
875
0
{
876
0
    VALIDATE_POINTER0(hGeomCoordPrec, "OGR_GFld_SetCoordinatePrecision");
877
0
    OGRGeomFieldDefn::FromHandle(hDefn)->SetCoordinatePrecision(
878
0
        *hGeomCoordPrec);
879
0
}
880
881
/************************************************************************/
882
/*                       OGRGeomFieldDefn::Seal()                       */
883
/************************************************************************/
884
885
/** Seal a OGRGeomFieldDefn.
886
 *
887
 * A sealed OGRGeomFieldDefn can not be modified while it is sealed.
888
 *
889
 * This method should only be called by driver implementations.
890
 *
891
 * @since GDAL 3.9
892
 */
893
void OGRGeomFieldDefn::Seal()
894
0
{
895
0
    m_bSealed = true;
896
0
}
897
898
/************************************************************************/
899
/*                      OGRGeomFieldDefn::Unseal()                      */
900
/************************************************************************/
901
902
/** Unseal a OGRGeomFieldDefn.
903
 *
904
 * Undo OGRGeomFieldDefn::Seal()
905
 *
906
 * Using GetTemporaryUnsealer() is recommended for most use cases.
907
 *
908
 * This method should only be called by driver implementations.
909
 *
910
 * @since GDAL 3.9
911
 */
912
void OGRGeomFieldDefn::Unseal()
913
0
{
914
0
    m_bSealed = false;
915
0
}
916
917
/************************************************************************/
918
/*               OGRGeomFieldDefn::GetTemporaryUnsealer()               */
919
/************************************************************************/
920
921
/** Return an object that temporary unseals the OGRGeomFieldDefn
922
 *
923
 * The returned object calls Unseal() initially, and when it is destroyed
924
 * it calls Seal().
925
 *
926
 * This method should only be called by driver implementations.
927
 *
928
 * It is also possible to use the helper method whileUnsealing(). Example:
929
 * whileUnsealing(poGeomFieldDefn)->some_method()
930
 *
931
 * @since GDAL 3.9
932
 */
933
OGRGeomFieldDefn::TemporaryUnsealer OGRGeomFieldDefn::GetTemporaryUnsealer()
934
0
{
935
0
    return TemporaryUnsealer(this);
936
0
}