Line data Source code
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 119279 : OGRGeomFieldDefn::OGRGeomFieldDefn(const char *pszNameIn,
40 119279 : OGRwkbGeometryType eGeomTypeIn)
41 :
42 : {
43 119279 : Initialize(pszNameIn, eGeomTypeIn);
44 119279 : }
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 17079 : OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn *poPrototype)
60 :
61 : {
62 17079 : Initialize(poPrototype->GetNameRef(), poPrototype->GetType());
63 17079 : const OGRSpatialReference *poSRSSrc = poPrototype->GetSpatialRef();
64 17079 : if (poSRSSrc)
65 : {
66 4011 : OGRSpatialReference *l_poSRS = poSRSSrc->Clone();
67 4011 : SetSpatialRef(l_poSRS);
68 4011 : l_poSRS->Release();
69 : }
70 17079 : SetNullable(poPrototype->IsNullable());
71 17079 : SetCoordinatePrecision(poPrototype->GetCoordinatePrecision());
72 17079 : }
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 191 : OGRGeomFieldDefnH OGR_GFld_Create(const char *pszName, OGRwkbGeometryType eType)
90 :
91 : {
92 191 : return OGRGeomFieldDefn::ToHandle(new OGRGeomFieldDefn(pszName, eType));
93 : }
94 :
95 : /************************************************************************/
96 : /* Initialize() */
97 : /************************************************************************/
98 :
99 : //! @cond Doxygen_Suppress
100 136358 : void OGRGeomFieldDefn::Initialize(const char *pszNameIn,
101 : OGRwkbGeometryType eTypeIn)
102 :
103 : {
104 136358 : pszName = CPLStrdup(pszNameIn);
105 136358 : eGeomType = eTypeIn;
106 136358 : }
107 :
108 : //! @endcond
109 :
110 : /************************************************************************/
111 : /* ~OGRGeomFieldDefn() */
112 : /************************************************************************/
113 :
114 219549 : OGRGeomFieldDefn::~OGRGeomFieldDefn()
115 :
116 : {
117 136348 : CPLFree(pszName);
118 :
119 136348 : if (nullptr != poSRS)
120 27883 : const_cast<OGRSpatialReference *>(poSRS)->Release();
121 219549 : }
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 13 : OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther)
133 26 : : pszName(CPLStrdup(oOther.pszName)), eGeomType(oOther.eGeomType),
134 13 : poSRS(nullptr), bIgnore(oOther.bIgnore), bNullable(oOther.bNullable),
135 13 : m_bSealed(oOther.m_bSealed), m_oCoordPrecision(oOther.m_oCoordPrecision)
136 : {
137 13 : if (oOther.poSRS)
138 : {
139 6 : poSRS = oOther.poSRS->Clone();
140 : }
141 13 : }
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 3 : OGRGeomFieldDefn &OGRGeomFieldDefn::operator=(const OGRGeomFieldDefn &oOther)
154 : {
155 3 : if (&oOther != this)
156 : {
157 3 : CPLFree(pszName);
158 3 : pszName = CPLStrdup(oOther.pszName);
159 3 : eGeomType = oOther.eGeomType;
160 3 : if (oOther.poSRS)
161 2 : const_cast<OGRSpatialReference *>(oOther.poSRS)->Reference();
162 3 : if (poSRS)
163 1 : const_cast<OGRSpatialReference *>(poSRS)->Dereference();
164 3 : poSRS = oOther.poSRS;
165 3 : bNullable = oOther.bNullable;
166 3 : m_oCoordPrecision = oOther.m_oCoordPrecision;
167 3 : m_bSealed = oOther.m_bSealed;
168 3 : bIgnore = oOther.bIgnore;
169 : }
170 3 : return *this;
171 : }
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 191 : void OGR_GFld_Destroy(OGRGeomFieldDefnH hDefn)
184 :
185 : {
186 191 : VALIDATE_POINTER0(hDefn, "OGR_GFld_Destroy");
187 :
188 191 : delete OGRGeomFieldDefn::FromHandle(hDefn);
189 : }
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 3444 : void OGRGeomFieldDefn::SetName(const char *pszNameIn)
211 :
212 : {
213 3444 : if (m_bSealed)
214 : {
215 5 : CPLError(CE_Failure, CPLE_AppDefined,
216 : "OGRGeomFieldDefn::SetName() not allowed on a sealed object");
217 5 : return;
218 : }
219 3439 : if (pszName != pszNameIn)
220 : {
221 3439 : CPLFree(pszName);
222 3439 : pszName = CPLStrdup(pszNameIn);
223 : }
224 : }
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 4 : void OGR_GFld_SetName(OGRGeomFieldDefnH hDefn, const char *pszName)
247 :
248 : {
249 4 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetName");
250 :
251 4 : OGRGeomFieldDefn::FromHandle(hDefn)->SetName(pszName);
252 : }
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 311 : const char *OGR_GFld_GetNameRef(OGRGeomFieldDefnH hDefn)
284 :
285 : {
286 311 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetNameRef", "");
287 :
288 : #ifdef OGRAPISPY_ENABLED
289 311 : if (bOGRAPISpyEnabled)
290 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetNameRef");
291 : #endif
292 :
293 311 : return OGRGeomFieldDefn::FromHandle(hDefn)->GetNameRef();
294 : }
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 101 : OGRwkbGeometryType OGR_GFld_GetType(OGRGeomFieldDefnH hDefn)
325 :
326 : {
327 101 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetType", wkbUnknown);
328 :
329 : #ifdef OGRAPISPY_ENABLED
330 101 : if (bOGRAPISpyEnabled)
331 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetType");
332 : #endif
333 :
334 101 : OGRwkbGeometryType eType = OGRGeomFieldDefn::FromHandle(hDefn)->GetType();
335 101 : if (OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag())
336 : {
337 1 : eType = OGR_GT_GetLinear(eType);
338 : }
339 101 : return eType;
340 : }
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 24589 : void OGRGeomFieldDefn::SetType(OGRwkbGeometryType eTypeIn)
364 :
365 : {
366 24589 : if (m_bSealed)
367 : {
368 1 : CPLError(CE_Failure, CPLE_AppDefined,
369 : "OGRGeomFieldDefn::SetType() not allowed on a sealed object");
370 1 : return;
371 : }
372 24588 : eGeomType = eTypeIn;
373 : }
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 1 : void OGR_GFld_SetType(OGRGeomFieldDefnH hDefn, OGRwkbGeometryType eType)
397 :
398 : {
399 1 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetType");
400 :
401 1 : OGRGeomFieldDefn::FromHandle(hDefn)->SetType(eType);
402 : }
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 6 : int OGR_GFld_IsIgnored(OGRGeomFieldDefnH hDefn)
434 : {
435 6 : VALIDATE_POINTER1(hDefn, "OGR_GFld_IsIgnored", FALSE);
436 :
437 6 : return OGRGeomFieldDefn::FromHandle(hDefn)->IsIgnored();
438 : }
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 1 : void OGR_GFld_SetIgnored(OGRGeomFieldDefnH hDefn, int ignore)
478 : {
479 1 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetIgnored");
480 :
481 1 : OGRGeomFieldDefn::FromHandle(hDefn)->SetIgnored(ignore);
482 : }
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 465299 : const OGRSpatialReference *OGRGeomFieldDefn::GetSpatialRef() const
497 : {
498 465299 : return poSRS;
499 : }
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 85 : OGRSpatialReferenceH OGR_GFld_GetSpatialRef(OGRGeomFieldDefnH hDefn)
519 : {
520 85 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetSpatialRef", nullptr);
521 :
522 : #ifdef OGRAPISPY_ENABLED
523 85 : if (bOGRAPISpyEnabled)
524 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetSpatialRef");
525 : #endif
526 :
527 85 : return OGRSpatialReference::ToHandle(const_cast<OGRSpatialReference *>(
528 85 : OGRGeomFieldDefn::FromHandle(hDefn)->GetSpatialRef()));
529 : }
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 43405 : void OGRGeomFieldDefn::SetSpatialRef(const OGRSpatialReference *poSRSIn)
553 : {
554 :
555 43405 : if (m_bSealed)
556 : {
557 1 : CPLError(
558 : CE_Failure, CPLE_AppDefined,
559 : "OGRGeomFieldDefn::SetSpatialRef() not allowed on a sealed object");
560 1 : return;
561 : }
562 :
563 43404 : if (poSRS == poSRSIn)
564 : {
565 16517 : return;
566 : }
567 :
568 26887 : if (poSRS != nullptr)
569 105 : const_cast<OGRSpatialReference *>(poSRS)->Release();
570 :
571 26887 : poSRS = poSRSIn;
572 :
573 26887 : if (poSRS != nullptr)
574 26876 : const_cast<OGRSpatialReference *>(poSRS)->Reference();
575 : }
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 50 : void OGR_GFld_SetSpatialRef(OGRGeomFieldDefnH hDefn, OGRSpatialReferenceH hSRS)
602 : {
603 50 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetSpatialRef");
604 :
605 50 : OGRGeomFieldDefn::FromHandle(hDefn)->SetSpatialRef(
606 : reinterpret_cast<OGRSpatialReference *>(hSRS));
607 : }
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 372 : int OGRGeomFieldDefn::IsSame(const OGRGeomFieldDefn *poOtherFieldDefn) const
622 : {
623 1098 : if (!(strcmp(GetNameRef(), poOtherFieldDefn->GetNameRef()) == 0 &&
624 726 : GetType() == poOtherFieldDefn->GetType() &&
625 354 : IsNullable() == poOtherFieldDefn->IsNullable() &&
626 354 : m_oCoordPrecision.dfXYResolution ==
627 354 : poOtherFieldDefn->m_oCoordPrecision.dfXYResolution &&
628 352 : m_oCoordPrecision.dfZResolution ==
629 352 : poOtherFieldDefn->m_oCoordPrecision.dfZResolution &&
630 351 : m_oCoordPrecision.dfMResolution ==
631 351 : poOtherFieldDefn->m_oCoordPrecision.dfMResolution))
632 22 : return FALSE;
633 350 : const OGRSpatialReference *poMySRS = GetSpatialRef();
634 350 : const OGRSpatialReference *poOtherSRS = poOtherFieldDefn->GetSpatialRef();
635 642 : return ((poMySRS == poOtherSRS) ||
636 292 : (poMySRS != nullptr && poOtherSRS != nullptr &&
637 641 : poMySRS->IsSame(poOtherSRS)));
638 : }
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 85 : int OGR_GFld_IsNullable(OGRGeomFieldDefnH hDefn)
692 : {
693 85 : return OGRGeomFieldDefn::FromHandle(hDefn)->IsNullable();
694 : }
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 25906 : void OGRGeomFieldDefn::SetNullable(int bNullableIn)
722 : {
723 25906 : if (m_bSealed)
724 : {
725 1 : CPLError(
726 : CE_Failure, CPLE_AppDefined,
727 : "OGRGeomFieldDefn::SetNullable() not allowed on a sealed object");
728 1 : return;
729 : }
730 25905 : bNullable = bNullableIn;
731 : }
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 23 : void OGR_GFld_SetNullable(OGRGeomFieldDefnH hDefn, int bNullableIn)
753 : {
754 23 : OGRGeomFieldDefn::FromHandle(hDefn)->SetNullable(bNullableIn);
755 23 : }
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 42 : OGR_GFld_GetCoordinatePrecision(OGRGeomFieldDefnH hDefn)
788 : {
789 : return const_cast<OGRGeomCoordinatePrecision *>(
790 42 : &(OGRGeomFieldDefn::FromHandle(hDefn)->GetCoordinatePrecision()));
791 : }
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 23370 : void OGRGeomFieldDefn::SetCoordinatePrecision(
810 : const OGRGeomCoordinatePrecision &prec)
811 : {
812 23370 : if (m_bSealed)
813 : {
814 0 : CPLError(CE_Failure, CPLE_AppDefined,
815 : "OGRGeomFieldDefn::SetCoordinatePrecision() not allowed on a "
816 : "sealed object");
817 0 : return;
818 : }
819 23370 : m_oCoordPrecision = prec;
820 : }
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 18 : void OGR_GFld_SetCoordinatePrecision(OGRGeomFieldDefnH hDefn,
840 : OGRGeomCoordinatePrecisionH hGeomCoordPrec)
841 : {
842 18 : VALIDATE_POINTER0(hGeomCoordPrec, "OGR_GFld_SetCoordinatePrecision");
843 18 : OGRGeomFieldDefn::FromHandle(hDefn)->SetCoordinatePrecision(
844 : *hGeomCoordPrec);
845 : }
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 35862 : void OGRGeomFieldDefn::Seal()
860 : {
861 35862 : m_bSealed = true;
862 35862 : }
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 20560 : void OGRGeomFieldDefn::Unseal()
879 : {
880 20560 : m_bSealed = false;
881 20560 : }
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 656 : OGRGeomFieldDefn::TemporaryUnsealer OGRGeomFieldDefn::GetTemporaryUnsealer()
900 : {
901 656 : return TemporaryUnsealer(this);
902 : }
|