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 120604 : OGRGeomFieldDefn::OGRGeomFieldDefn(const char *pszNameIn,
40 120604 : OGRwkbGeometryType eGeomTypeIn)
41 :
42 : {
43 120604 : Initialize(pszNameIn, eGeomTypeIn);
44 120604 : }
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 17686 : OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn *poPrototype)
60 17686 : : OGRGeomFieldDefn(*poPrototype)
61 :
62 : {
63 17686 : }
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 194 : OGRGeomFieldDefnH OGR_GFld_Create(const char *pszName, OGRwkbGeometryType eType)
81 :
82 : {
83 194 : return OGRGeomFieldDefn::ToHandle(new OGRGeomFieldDefn(pszName, eType));
84 : }
85 :
86 : /************************************************************************/
87 : /* Initialize() */
88 : /************************************************************************/
89 :
90 : //! @cond Doxygen_Suppress
91 120604 : void OGRGeomFieldDefn::Initialize(const char *pszNameIn,
92 : OGRwkbGeometryType eTypeIn)
93 :
94 : {
95 120604 : pszName = CPLStrdup(pszNameIn);
96 120604 : eGeomType = eTypeIn;
97 120604 : }
98 :
99 : //! @endcond
100 :
101 : /************************************************************************/
102 : /* ~OGRGeomFieldDefn() */
103 : /************************************************************************/
104 :
105 222980 : OGRGeomFieldDefn::~OGRGeomFieldDefn()
106 :
107 : {
108 138500 : CPLFree(pszName);
109 :
110 138500 : if (nullptr != poSRS)
111 28060 : const_cast<OGRSpatialReference *>(poSRS)->Release();
112 222980 : }
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 17919 : OGRGeomFieldDefn::OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther)
124 35838 : : pszName(CPLStrdup(oOther.pszName)), eGeomType(oOther.eGeomType),
125 17919 : poSRS(nullptr), bIgnore(oOther.bIgnore), bNullable(oOther.bNullable),
126 17919 : m_bSealed(false), m_oCoordPrecision(oOther.m_oCoordPrecision)
127 : {
128 17919 : if (auto poSrcSRS = oOther.GetSpatialRef())
129 : {
130 4127 : poSRS = poSrcSRS->Clone();
131 : }
132 17919 : }
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 0 : 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 : {
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 3 : OGRGeomFieldDefn &OGRGeomFieldDefn::operator=(const OGRGeomFieldDefn &oOther)
163 : {
164 3 : if (&oOther != this)
165 : {
166 3 : CPLFree(pszName);
167 3 : pszName = CPLStrdup(oOther.pszName);
168 3 : eGeomType = oOther.eGeomType;
169 3 : if (oOther.poSRS)
170 2 : const_cast<OGRSpatialReference *>(oOther.poSRS)->Reference();
171 3 : if (poSRS)
172 1 : const_cast<OGRSpatialReference *>(poSRS)->Dereference();
173 3 : poSRS = oOther.poSRS;
174 3 : bNullable = oOther.bNullable;
175 3 : m_oCoordPrecision = oOther.m_oCoordPrecision;
176 3 : m_bSealed = oOther.m_bSealed;
177 3 : bIgnore = oOther.bIgnore;
178 : }
179 3 : return *this;
180 : }
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 0 : OGRGeomFieldDefn &OGRGeomFieldDefn::operator=(OGRGeomFieldDefn &&oOther)
193 : {
194 0 : if (&oOther != this)
195 : {
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 : }
204 0 : return *this;
205 : }
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 194 : void OGR_GFld_Destroy(OGRGeomFieldDefnH hDefn)
218 :
219 : {
220 194 : VALIDATE_POINTER0(hDefn, "OGR_GFld_Destroy");
221 :
222 194 : delete OGRGeomFieldDefn::FromHandle(hDefn);
223 : }
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 3565 : void OGRGeomFieldDefn::SetName(const char *pszNameIn)
245 :
246 : {
247 3565 : if (m_bSealed)
248 : {
249 5 : CPLError(CE_Failure, CPLE_AppDefined,
250 : "OGRGeomFieldDefn::SetName() not allowed on a sealed object");
251 5 : return;
252 : }
253 3560 : if (pszName != pszNameIn)
254 : {
255 3560 : CPLFree(pszName);
256 3560 : pszName = CPLStrdup(pszNameIn);
257 : }
258 : }
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 4 : void OGR_GFld_SetName(OGRGeomFieldDefnH hDefn, const char *pszName)
281 :
282 : {
283 4 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetName");
284 :
285 4 : OGRGeomFieldDefn::FromHandle(hDefn)->SetName(pszName);
286 : }
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 367 : const char *OGR_GFld_GetNameRef(OGRGeomFieldDefnH hDefn)
318 :
319 : {
320 367 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetNameRef", "");
321 :
322 : #ifdef OGRAPISPY_ENABLED
323 367 : if (bOGRAPISpyEnabled)
324 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetNameRef");
325 : #endif
326 :
327 367 : return OGRGeomFieldDefn::FromHandle(hDefn)->GetNameRef();
328 : }
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 105 : OGRwkbGeometryType OGR_GFld_GetType(OGRGeomFieldDefnH hDefn)
359 :
360 : {
361 105 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetType", wkbUnknown);
362 :
363 : #ifdef OGRAPISPY_ENABLED
364 105 : if (bOGRAPISpyEnabled)
365 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetType");
366 : #endif
367 :
368 105 : OGRwkbGeometryType eType = OGRGeomFieldDefn::FromHandle(hDefn)->GetType();
369 105 : if (OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag())
370 : {
371 1 : eType = OGR_GT_GetLinear(eType);
372 : }
373 105 : return eType;
374 : }
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 25073 : void OGRGeomFieldDefn::SetType(OGRwkbGeometryType eTypeIn)
398 :
399 : {
400 25073 : if (m_bSealed)
401 : {
402 1 : CPLError(CE_Failure, CPLE_AppDefined,
403 : "OGRGeomFieldDefn::SetType() not allowed on a sealed object");
404 1 : return;
405 : }
406 25072 : eGeomType = eTypeIn;
407 : }
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 1 : void OGR_GFld_SetType(OGRGeomFieldDefnH hDefn, OGRwkbGeometryType eType)
431 :
432 : {
433 1 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetType");
434 :
435 1 : OGRGeomFieldDefn::FromHandle(hDefn)->SetType(eType);
436 : }
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 6 : int OGR_GFld_IsIgnored(OGRGeomFieldDefnH hDefn)
468 : {
469 6 : VALIDATE_POINTER1(hDefn, "OGR_GFld_IsIgnored", FALSE);
470 :
471 6 : return OGRGeomFieldDefn::FromHandle(hDefn)->IsIgnored();
472 : }
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 1 : void OGR_GFld_SetIgnored(OGRGeomFieldDefnH hDefn, int ignore)
512 : {
513 1 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetIgnored");
514 :
515 1 : OGRGeomFieldDefn::FromHandle(hDefn)->SetIgnored(ignore);
516 : }
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 468636 : const OGRSpatialReference *OGRGeomFieldDefn::GetSpatialRef() const
531 : {
532 468636 : return poSRS;
533 : }
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 85 : OGRSpatialReferenceH OGR_GFld_GetSpatialRef(OGRGeomFieldDefnH hDefn)
553 : {
554 85 : VALIDATE_POINTER1(hDefn, "OGR_GFld_GetSpatialRef", nullptr);
555 :
556 : #ifdef OGRAPISPY_ENABLED
557 85 : if (bOGRAPISpyEnabled)
558 2 : OGRAPISpy_GFld_GetXXXX(hDefn, "GetSpatialRef");
559 : #endif
560 :
561 85 : return OGRSpatialReference::ToHandle(const_cast<OGRSpatialReference *>(
562 85 : OGRGeomFieldDefn::FromHandle(hDefn)->GetSpatialRef()));
563 : }
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 39779 : void OGRGeomFieldDefn::SetSpatialRef(const OGRSpatialReference *poSRSIn)
587 : {
588 :
589 39779 : if (m_bSealed)
590 : {
591 1 : CPLError(
592 : CE_Failure, CPLE_AppDefined,
593 : "OGRGeomFieldDefn::SetSpatialRef() not allowed on a sealed object");
594 1 : return;
595 : }
596 :
597 39778 : if (poSRS == poSRSIn)
598 : {
599 16773 : return;
600 : }
601 :
602 23005 : if (poSRS != nullptr)
603 182 : const_cast<OGRSpatialReference *>(poSRS)->Release();
604 :
605 23005 : poSRS = poSRSIn;
606 :
607 23005 : if (poSRS != nullptr)
608 22994 : const_cast<OGRSpatialReference *>(poSRS)->Reference();
609 : }
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 50 : void OGR_GFld_SetSpatialRef(OGRGeomFieldDefnH hDefn, OGRSpatialReferenceH hSRS)
636 : {
637 50 : VALIDATE_POINTER0(hDefn, "OGR_GFld_SetSpatialRef");
638 :
639 50 : OGRGeomFieldDefn::FromHandle(hDefn)->SetSpatialRef(
640 : reinterpret_cast<OGRSpatialReference *>(hSRS));
641 : }
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 378 : int OGRGeomFieldDefn::IsSame(const OGRGeomFieldDefn *poOtherFieldDefn) const
656 : {
657 1116 : if (!(strcmp(GetNameRef(), poOtherFieldDefn->GetNameRef()) == 0 &&
658 738 : GetType() == poOtherFieldDefn->GetType() &&
659 360 : IsNullable() == poOtherFieldDefn->IsNullable() &&
660 360 : m_oCoordPrecision.dfXYResolution ==
661 360 : poOtherFieldDefn->m_oCoordPrecision.dfXYResolution &&
662 358 : m_oCoordPrecision.dfZResolution ==
663 358 : poOtherFieldDefn->m_oCoordPrecision.dfZResolution &&
664 357 : m_oCoordPrecision.dfMResolution ==
665 357 : poOtherFieldDefn->m_oCoordPrecision.dfMResolution))
666 22 : return FALSE;
667 356 : const OGRSpatialReference *poMySRS = GetSpatialRef();
668 356 : const OGRSpatialReference *poOtherSRS = poOtherFieldDefn->GetSpatialRef();
669 633 : return ((poMySRS == poOtherSRS) ||
670 277 : (poMySRS != nullptr && poOtherSRS != nullptr &&
671 632 : poMySRS->IsSame(poOtherSRS)));
672 : }
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 85 : int OGR_GFld_IsNullable(OGRGeomFieldDefnH hDefn)
726 : {
727 85 : return OGRGeomFieldDefn::FromHandle(hDefn)->IsNullable();
728 : }
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 9131 : void OGRGeomFieldDefn::SetNullable(int bNullableIn)
756 : {
757 9131 : if (m_bSealed)
758 : {
759 1 : CPLError(
760 : CE_Failure, CPLE_AppDefined,
761 : "OGRGeomFieldDefn::SetNullable() not allowed on a sealed object");
762 1 : return;
763 : }
764 9130 : bNullable = bNullableIn;
765 : }
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 23 : void OGR_GFld_SetNullable(OGRGeomFieldDefnH hDefn, int bNullableIn)
787 : {
788 23 : OGRGeomFieldDefn::FromHandle(hDefn)->SetNullable(bNullableIn);
789 23 : }
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 42 : OGR_GFld_GetCoordinatePrecision(OGRGeomFieldDefnH hDefn)
822 : {
823 : return const_cast<OGRGeomCoordinatePrecision *>(
824 42 : &(OGRGeomFieldDefn::FromHandle(hDefn)->GetCoordinatePrecision()));
825 : }
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 6347 : void OGRGeomFieldDefn::SetCoordinatePrecision(
844 : const OGRGeomCoordinatePrecision &prec)
845 : {
846 6347 : if (m_bSealed)
847 : {
848 0 : CPLError(CE_Failure, CPLE_AppDefined,
849 : "OGRGeomFieldDefn::SetCoordinatePrecision() not allowed on a "
850 : "sealed object");
851 0 : return;
852 : }
853 6347 : m_oCoordPrecision = prec;
854 : }
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 18 : void OGR_GFld_SetCoordinatePrecision(OGRGeomFieldDefnH hDefn,
874 : OGRGeomCoordinatePrecisionH hGeomCoordPrec)
875 : {
876 18 : VALIDATE_POINTER0(hGeomCoordPrec, "OGR_GFld_SetCoordinatePrecision");
877 18 : OGRGeomFieldDefn::FromHandle(hDefn)->SetCoordinatePrecision(
878 : *hGeomCoordPrec);
879 : }
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 36229 : void OGRGeomFieldDefn::Seal()
894 : {
895 36229 : m_bSealed = true;
896 36229 : }
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 20754 : void OGRGeomFieldDefn::Unseal()
913 : {
914 20754 : m_bSealed = false;
915 20754 : }
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 668 : OGRGeomFieldDefn::TemporaryUnsealer OGRGeomFieldDefn::GetTemporaryUnsealer()
934 : {
935 668 : return TemporaryUnsealer(this);
936 : }
|