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