Coverage Report

Created: 2025-11-16 06:25

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