Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: The OGRFeatureDefn class implementation.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
9 : * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "cpl_port.h"
15 : #include "ogr_feature.h"
16 :
17 : #include <algorithm>
18 : #include <cassert>
19 : #include <cstring>
20 :
21 : #include "cpl_conv.h"
22 : #include "cpl_error.h"
23 : #include "cpl_string.h"
24 : #include "ogr_api.h"
25 : #include "ogr_core.h"
26 : #include "ogr_p.h"
27 : #include "ograpispy.h"
28 :
29 : /************************************************************************/
30 : /* OGRFeatureDefn() */
31 : /************************************************************************/
32 :
33 : /**
34 : * \brief Constructor.
35 : *
36 : * The OGRFeatureDefn maintains a reference count, but this starts at
37 : * zero. It is mainly intended to represent a count of OGRFeature's
38 : * based on this definition.
39 : *
40 : * This method is the same as the C function OGR_FD_Create().
41 : *
42 : * @param pszName the name to be assigned to this layer/class. It does not
43 : * need to be unique.
44 : */
45 :
46 67794 : OGRFeatureDefn::OGRFeatureDefn(const char *pszName)
47 : {
48 67794 : pszFeatureClassName = CPLStrdup(pszName);
49 : apoGeomFieldDefn.emplace_back(
50 67794 : std::make_unique<OGRGeomFieldDefn>("", wkbUnknown));
51 67794 : }
52 :
53 : /************************************************************************/
54 : /* OGR_FD_Create() */
55 : /************************************************************************/
56 : /**
57 : * \brief Create a new feature definition object to hold the field definitions.
58 : *
59 : * The OGRFeatureDefn maintains a reference count, but this starts at
60 : * zero, and should normally be incremented by the owner.
61 : *
62 : * This function is the same as the C++ method
63 : * OGRFeatureDefn::OGRFeatureDefn().
64 : *
65 : * @param pszName the name to be assigned to this layer/class. It does not
66 : * need to be unique.
67 : * @return handle to the newly created feature definition.
68 : */
69 :
70 118 : OGRFeatureDefnH OGR_FD_Create(const char *pszName)
71 :
72 : {
73 118 : return OGRFeatureDefn::ToHandle(new OGRFeatureDefn(pszName));
74 : }
75 :
76 : /************************************************************************/
77 : /* ~OGRFeatureDefn() */
78 : /************************************************************************/
79 :
80 119642 : OGRFeatureDefn::~OGRFeatureDefn()
81 :
82 : {
83 67781 : if (nRefCount != 0)
84 : {
85 80 : CPLDebug("OGRFeatureDefn",
86 : "OGRFeatureDefn %s with a ref count of %d deleted!",
87 80 : pszFeatureClassName, nRefCount);
88 : }
89 :
90 67781 : CPLFree(pszFeatureClassName);
91 119642 : }
92 :
93 : /************************************************************************/
94 : /* OGR_FD_Destroy() */
95 : /************************************************************************/
96 : /**
97 : * \brief Destroy a feature definition object and release all memory associated
98 : * with it.
99 : *
100 : * This function is the same as the C++ method
101 : * OGRFeatureDefn::~OGRFeatureDefn().
102 : *
103 : * @param hDefn handle to the feature definition to be destroyed.
104 : */
105 :
106 0 : void OGR_FD_Destroy(OGRFeatureDefnH hDefn)
107 :
108 : {
109 0 : delete OGRFeatureDefn::FromHandle(hDefn);
110 0 : }
111 :
112 : /************************************************************************/
113 : /* Release() */
114 : /************************************************************************/
115 :
116 : /**
117 : * \fn void OGRFeatureDefn::Release();
118 : *
119 : * \brief Drop a reference to this object, and destroy if no longer referenced.
120 : */
121 :
122 2435740 : void OGRFeatureDefn::Release()
123 :
124 : {
125 2435740 : if (Dereference() <= 0)
126 67312 : delete this;
127 2435740 : }
128 :
129 : /************************************************************************/
130 : /* OGR_FD_Release() */
131 : /************************************************************************/
132 :
133 : /**
134 : * \brief Drop a reference, and destroy if unreferenced.
135 : *
136 : * This function is the same as the C++ method OGRFeatureDefn::Release().
137 : *
138 : * @param hDefn handle to the feature definition to be released.
139 : */
140 :
141 125470 : void OGR_FD_Release(OGRFeatureDefnH hDefn)
142 :
143 : {
144 125470 : OGRFeatureDefn::FromHandle(hDefn)->Release();
145 125470 : }
146 :
147 : /************************************************************************/
148 : /* Clone() */
149 : /************************************************************************/
150 :
151 : /**
152 : * \fn OGRFeatureDefn *OGRFeatureDefn::Clone() const;
153 : *
154 : * \brief Create a copy of this feature definition.
155 : *
156 : * Creates a deep copy of the feature definition.
157 : * The reference counter of the copy is initialized at 0.
158 : *
159 : * @return the copy.
160 : */
161 :
162 626 : OGRFeatureDefn *OGRFeatureDefn::Clone() const
163 :
164 : {
165 626 : OGRFeatureDefn *poCopy = new OGRFeatureDefn(GetName());
166 :
167 : {
168 626 : const int nFieldCount = GetFieldCount();
169 626 : poCopy->apoFieldDefn.reserve(nFieldCount);
170 3566 : for (int i = 0; i < nFieldCount; i++)
171 2940 : poCopy->AddFieldDefn(GetFieldDefn(i));
172 : }
173 :
174 : {
175 : // Remove the default geometry field created instantiation.
176 626 : poCopy->DeleteGeomFieldDefn(0);
177 626 : const int nGeomFieldCount = GetGeomFieldCount();
178 626 : poCopy->apoGeomFieldDefn.reserve(nGeomFieldCount);
179 978 : for (int i = 0; i < nGeomFieldCount; i++)
180 352 : poCopy->AddGeomFieldDefn(GetGeomFieldDefn(i));
181 : }
182 :
183 626 : return poCopy;
184 : }
185 :
186 : /************************************************************************/
187 : /* SetName() */
188 : /************************************************************************/
189 :
190 : /**
191 : * \brief Change name of this OGRFeatureDefn.
192 : *
193 : * To rename a layer, do not use this function directly, but use
194 : * OGRLayer::Rename() instead.
195 : *
196 : * @param pszName feature definition name
197 : * @since GDAL 2.3
198 : */
199 256 : void OGRFeatureDefn::SetName(const char *pszName)
200 : {
201 256 : if (m_bSealed)
202 : {
203 1 : CPLError(CE_Failure, CPLE_AppDefined,
204 : "OGRFeatureDefn::SetName() not allowed on a sealed object");
205 1 : return;
206 : }
207 255 : CPLFree(pszFeatureClassName);
208 255 : pszFeatureClassName = CPLStrdup(pszName);
209 : }
210 :
211 : /************************************************************************/
212 : /* GetName() */
213 : /************************************************************************/
214 :
215 : /**
216 : * \fn const char *OGRFeatureDefn::GetName();
217 : *
218 : * \brief Get name of this OGRFeatureDefn.
219 : *
220 : * This method is the same as the C function OGR_FD_GetName().
221 : *
222 : * @return the name. This name is internal and should not be modified, or
223 : * freed.
224 : */
225 1247960 : const char *OGRFeatureDefn::GetName() const
226 : {
227 1247960 : return pszFeatureClassName;
228 : }
229 :
230 : /************************************************************************/
231 : /* OGR_FD_GetName() */
232 : /************************************************************************/
233 : /**
234 : * \brief Get name of the OGRFeatureDefn passed as an argument.
235 : *
236 : * This function is the same as the C++ method OGRFeatureDefn::GetName().
237 : *
238 : * @param hDefn handle to the feature definition to get the name from.
239 : * @return the name. This name is internal and should not be modified, or
240 : * freed.
241 : */
242 :
243 107 : const char *OGR_FD_GetName(OGRFeatureDefnH hDefn)
244 :
245 : {
246 107 : return OGRFeatureDefn::FromHandle(hDefn)->GetName();
247 : }
248 :
249 : /************************************************************************/
250 : /* GetFieldCount() */
251 : /************************************************************************/
252 :
253 : /**
254 : * \fn int OGRFeatureDefn::GetFieldCount() const;
255 : *
256 : * \brief Fetch number of fields on this feature.
257 : *
258 : * This method is the same as the C function OGR_FD_GetFieldCount().
259 : * @return count of fields.
260 : */
261 :
262 46793700 : int OGRFeatureDefn::GetFieldCount() const
263 : {
264 46793700 : return static_cast<int>(apoFieldDefn.size());
265 : }
266 :
267 : /************************************************************************/
268 : /* OGR_FD_GetFieldCount() */
269 : /************************************************************************/
270 :
271 : /**
272 : * \brief Fetch number of fields on the passed feature definition.
273 : *
274 : * This function is the same as the C++ OGRFeatureDefn::GetFieldCount().
275 : *
276 : * @param hDefn handle to the feature definition to get the fields count from.
277 : * @return count of fields.
278 : */
279 :
280 48418 : int OGR_FD_GetFieldCount(OGRFeatureDefnH hDefn)
281 :
282 : {
283 : #ifdef OGRAPISPY_ENABLED
284 48418 : if (bOGRAPISpyEnabled)
285 6 : OGRAPISpy_FD_GetFieldCount(hDefn);
286 : #endif
287 :
288 48418 : return OGRFeatureDefn::FromHandle(hDefn)->GetFieldCount();
289 : }
290 :
291 : /************************************************************************/
292 : /* GetFieldDefn() */
293 : /************************************************************************/
294 :
295 : /**
296 : * \brief Fetch field definition.
297 : *
298 : * This method is the same as the C function OGR_FD_GetFieldDefn().
299 : *
300 : * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
301 : *
302 : * @return a pointer to an internal field definition object or NULL if invalid
303 : * index. This object should not be modified or freed by the application.
304 : */
305 :
306 20744900 : OGRFieldDefn *OGRFeatureDefn::GetFieldDefn(int iField)
307 :
308 : {
309 20744900 : if (iField < 0 || iField >= GetFieldCount())
310 : {
311 11 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
312 11 : return nullptr;
313 : }
314 :
315 20744900 : return apoFieldDefn[iField].get();
316 : }
317 :
318 : /**
319 : * \brief Fetch field definition.
320 : *
321 : * This method is the same as the C function OGR_FD_GetFieldDefn().
322 : *
323 : * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
324 : *
325 : * @return a pointer to an internal field definition object or NULL if invalid
326 : * index. This object should not be modified or freed by the application.
327 : *
328 : * @since GDAL 2.3
329 : */
330 :
331 17970900 : const OGRFieldDefn *OGRFeatureDefn::GetFieldDefn(int iField) const
332 :
333 : {
334 17970900 : if (iField < 0 || iField >= GetFieldCount())
335 : {
336 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
337 0 : return nullptr;
338 : }
339 :
340 17970900 : return apoFieldDefn[iField].get();
341 : }
342 :
343 : /************************************************************************/
344 : /* OGR_FD_GetFieldDefn() */
345 : /************************************************************************/
346 :
347 : /**
348 : * \brief Fetch field definition of the passed feature definition.
349 : *
350 : * This function is the same as the C++ method
351 : * OGRFeatureDefn::GetFieldDefn().
352 : *
353 : * @param hDefn handle to the feature definition to get the field definition
354 : * from.
355 : * @param iField the field to fetch, between 0 and GetFieldCount()-1.
356 : *
357 : * @return a handle to an internal field definition object or NULL if invalid
358 : * index. This object should not be modified or freed by the application.
359 : */
360 :
361 221592 : OGRFieldDefnH OGR_FD_GetFieldDefn(OGRFeatureDefnH hDefn, int iField)
362 :
363 : {
364 221592 : OGRFieldDefnH hFieldDefnH = OGRFieldDefn::ToHandle(
365 221592 : OGRFeatureDefn::FromHandle(hDefn)->GetFieldDefn(iField));
366 :
367 : #ifdef OGRAPISPY_ENABLED
368 221592 : if (bOGRAPISpyEnabled)
369 2 : OGRAPISpy_FD_GetFieldDefn(hDefn, iField, hFieldDefnH);
370 : #endif
371 :
372 221592 : return hFieldDefnH;
373 : }
374 :
375 : //! @cond Doxygen_Suppress
376 :
377 : /************************************************************************/
378 : /* ReserveSpaceForFields() */
379 : /************************************************************************/
380 :
381 938 : void OGRFeatureDefn::ReserveSpaceForFields(int nFieldCountIn)
382 : {
383 938 : apoFieldDefn.reserve(nFieldCountIn);
384 938 : }
385 :
386 : //! @endcond
387 :
388 : /************************************************************************/
389 : /* AddFieldDefn() */
390 : /************************************************************************/
391 :
392 : /**
393 : * \brief Add a new field definition.
394 : *
395 : * To add a new field definition to a layer definition, do not use this
396 : * function directly, but use OGRLayer::CreateField() instead.
397 : *
398 : * This method should only be called while there are no OGRFeature
399 : * objects in existence based on this OGRFeatureDefn. The OGRFieldDefn
400 : * passed in is copied, and remains the responsibility of the caller.
401 : *
402 : * This method is the same as the C function OGR_FD_AddFieldDefn().
403 : *
404 : * @param poNewDefn the definition of the new field.
405 : */
406 :
407 704070 : void OGRFeatureDefn::AddFieldDefn(const OGRFieldDefn *poNewDefn)
408 :
409 : {
410 704070 : if (m_bSealed)
411 : {
412 2 : CPLError(
413 : CE_Failure, CPLE_AppDefined,
414 : "OGRFeatureDefn::AddFieldDefn() not allowed on a sealed object");
415 2 : return;
416 : }
417 704068 : apoFieldDefn.emplace_back(std::make_unique<OGRFieldDefn>(poNewDefn));
418 : }
419 :
420 : /************************************************************************/
421 : /* OGR_FD_AddFieldDefn() */
422 : /************************************************************************/
423 :
424 : /**
425 : * \brief Add a new field definition to the passed feature definition.
426 : *
427 : * To add a new field definition to a layer definition, do not use this
428 : * function directly, but use OGR_L_CreateField() instead.
429 : *
430 : * This function should only be called while there are no OGRFeature
431 : * objects in existence based on this OGRFeatureDefn. The OGRFieldDefn
432 : * passed in is copied, and remains the responsibility of the caller.
433 : *
434 : * This function is the same as the C++ method OGRFeatureDefn::AddFieldDefn().
435 : *
436 : * @param hDefn handle to the feature definition to add the field definition
437 : * to.
438 : * @param hNewField handle to the new field definition.
439 : */
440 :
441 413 : void OGR_FD_AddFieldDefn(OGRFeatureDefnH hDefn, OGRFieldDefnH hNewField)
442 :
443 : {
444 826 : OGRFeatureDefn::FromHandle(hDefn)->AddFieldDefn(
445 413 : OGRFieldDefn::FromHandle(hNewField));
446 413 : }
447 :
448 : /************************************************************************/
449 : /* DeleteFieldDefn() */
450 : /************************************************************************/
451 :
452 : /**
453 : * \brief Delete an existing field definition.
454 : *
455 : * To delete an existing field definition from a layer definition, do not use
456 : * this function directly, but use OGRLayer::DeleteField() instead.
457 : *
458 : * This method should only be called while there are no OGRFeature
459 : * objects in existence based on this OGRFeatureDefn.
460 : *
461 : * This method is the same as the C function OGR_FD_DeleteFieldDefn().
462 : *
463 : * @param iField the index of the field definition.
464 : * @return OGRERR_NONE in case of success.
465 : * @since OGR 1.9.0
466 : */
467 :
468 75 : OGRErr OGRFeatureDefn::DeleteFieldDefn(int iField)
469 :
470 : {
471 75 : if (m_bSealed)
472 : {
473 1 : CPLError(
474 : CE_Failure, CPLE_AppDefined,
475 : "OGRFeatureDefn::DeleteFieldDefn() not allowed on a sealed object");
476 1 : return OGRERR_FAILURE;
477 : }
478 74 : if (iField < 0 || iField >= GetFieldCount())
479 0 : return OGRERR_FAILURE;
480 :
481 74 : apoFieldDefn.erase(apoFieldDefn.begin() + iField);
482 74 : return OGRERR_NONE;
483 : }
484 :
485 : /************************************************************************/
486 : /* OGR_FD_DeleteFieldDefn() */
487 : /************************************************************************/
488 :
489 : /**
490 : * \brief Delete an existing field definition.
491 : *
492 : * To delete an existing field definition from a layer definition, do not use
493 : * this function directly, but use OGR_L_DeleteField() instead.
494 : *
495 : * This method should only be called while there are no OGRFeature
496 : * objects in existence based on this OGRFeatureDefn.
497 : *
498 : * This method is the same as the C++ method OGRFeatureDefn::DeleteFieldDefn().
499 : *
500 : * @param hDefn handle to the feature definition.
501 : * @param iField the index of the field definition.
502 : * @return OGRERR_NONE in case of success.
503 : * @since OGR 1.9.0
504 : */
505 :
506 0 : OGRErr OGR_FD_DeleteFieldDefn(OGRFeatureDefnH hDefn, int iField)
507 :
508 : {
509 0 : return OGRFeatureDefn::FromHandle(hDefn)->DeleteFieldDefn(iField);
510 : }
511 :
512 : /************************************************************************/
513 : /* ReorderFieldDefns() */
514 : /************************************************************************/
515 :
516 : /**
517 : * \brief Reorder the field definitions in the array of the feature definition
518 : *
519 : * To reorder the field definitions in a layer definition, do not use this
520 : * function directly, but use OGR_L_ReorderFields() instead.
521 : *
522 : * This method should only be called while there are no OGRFeature
523 : * objects in existence based on this OGRFeatureDefn.
524 : *
525 : * This method is the same as the C function OGR_FD_ReorderFieldDefns().
526 : *
527 : * @param panMap an array of GetFieldCount() elements which
528 : * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
529 : * for each field definition at position i after reordering,
530 : * its position before reordering was panMap[i].
531 : * @return OGRERR_NONE in case of success.
532 : * @since OGR 1.9.0
533 : */
534 :
535 74 : OGRErr OGRFeatureDefn::ReorderFieldDefns(const int *panMap)
536 :
537 : {
538 74 : if (m_bSealed)
539 : {
540 1 : CPLError(CE_Failure, CPLE_AppDefined,
541 : "OGRFeatureDefn::ReorderFieldDefns() not allowed on a sealed "
542 : "object");
543 1 : return OGRERR_FAILURE;
544 : }
545 73 : const int nFieldCount = GetFieldCount();
546 73 : if (nFieldCount == 0)
547 0 : return OGRERR_NONE;
548 :
549 73 : const OGRErr eErr = OGRCheckPermutation(panMap, nFieldCount);
550 73 : if (eErr != OGRERR_NONE)
551 0 : return eErr;
552 :
553 73 : std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefnNew(nFieldCount);
554 511 : for (int i = 0; i < nFieldCount; i++)
555 : {
556 438 : apoFieldDefnNew[i] = std::move(apoFieldDefn[panMap[i]]);
557 : }
558 73 : apoFieldDefn = std::move(apoFieldDefnNew);
559 73 : return OGRERR_NONE;
560 : }
561 :
562 : /************************************************************************/
563 : /* OGR_FD_ReorderFieldDefns() */
564 : /************************************************************************/
565 :
566 : /**
567 : * \brief Reorder the field definitions in the array of the feature definition
568 : *
569 : * To reorder the field definitions in a layer definition, do not use this
570 : * function directly, but use OGR_L_ReorderFields() instead.
571 : *
572 : * This method should only be called while there are no OGRFeature
573 : * objects in existence based on this OGRFeatureDefn.
574 : *
575 : * This method is the same as the C++ method
576 : * OGRFeatureDefn::ReorderFieldDefns().
577 : *
578 : * @param hDefn handle to the feature definition.
579 : * @param panMap an array of GetFieldCount() elements which
580 : * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
581 : * for each field definition at position i after reordering,
582 : * its position before reordering was panMap[i].
583 : * @return OGRERR_NONE in case of success.
584 : * @since OGR 2.1.0
585 : */
586 :
587 0 : OGRErr OGR_FD_ReorderFieldDefns(OGRFeatureDefnH hDefn, const int *panMap)
588 :
589 : {
590 0 : return OGRFeatureDefn::FromHandle(hDefn)->ReorderFieldDefns(panMap);
591 : }
592 :
593 : /************************************************************************/
594 : /* GetGeomFieldCount() */
595 : /************************************************************************/
596 :
597 : /**
598 : * \fn int OGRFeatureDefn::GetGeomFieldCount() const;
599 : *
600 : * \brief Fetch number of geometry fields on this feature.
601 : *
602 : * This method is the same as the C function OGR_FD_GetGeomFieldCount().
603 : * @return count of geometry fields.
604 : *
605 : * @since GDAL 1.11
606 : */
607 18417100 : int OGRFeatureDefn::GetGeomFieldCount() const
608 : {
609 18417100 : return static_cast<int>(apoGeomFieldDefn.size());
610 : }
611 :
612 : /************************************************************************/
613 : /* OGR_FD_GetGeomFieldCount() */
614 : /************************************************************************/
615 :
616 : /**
617 : * \brief Fetch number of geometry fields on the passed feature definition.
618 : *
619 : * This function is the same as the C++ OGRFeatureDefn::GetGeomFieldCount().
620 : *
621 : * @param hDefn handle to the feature definition to get the fields count from.
622 : * @return count of geometry fields.
623 : *
624 : * @since GDAL 1.11
625 : */
626 :
627 293 : int OGR_FD_GetGeomFieldCount(OGRFeatureDefnH hDefn)
628 :
629 : {
630 : #ifdef OGRAPISPY_ENABLED
631 293 : if (bOGRAPISpyEnabled)
632 2 : OGRAPISpy_FD_GetGeomFieldCount(hDefn);
633 : #endif
634 :
635 293 : return OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldCount();
636 : }
637 :
638 : /************************************************************************/
639 : /* GetGeomFieldDefn() */
640 : /************************************************************************/
641 :
642 : /**
643 : * \brief Fetch geometry field definition.
644 : *
645 : * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
646 : *
647 : * @param iGeomField the geometry field to fetch, between 0 and
648 : * GetGeomFieldCount() - 1.
649 : *
650 : * @return a pointer to an internal field definition object or NULL if invalid
651 : * index. This object should not be modified or freed by the application.
652 : *
653 : * @since GDAL 1.11
654 : */
655 :
656 915717 : OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn(int iGeomField)
657 :
658 : {
659 915717 : if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
660 : {
661 2 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
662 2 : return nullptr;
663 : }
664 :
665 915715 : return apoGeomFieldDefn[iGeomField].get();
666 : }
667 :
668 : /**
669 : * \brief Fetch geometry field definition.
670 : *
671 : * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
672 : *
673 : * @param iGeomField the geometry field to fetch, between 0 and
674 : * GetGeomFieldCount() - 1.
675 : *
676 : * @return a pointer to an internal field definition object or NULL if invalid
677 : * index. This object should not be modified or freed by the application.
678 : *
679 : * @since GDAL 2.3
680 : */
681 :
682 675992 : const OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn(int iGeomField) const
683 :
684 : {
685 675992 : if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
686 : {
687 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
688 0 : return nullptr;
689 : }
690 :
691 675992 : return apoGeomFieldDefn[iGeomField].get();
692 : }
693 :
694 : /************************************************************************/
695 : /* OGR_FD_GetGeomFieldDefn() */
696 : /************************************************************************/
697 :
698 : /**
699 : * \brief Fetch geometry field definition of the passed feature definition.
700 : *
701 : * This function is the same as the C++ method
702 : * OGRFeatureDefn::GetGeomFieldDefn().
703 : *
704 : * @param hDefn handle to the feature definition to get the field definition
705 : * from.
706 : * @param iGeomField the geometry field to fetch, between 0 and
707 : * GetGeomFieldCount() - 1.
708 : *
709 : * @return a handle to an internal field definition object or NULL if invalid
710 : * index. This object should not be modified or freed by the application.
711 : *
712 : * @since GDAL 1.11
713 : */
714 :
715 578 : OGRGeomFieldDefnH OGR_FD_GetGeomFieldDefn(OGRFeatureDefnH hDefn, int iGeomField)
716 :
717 : {
718 578 : OGRGeomFieldDefnH hGeomField = OGRGeomFieldDefn::ToHandle(
719 578 : OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldDefn(iGeomField));
720 :
721 : #ifdef OGRAPISPY_ENABLED
722 578 : if (bOGRAPISpyEnabled)
723 2 : OGRAPISpy_FD_GetGeomFieldDefn(hDefn, iGeomField, hGeomField);
724 : #endif
725 :
726 578 : return hGeomField;
727 : }
728 :
729 : /************************************************************************/
730 : /* AddGeomFieldDefn() */
731 : /************************************************************************/
732 :
733 : /**
734 : * \brief Add a new geometry field definition.
735 : *
736 : * To add a new geometry field definition to a layer definition, do not use this
737 : * function directly, but use OGRLayer::CreateGeomField() instead.
738 : *
739 : * This method does an internal copy of the passed geometry field definition,
740 : * unless bCopy is set to FALSE (in which case it takes ownership of the
741 : * field definition.
742 : *
743 : * This method should only be called while there are no OGRFeature
744 : * objects in existence based on this OGRFeatureDefn. The OGRGeomFieldDefn
745 : * passed in is copied, and remains the responsibility of the caller.
746 : *
747 : * This method is the same as the C function OGR_FD_AddGeomFieldDefn().
748 : *
749 : * @param poNewDefn the definition of the new geometry field.
750 : *
751 : * @since GDAL 1.11
752 : */
753 :
754 7010 : void OGRFeatureDefn::AddGeomFieldDefn(const OGRGeomFieldDefn *poNewDefn)
755 : {
756 7010 : if (m_bSealed)
757 : {
758 1 : CPLError(CE_Failure, CPLE_AppDefined,
759 : "OGRFeatureDefn::AddGeomFieldDefn() not allowed on a sealed "
760 : "object");
761 1 : return;
762 : }
763 : apoGeomFieldDefn.emplace_back(
764 7009 : std::make_unique<OGRGeomFieldDefn>(poNewDefn));
765 : }
766 :
767 : /**
768 : * \brief Add a new geometry field definition.
769 : *
770 : * To add a new geometry field definition to a layer definition, do not use this
771 : * function directly, but use OGRLayer::CreateGeomField() instead.
772 : *
773 : * This method takes ownership of the passed geometry field definition.
774 : *
775 : * This method should only be called while there are no OGRFeature
776 : * objects in existence based on this OGRFeatureDefn.
777 : *
778 : * @param poNewDefn the definition of the new geometry field.
779 : *
780 : * @since GDAL 3.4
781 : */
782 :
783 11338 : void OGRFeatureDefn::AddGeomFieldDefn(
784 : std::unique_ptr<OGRGeomFieldDefn> &&poNewDefn)
785 : {
786 11338 : apoGeomFieldDefn.emplace_back(std::move(poNewDefn));
787 11338 : }
788 :
789 : /************************************************************************/
790 : /* OGR_FD_AddGeomFieldDefn() */
791 : /************************************************************************/
792 :
793 : /**
794 : * \brief Add a new field definition to the passed feature definition.
795 : *
796 : * To add a new field definition to a layer definition, do not use this
797 : * function directly, but use OGR_L_CreateGeomField() instead.
798 : *
799 : * This function should only be called while there are no OGRFeature
800 : * objects in existence based on this OGRFeatureDefn. The OGRGeomFieldDefn
801 : * passed in is copied, and remains the responsibility of the caller.
802 : *
803 : * This function is the same as the C++ method
804 : * OGRFeatureDefn::AddGeomFieldDefn().
805 : *
806 : * @param hDefn handle to the feature definition to add the geometry field
807 : * definition to.
808 : * @param hNewGeomField handle to the new field definition.
809 : *
810 : * @since GDAL 1.11
811 : */
812 :
813 11 : void OGR_FD_AddGeomFieldDefn(OGRFeatureDefnH hDefn,
814 : OGRGeomFieldDefnH hNewGeomField)
815 :
816 : {
817 22 : OGRFeatureDefn::FromHandle(hDefn)->AddGeomFieldDefn(
818 11 : OGRGeomFieldDefn::FromHandle(hNewGeomField));
819 11 : }
820 :
821 : /************************************************************************/
822 : /* DeleteGeomFieldDefn() */
823 : /************************************************************************/
824 :
825 : /**
826 : * \brief Delete an existing geometry field definition.
827 : *
828 : * To delete an existing field definition from a layer definition, do not use
829 : * this function directly, but use OGRLayer::DeleteGeomField() instead.
830 : *
831 : * This method should only be called while there are no OGRFeature
832 : * objects in existence based on this OGRFeatureDefn.
833 : *
834 : * This method is the same as the C function OGR_FD_DeleteGeomFieldDefn().
835 : *
836 : * @param iGeomField the index of the geometry field definition.
837 : * @return OGRERR_NONE in case of success.
838 : *
839 : * @since GDAL 1.11
840 : */
841 :
842 51527 : OGRErr OGRFeatureDefn::DeleteGeomFieldDefn(int iGeomField)
843 :
844 : {
845 51527 : if (m_bSealed)
846 : {
847 1 : CPLError(CE_Failure, CPLE_AppDefined,
848 : "OGRFeatureDefn::DeleteGeomFieldDefn() not allowed on a "
849 : "sealed object");
850 1 : return OGRERR_FAILURE;
851 : }
852 51526 : if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
853 2 : return OGRERR_FAILURE;
854 :
855 51524 : apoGeomFieldDefn.erase(apoGeomFieldDefn.begin() + iGeomField);
856 51524 : return OGRERR_NONE;
857 : }
858 :
859 : /************************************************************************/
860 : /* OGR_FD_DeleteGeomFieldDefn() */
861 : /************************************************************************/
862 :
863 : /**
864 : * \brief Delete an existing geometry field definition.
865 : *
866 : * To delete an existing geometry field definition from a layer definition, do
867 : * not use this function directly, but use OGR_L_DeleteGeomField() instead
868 : * (*not implemented yet*).
869 : *
870 : * This method should only be called while there are no OGRFeature
871 : * objects in existence based on this OGRFeatureDefn.
872 : *
873 : * This method is the same as the C++ method
874 : * OGRFeatureDefn::DeleteGeomFieldDefn().
875 : *
876 : * @param hDefn handle to the feature definition.
877 : * @param iGeomField the index of the geometry field definition.
878 : * @return OGRERR_NONE in case of success.
879 : *
880 : * @since GDAL 1.11
881 : */
882 :
883 4 : OGRErr OGR_FD_DeleteGeomFieldDefn(OGRFeatureDefnH hDefn, int iGeomField)
884 :
885 : {
886 4 : return OGRFeatureDefn::FromHandle(hDefn)->DeleteGeomFieldDefn(iGeomField);
887 : }
888 :
889 : /************************************************************************/
890 : /* GetGeomFieldIndex() */
891 : /************************************************************************/
892 :
893 : /**
894 : * \brief Find geometry field by name.
895 : *
896 : * The geometry field index of the first geometry field matching the passed
897 : * field name (case insensitively) is returned.
898 : *
899 : * This method is the same as the C function OGR_FD_GetGeomFieldIndex().
900 : *
901 : * @param pszGeomFieldName the geometry field name to search for.
902 : *
903 : * @return the geometry field index, or -1 if no match found.
904 : */
905 :
906 26136 : int OGRFeatureDefn::GetGeomFieldIndex(const char *pszGeomFieldName) const
907 :
908 : {
909 26136 : const int nGeomFieldCount = GetGeomFieldCount();
910 42892 : for (int i = 0; i < nGeomFieldCount; i++)
911 : {
912 34526 : const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(i);
913 69052 : if (poGFldDefn != nullptr &&
914 34526 : EQUAL(pszGeomFieldName, poGFldDefn->GetNameRef()))
915 17770 : return i;
916 : }
917 :
918 8366 : return -1;
919 : }
920 :
921 : /************************************************************************/
922 : /* OGR_FD_GetGeomFieldIndex() */
923 : /************************************************************************/
924 : /**
925 : * \brief Find geometry field by name.
926 : *
927 : * The geometry field index of the first geometry field matching the passed
928 : * field name (case insensitively) is returned.
929 : *
930 : * This function is the same as the C++ method
931 : * OGRFeatureDefn::GetGeomFieldIndex.
932 : *
933 : * @param hDefn handle to the feature definition to get field index from.
934 : * @param pszGeomFieldName the geometry field name to search for.
935 : *
936 : * @return the geometry field index, or -1 if no match found.
937 : */
938 :
939 37 : int OGR_FD_GetGeomFieldIndex(OGRFeatureDefnH hDefn,
940 : const char *pszGeomFieldName)
941 :
942 : {
943 : #ifdef OGRAPISPY_ENABLED
944 37 : if (bOGRAPISpyEnabled)
945 2 : OGRAPISpy_FD_GetGeomFieldIndex(hDefn, pszGeomFieldName);
946 : #endif
947 :
948 74 : return OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldIndex(
949 37 : pszGeomFieldName);
950 : }
951 :
952 : /************************************************************************/
953 : /* GetGeomType() */
954 : /************************************************************************/
955 :
956 : /**
957 : * \fn OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const;
958 : *
959 : * \brief Fetch the geometry base type.
960 : *
961 : * Note that some drivers are unable to determine a specific geometry
962 : * type for a layer, in which case wkbUnknown is returned. A value of
963 : * wkbNone indicates no geometry is available for the layer at all.
964 : * Many drivers do not properly mark the geometry
965 : * type as 25D even if some or all geometries are in fact 25D. A few (broken)
966 : * drivers return wkbPolygon for layers that also include wkbMultiPolygon.
967 : *
968 : * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
969 : *
970 : * This method is the same as the C function OGR_FD_GetGeomType().
971 : *
972 : * @return the base type for all geometry related to this definition.
973 : */
974 550452 : OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const
975 : {
976 550452 : if (GetGeomFieldCount() == 0)
977 1986 : return wkbNone;
978 548466 : const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
979 548466 : if (poGFldDefn == nullptr)
980 0 : return wkbNone;
981 548466 : OGRwkbGeometryType eType = poGFldDefn->GetType();
982 548471 : if (eType == (/*wkbUnknown |*/ wkb25DBitInternalUse) &&
983 5 : CPLTestBool(CPLGetConfigOption("QGIS_HACK", "NO")))
984 0 : eType = wkbUnknown;
985 548466 : return eType;
986 : }
987 :
988 : /************************************************************************/
989 : /* OGR_FD_GetGeomType() */
990 : /************************************************************************/
991 : /**
992 : * \brief Fetch the geometry base type of the passed feature definition.
993 : *
994 : * This function is the same as the C++ method OGRFeatureDefn::GetGeomType().
995 : *
996 : * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
997 : *
998 : * @param hDefn handle to the feature definition to get the geometry type from.
999 : * @return the base type for all geometry related to this definition.
1000 : */
1001 :
1002 2270 : OGRwkbGeometryType OGR_FD_GetGeomType(OGRFeatureDefnH hDefn)
1003 :
1004 : {
1005 2270 : OGRwkbGeometryType eType = OGRFeatureDefn::FromHandle(hDefn)->GetGeomType();
1006 2270 : if (OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag())
1007 : {
1008 1 : eType = OGR_GT_GetLinear(eType);
1009 : }
1010 : #ifdef OGRAPISPY_ENABLED
1011 2270 : if (bOGRAPISpyEnabled)
1012 2 : OGRAPISpy_FD_GetGeomType(hDefn);
1013 : #endif
1014 :
1015 2270 : return eType;
1016 : }
1017 :
1018 : /************************************************************************/
1019 : /* SetGeomType() */
1020 : /************************************************************************/
1021 :
1022 : /**
1023 : * \brief Assign the base geometry type for this layer.
1024 : *
1025 : * All geometry objects using this type must be of the defined type or
1026 : * a derived type. The default upon creation is wkbUnknown which allows for
1027 : * any geometry type. The geometry type should generally not be changed
1028 : * after any OGRFeatures have been created against this definition.
1029 : *
1030 : * This method is the same as the C function OGR_FD_SetGeomType().
1031 : *
1032 : * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
1033 : *
1034 : * @param eNewType the new type to assign.
1035 : */
1036 :
1037 72336 : void OGRFeatureDefn::SetGeomType(OGRwkbGeometryType eNewType)
1038 :
1039 : {
1040 72336 : if (m_bSealed)
1041 : {
1042 0 : CPLError(
1043 : CE_Failure, CPLE_AppDefined,
1044 : "OGRFeatureDefn::SetGeomType() not allowed on a sealed object");
1045 0 : return;
1046 : }
1047 72336 : const int nGeomFieldCount = GetGeomFieldCount();
1048 72336 : if (nGeomFieldCount > 0)
1049 : {
1050 66958 : if (nGeomFieldCount == 1 && eNewType == wkbNone)
1051 50200 : DeleteGeomFieldDefn(0);
1052 : else
1053 16758 : GetGeomFieldDefn(0)->SetType(eNewType);
1054 : }
1055 5378 : else if (eNewType != wkbNone)
1056 : {
1057 3330 : OGRGeomFieldDefn oGeomFieldDefn("", eNewType);
1058 1665 : AddGeomFieldDefn(&oGeomFieldDefn);
1059 : }
1060 : }
1061 :
1062 : /************************************************************************/
1063 : /* OGR_FD_SetGeomType() */
1064 : /************************************************************************/
1065 :
1066 : /**
1067 : * \brief Assign the base geometry type for the passed layer (the same as the
1068 : * feature definition).
1069 : *
1070 : * All geometry objects using this type must be of the defined type or
1071 : * a derived type. The default upon creation is wkbUnknown which allows for
1072 : * any geometry type. The geometry type should generally not be changed
1073 : * after any OGRFeatures have been created against this definition.
1074 : *
1075 : * This function is the same as the C++ method OGRFeatureDefn::SetGeomType().
1076 : *
1077 : * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
1078 : *
1079 : * @param hDefn handle to the layer or feature definition to set the geometry
1080 : * type to.
1081 : * @param eType the new type to assign.
1082 : */
1083 :
1084 19 : void OGR_FD_SetGeomType(OGRFeatureDefnH hDefn, OGRwkbGeometryType eType)
1085 :
1086 : {
1087 19 : OGRFeatureDefn::FromHandle(hDefn)->SetGeomType(eType);
1088 19 : }
1089 :
1090 : /************************************************************************/
1091 : /* Reference() */
1092 : /************************************************************************/
1093 :
1094 : /**
1095 : * \fn int OGRFeatureDefn::Reference();
1096 : *
1097 : * \brief Increments the reference count by one.
1098 : *
1099 : * The reference count is used keep track of the number of OGRFeature
1100 : * objects referencing this definition.
1101 : *
1102 : * This method is the same as the C function OGR_FD_Reference().
1103 : *
1104 : * @return the updated reference count.
1105 : */
1106 :
1107 : /************************************************************************/
1108 : /* OGR_FD_Reference() */
1109 : /************************************************************************/
1110 : /**
1111 : * \brief Increments the reference count by one.
1112 : *
1113 : * The reference count is used keep track of the number of OGRFeature
1114 : * objects referencing this definition.
1115 : *
1116 : * This function is the same as the C++ method OGRFeatureDefn::Reference().
1117 : *
1118 : * @param hDefn handle to the feature definition on witch OGRFeature are
1119 : * based on.
1120 : * @return the updated reference count.
1121 : */
1122 :
1123 125469 : int OGR_FD_Reference(OGRFeatureDefnH hDefn)
1124 :
1125 : {
1126 125469 : return OGRFeatureDefn::FromHandle(hDefn)->Reference();
1127 : }
1128 :
1129 : /************************************************************************/
1130 : /* Dereference() */
1131 : /************************************************************************/
1132 :
1133 : /**
1134 : * \fn int OGRFeatureDefn::Dereference();
1135 : *
1136 : * \brief Decrements the reference count by one.
1137 : *
1138 : * This method is the same as the C function OGR_FD_Dereference().
1139 : *
1140 : * @return the updated reference count.
1141 : */
1142 :
1143 : /************************************************************************/
1144 : /* OGR_FD_Dereference() */
1145 : /************************************************************************/
1146 :
1147 : /**
1148 : * \brief Decrements the reference count by one.
1149 : *
1150 : * This function is the same as the C++ method OGRFeatureDefn::Dereference().
1151 : *
1152 : * @param hDefn handle to the feature definition on witch OGRFeature are
1153 : * based on.
1154 : * @return the updated reference count.
1155 : */
1156 :
1157 0 : int OGR_FD_Dereference(OGRFeatureDefnH hDefn)
1158 :
1159 : {
1160 0 : return OGRFeatureDefn::FromHandle(hDefn)->Dereference();
1161 : }
1162 :
1163 : /************************************************************************/
1164 : /* GetReferenceCount() */
1165 : /************************************************************************/
1166 :
1167 : /**
1168 : * \fn int OGRFeatureDefn::GetReferenceCount();
1169 : *
1170 : * \brief Fetch current reference count.
1171 : *
1172 : * This method is the same as the C function OGR_FD_GetReferenceCount().
1173 : *
1174 : * @return the current reference count.
1175 : */
1176 :
1177 : /************************************************************************/
1178 : /* OGR_FD_GetReferenceCount() */
1179 : /************************************************************************/
1180 :
1181 : /**
1182 : * \brief Fetch current reference count.
1183 : *
1184 : * This function is the same as the C++ method
1185 : * OGRFeatureDefn::GetReferenceCount().
1186 : *
1187 : * @param hDefn handle to the feature definition on witch OGRFeature are
1188 : * based on.
1189 : * @return the current reference count.
1190 : */
1191 :
1192 3 : int OGR_FD_GetReferenceCount(OGRFeatureDefnH hDefn)
1193 :
1194 : {
1195 3 : return OGRFeatureDefn::FromHandle(hDefn)->GetReferenceCount();
1196 : }
1197 :
1198 : /************************************************************************/
1199 : /* GetFieldIndex() */
1200 : /************************************************************************/
1201 :
1202 : /**
1203 : * \brief Find field by name.
1204 : *
1205 : * The field index of the first field matching the passed field name (case
1206 : * insensitively) is returned.
1207 : *
1208 : * This method is the same as the C function OGR_FD_GetFieldIndex().
1209 : *
1210 : * @param pszFieldName the field name to search for.
1211 : *
1212 : * @return the field index, or -1 if no match found.
1213 : */
1214 :
1215 2516090 : int OGRFeatureDefn::GetFieldIndex(const char *pszFieldName) const
1216 :
1217 : {
1218 2516090 : const int nFieldCount = GetFieldCount();
1219 17795100 : for (int i = 0; i < nFieldCount; i++)
1220 : {
1221 17710300 : const OGRFieldDefn *poFDefn = GetFieldDefn(i);
1222 17710300 : if (poFDefn != nullptr && EQUAL(pszFieldName, poFDefn->GetNameRef()))
1223 2431350 : return i;
1224 : }
1225 :
1226 84743 : return -1;
1227 : }
1228 :
1229 : /************************************************************************/
1230 : /* GetFieldIndexCaseSensitive() */
1231 : /************************************************************************/
1232 :
1233 : /**
1234 : * \brief Find field by name, in a case sensitive way.
1235 : *
1236 : * The field index of the first field matching the passed field name is
1237 : * returned.
1238 : *
1239 : * @param pszFieldName the field name to search for.
1240 : *
1241 : * @return the field index, or -1 if no match found.
1242 : */
1243 :
1244 9732 : int OGRFeatureDefn::GetFieldIndexCaseSensitive(const char *pszFieldName) const
1245 :
1246 : {
1247 9732 : const int nFieldCount = GetFieldCount();
1248 57710 : for (int i = 0; i < nFieldCount; i++)
1249 : {
1250 55987 : const OGRFieldDefn *poFDefn = GetFieldDefn(i);
1251 111974 : if (poFDefn != nullptr &&
1252 55987 : strcmp(pszFieldName, poFDefn->GetNameRef()) == 0)
1253 : {
1254 8009 : return i;
1255 : }
1256 : }
1257 :
1258 1723 : return -1;
1259 : }
1260 :
1261 : /************************************************************************/
1262 : /* OGR_FD_GetFieldIndex() */
1263 : /************************************************************************/
1264 : /**
1265 : * \brief Find field by name.
1266 : *
1267 : * The field index of the first field matching the passed field name (case
1268 : * insensitively) is returned.
1269 : *
1270 : * This function is the same as the C++ method OGRFeatureDefn::GetFieldIndex.
1271 : *
1272 : * @param hDefn handle to the feature definition to get field index from.
1273 : * @param pszFieldName the field name to search for.
1274 : *
1275 : * @return the field index, or -1 if no match found.
1276 : */
1277 :
1278 1926 : int OGR_FD_GetFieldIndex(OGRFeatureDefnH hDefn, const char *pszFieldName)
1279 :
1280 : {
1281 : #ifdef OGRAPISPY_ENABLED
1282 1926 : if (bOGRAPISpyEnabled)
1283 2 : OGRAPISpy_FD_GetFieldIndex(hDefn, pszFieldName);
1284 : #endif
1285 :
1286 1926 : return OGRFeatureDefn::FromHandle(hDefn)->GetFieldIndex(pszFieldName);
1287 : }
1288 :
1289 : /************************************************************************/
1290 : /* IsGeometryIgnored() */
1291 : /************************************************************************/
1292 :
1293 : /**
1294 : * \fn int OGRFeatureDefn::IsGeometryIgnored() const;
1295 : *
1296 : * \brief Determine whether the geometry can be omitted when fetching features
1297 : *
1298 : * This method is the same as the C function OGR_FD_IsGeometryIgnored().
1299 : *
1300 : * Starting with GDAL 1.11, this method returns
1301 : * GetGeomFieldDefn(0)->IsIgnored().
1302 : *
1303 : * @return ignore state
1304 : */
1305 :
1306 91306 : int OGRFeatureDefn::IsGeometryIgnored() const
1307 : {
1308 91306 : if (GetGeomFieldCount() == 0)
1309 183 : return FALSE;
1310 91123 : const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
1311 91123 : if (poGFldDefn == nullptr)
1312 0 : return FALSE;
1313 91123 : return poGFldDefn->IsIgnored();
1314 : }
1315 :
1316 : /************************************************************************/
1317 : /* OGR_FD_IsGeometryIgnored() */
1318 : /************************************************************************/
1319 :
1320 : /**
1321 : * \brief Determine whether the geometry can be omitted when fetching features
1322 : *
1323 : * This function is the same as the C++ method
1324 : * OGRFeatureDefn::IsGeometryIgnored().
1325 : *
1326 : * Starting with GDAL 1.11, this method returns
1327 : * GetGeomFieldDefn(0)->IsIgnored().
1328 : *
1329 : * @param hDefn handle to the feature definition on witch OGRFeature are
1330 : * based on.
1331 : * @return ignore state
1332 : */
1333 :
1334 6 : int OGR_FD_IsGeometryIgnored(OGRFeatureDefnH hDefn)
1335 : {
1336 6 : return OGRFeatureDefn::FromHandle(hDefn)->IsGeometryIgnored();
1337 : }
1338 :
1339 : /************************************************************************/
1340 : /* SetGeometryIgnored() */
1341 : /************************************************************************/
1342 :
1343 : /**
1344 : * \fn void OGRFeatureDefn::SetGeometryIgnored( int bIgnore );
1345 : *
1346 : * \brief Set whether the geometry can be omitted when fetching features
1347 : *
1348 : * This method is the same as the C function OGR_FD_SetGeometryIgnored().
1349 : *
1350 : * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
1351 : *
1352 : * @param bIgnore ignore state
1353 : */
1354 :
1355 963 : void OGRFeatureDefn::SetGeometryIgnored(int bIgnore)
1356 : {
1357 963 : if (GetGeomFieldCount() > 0)
1358 : {
1359 777 : OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
1360 777 : if (poGFldDefn != nullptr)
1361 777 : poGFldDefn->SetIgnored(bIgnore);
1362 : }
1363 963 : }
1364 :
1365 : /************************************************************************/
1366 : /* OGR_FD_SetGeometryIgnored() */
1367 : /************************************************************************/
1368 :
1369 : /**
1370 : * \brief Set whether the geometry can be omitted when fetching features
1371 : *
1372 : * This function is the same as the C++ method
1373 : * OGRFeatureDefn::SetGeometryIgnored().
1374 : *
1375 : * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
1376 : *
1377 : * @param hDefn handle to the feature definition on witch OGRFeature are
1378 : * based on.
1379 : * @param bIgnore ignore state
1380 : */
1381 :
1382 3 : void OGR_FD_SetGeometryIgnored(OGRFeatureDefnH hDefn, int bIgnore)
1383 : {
1384 3 : OGRFeatureDefn::FromHandle(hDefn)->SetGeometryIgnored(bIgnore);
1385 3 : }
1386 :
1387 : /************************************************************************/
1388 : /* IsStyleIgnored() */
1389 : /************************************************************************/
1390 :
1391 : /**
1392 : * \fn int OGRFeatureDefn::IsStyleIgnored() const;
1393 : *
1394 : * \brief Determine whether the style can be omitted when fetching features
1395 : *
1396 : * This method is the same as the C function OGR_FD_IsStyleIgnored().
1397 : *
1398 : * @return ignore state
1399 : */
1400 :
1401 : /************************************************************************/
1402 : /* OGR_FD_IsStyleIgnored() */
1403 : /************************************************************************/
1404 :
1405 : /**
1406 : * \brief Determine whether the style can be omitted when fetching features
1407 : *
1408 : * This function is the same as the C++ method
1409 : * OGRFeatureDefn::IsStyleIgnored().
1410 : *
1411 : * @param hDefn handle to the feature definition on which OGRFeature are
1412 : * based on.
1413 : * @return ignore state
1414 : */
1415 :
1416 2 : int OGR_FD_IsStyleIgnored(OGRFeatureDefnH hDefn)
1417 : {
1418 2 : return OGRFeatureDefn::FromHandle(hDefn)->IsStyleIgnored();
1419 : }
1420 :
1421 : /************************************************************************/
1422 : /* SetStyleIgnored() */
1423 : /************************************************************************/
1424 :
1425 : /**
1426 : * \fn void OGRFeatureDefn::SetStyleIgnored( int bIgnore );
1427 : *
1428 : * \brief Set whether the style can be omitted when fetching features
1429 : *
1430 : * This method is the same as the C function OGR_FD_SetStyleIgnored().
1431 : *
1432 : * @param bIgnore ignore state
1433 : */
1434 :
1435 : /************************************************************************/
1436 : /* OGR_FD_SetStyleIgnored() */
1437 : /************************************************************************/
1438 :
1439 : /**
1440 : * \brief Set whether the style can be omitted when fetching features
1441 : *
1442 : * This function is the same as the C++ method
1443 : * OGRFeatureDefn::SetStyleIgnored().
1444 : *
1445 : * @param hDefn handle to the feature definition on witch OGRFeature are
1446 : * based on.
1447 : * @param bIgnore ignore state
1448 : */
1449 :
1450 0 : void OGR_FD_SetStyleIgnored(OGRFeatureDefnH hDefn, int bIgnore)
1451 : {
1452 0 : OGRFeatureDefn::FromHandle(hDefn)->SetStyleIgnored(CPL_TO_BOOL(bIgnore));
1453 0 : }
1454 :
1455 : /************************************************************************/
1456 : /* CreateFeatureDefn() */
1457 : /************************************************************************/
1458 :
1459 : /** Create a new feature definition object.
1460 : * @param pszName name
1461 : * @return new feature definition object.
1462 : */
1463 1 : OGRFeatureDefn *OGRFeatureDefn::CreateFeatureDefn(const char *pszName)
1464 :
1465 : {
1466 1 : return new OGRFeatureDefn(pszName);
1467 : }
1468 :
1469 : /************************************************************************/
1470 : /* DestroyFeatureDefn() */
1471 : /************************************************************************/
1472 :
1473 : /** Destroy a feature definition.
1474 : * @param poDefn feature definition.
1475 : */
1476 7 : void OGRFeatureDefn::DestroyFeatureDefn(OGRFeatureDefn *poDefn)
1477 :
1478 : {
1479 7 : delete poDefn;
1480 7 : }
1481 :
1482 : /************************************************************************/
1483 : /* IsSame() */
1484 : /************************************************************************/
1485 :
1486 : /**
1487 : * \brief Test if the feature definition is identical to the other one.
1488 : *
1489 : * @param poOtherFeatureDefn the other feature definition to compare to.
1490 : * @return TRUE if the feature definition is identical to the other one.
1491 : */
1492 :
1493 420 : int OGRFeatureDefn::IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const
1494 : {
1495 420 : const int nFieldCount = GetFieldCount();
1496 420 : const int nGeomFieldCount = GetGeomFieldCount();
1497 420 : if (strcmp(GetName(), poOtherFeatureDefn->GetName()) == 0 &&
1498 778 : nFieldCount == poOtherFeatureDefn->GetFieldCount() &&
1499 358 : nGeomFieldCount == poOtherFeatureDefn->GetGeomFieldCount())
1500 : {
1501 904 : for (int i = 0; i < nFieldCount; i++)
1502 : {
1503 619 : const OGRFieldDefn *poFldDefn = GetFieldDefn(i);
1504 : const OGRFieldDefn *poOtherFldDefn =
1505 619 : poOtherFeatureDefn->GetFieldDefn(i);
1506 619 : if (!poFldDefn->IsSame(poOtherFldDefn))
1507 : {
1508 3 : return FALSE;
1509 : }
1510 : }
1511 597 : for (int i = 0; i < nGeomFieldCount; i++)
1512 : {
1513 337 : const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(i);
1514 : const OGRGeomFieldDefn *poOtherGFldDefn =
1515 337 : poOtherFeatureDefn->GetGeomFieldDefn(i);
1516 337 : if (!poGFldDefn->IsSame(poOtherGFldDefn))
1517 : {
1518 25 : return FALSE;
1519 : }
1520 : }
1521 260 : return TRUE;
1522 : }
1523 132 : return FALSE;
1524 : }
1525 :
1526 : /************************************************************************/
1527 : /* OGR_FD_IsSame() */
1528 : /************************************************************************/
1529 :
1530 : /**
1531 : * \brief Test if the feature definition is identical to the other one.
1532 : *
1533 : * @param hFDefn handle to the feature definition on witch OGRFeature are
1534 : * based on.
1535 : * @param hOtherFDefn handle to the other feature definition to compare to.
1536 : * @return TRUE if the feature definition is identical to the other one.
1537 : *
1538 : * @since OGR 1.11
1539 : */
1540 :
1541 11 : int OGR_FD_IsSame(OGRFeatureDefnH hFDefn, OGRFeatureDefnH hOtherFDefn)
1542 : {
1543 11 : VALIDATE_POINTER1(hFDefn, "OGR_FD_IsSame", FALSE);
1544 11 : VALIDATE_POINTER1(hOtherFDefn, "OGR_FD_IsSame", FALSE);
1545 :
1546 22 : return OGRFeatureDefn::FromHandle(hFDefn)->IsSame(
1547 11 : OGRFeatureDefn::FromHandle(hOtherFDefn));
1548 : }
1549 :
1550 : /************************************************************************/
1551 : /* ComputeMapForSetFrom() */
1552 : /************************************************************************/
1553 :
1554 : /**
1555 : * \brief Compute the map from source to target field that can be passed to
1556 : * SetFrom().
1557 : *
1558 : * @param poSrcFDefn the feature definition of source features later passed to
1559 : * SetFrom()
1560 : *
1561 : * @param bForgiving true if the operation should continue despite lacking
1562 : * output fields matching some of the source fields.
1563 : *
1564 : * @return an array of size poSrcFDefn->GetFieldCount() if everything succeeds,
1565 : * or empty in case a source field definition was not found in the target layer
1566 : * and bForgiving == true.
1567 : *
1568 : * @since GDAL 2.3
1569 : */
1570 :
1571 : std::vector<int>
1572 6354 : OGRFeatureDefn::ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
1573 : bool bForgiving) const
1574 : {
1575 12708 : std::map<CPLString, int> oMapNameToTargetFieldIndex;
1576 12708 : std::map<CPLString, int> oMapNameToTargetFieldIndexUC;
1577 6354 : const int nFieldCount = GetFieldCount();
1578 94825 : for (int i = 0; i < nFieldCount; i++)
1579 : {
1580 88471 : const OGRFieldDefn *poFldDefn = GetFieldDefn(i);
1581 88471 : if (poFldDefn == nullptr)
1582 0 : continue;
1583 88471 : const char *pszName = poFldDefn->GetNameRef();
1584 :
1585 : // In the insane case where there are several matches, arbitrarily
1586 : // decide for the first one (preserve past behavior)
1587 88471 : if (oMapNameToTargetFieldIndex.find(pszName) ==
1588 176942 : oMapNameToTargetFieldIndex.end())
1589 : {
1590 88471 : oMapNameToTargetFieldIndex[pszName] = i;
1591 : }
1592 : }
1593 12708 : std::vector<int> aoMapSrcToTargetIdx;
1594 6354 : const int nSrcFieldCount = poSrcFDefn->GetFieldCount();
1595 6354 : aoMapSrcToTargetIdx.resize(nSrcFieldCount);
1596 94018 : for (int i = 0; i < nSrcFieldCount; i++)
1597 : {
1598 87664 : const OGRFieldDefn *poSrcFldDefn = poSrcFDefn->GetFieldDefn(i);
1599 87664 : if (poSrcFldDefn == nullptr)
1600 0 : continue;
1601 87664 : const char *pszSrcName = poSrcFldDefn->GetNameRef();
1602 :
1603 87664 : auto oIter = oMapNameToTargetFieldIndex.find(pszSrcName);
1604 87664 : if (oIter == oMapNameToTargetFieldIndex.end())
1605 : {
1606 : // Build case insensitive map only if needed
1607 4954 : if (oMapNameToTargetFieldIndexUC.empty())
1608 : {
1609 6935 : for (int j = 0; j < nFieldCount; j++)
1610 : {
1611 5694 : const OGRFieldDefn *poFldDefn = GetFieldDefn(j);
1612 5694 : if (poFldDefn == nullptr)
1613 0 : continue;
1614 : oMapNameToTargetFieldIndexUC
1615 5694 : [CPLString(poFldDefn->GetNameRef()).toupper()] = j;
1616 : }
1617 : }
1618 : oIter = oMapNameToTargetFieldIndexUC.find(
1619 4954 : CPLString(pszSrcName).toupper());
1620 4954 : if (oIter == oMapNameToTargetFieldIndexUC.end())
1621 : {
1622 1846 : if (!bForgiving)
1623 : {
1624 0 : return std::vector<int>();
1625 : }
1626 1846 : aoMapSrcToTargetIdx[i] = -1;
1627 : }
1628 : else
1629 : {
1630 3108 : aoMapSrcToTargetIdx[i] = oIter->second;
1631 : }
1632 : }
1633 : else
1634 : {
1635 82710 : aoMapSrcToTargetIdx[i] = oIter->second;
1636 : }
1637 : }
1638 6354 : return aoMapSrcToTargetIdx;
1639 : }
1640 :
1641 : /************************************************************************/
1642 : /* OGRFeatureDefn::Seal() */
1643 : /************************************************************************/
1644 :
1645 : /** Seal a OGRFeatureDefn.
1646 : *
1647 : * A sealed OGRFeatureDefn can not be modified while it is sealed.
1648 : *
1649 : * This method also call OGRFieldDefn::Seal() and OGRGeomFieldDefn::Seal()
1650 : * on its fields and geometry fields.
1651 : *
1652 : * This method should only be called by driver implementations.
1653 : *
1654 : * @param bSealFields Whether fields and geometry fields should be sealed.
1655 : * This is generally desirabled, but in case of deferred
1656 : * resolution of them, this parameter should be set to false.
1657 : * @since GDAL 3.9
1658 : */
1659 49286 : void OGRFeatureDefn::Seal(bool bSealFields)
1660 : {
1661 49286 : if (m_bSealed)
1662 : {
1663 1 : CPLError(CE_Failure, CPLE_AppDefined,
1664 : "OGRFeatureDefn::Seal(): the object is already sealed");
1665 1 : return;
1666 : }
1667 49285 : if (bSealFields)
1668 : {
1669 37781 : const int nFieldCount = GetFieldCount();
1670 4745850 : for (int i = 0; i < nFieldCount; ++i)
1671 4708070 : GetFieldDefn(i)->Seal();
1672 37781 : const int nGeomFieldCount = GetGeomFieldCount();
1673 65558 : for (int i = 0; i < nGeomFieldCount; ++i)
1674 27777 : GetGeomFieldDefn(i)->Seal();
1675 : }
1676 49285 : m_bSealed = true;
1677 : }
1678 :
1679 : /************************************************************************/
1680 : /* OGRFeatureDefn::Unseal() */
1681 : /************************************************************************/
1682 :
1683 : /** Unseal a OGRFeatureDefn.
1684 : *
1685 : * Undo OGRFeatureDefn::Seal()
1686 : *
1687 : * This method also call OGRFieldDefn::Unseal() and OGRGeomFieldDefn::Unseal()
1688 : * on its fields and geometry fields.
1689 : *
1690 : * Using GetTemporaryUnsealer() is recommended for most use cases.
1691 : *
1692 : * This method should only be called by driver implementations.
1693 : *
1694 : * @param bUnsealFields Whether fields and geometry fields should be unsealed.
1695 : * This is generally desirabled, but in case of deferred
1696 : * resolution of them, this parameter should be set to
1697 : * false.
1698 : * @since GDAL 3.9
1699 : */
1700 25254 : void OGRFeatureDefn::Unseal(bool bUnsealFields)
1701 : {
1702 25254 : if (!m_bSealed)
1703 : {
1704 1 : CPLError(CE_Failure, CPLE_AppDefined,
1705 : "OGRFeatureDefn::Unseal(): the object is already unsealed");
1706 1 : return;
1707 : }
1708 25253 : m_bSealed = false;
1709 25253 : if (bUnsealFields)
1710 : {
1711 25208 : const int nFieldCount = GetFieldCount();
1712 4696740 : for (int i = 0; i < nFieldCount; ++i)
1713 4671530 : GetFieldDefn(i)->Unseal();
1714 25208 : const int nGeomFieldCount = GetGeomFieldCount();
1715 41801 : for (int i = 0; i < nGeomFieldCount; ++i)
1716 16593 : GetGeomFieldDefn(i)->Unseal();
1717 : }
1718 : }
1719 :
1720 : /************************************************************************/
1721 : /* OGRFeatureDefn::GetTemporaryUnsealer() */
1722 : /************************************************************************/
1723 :
1724 : /** Return an object that temporary unseals the OGRFeatureDefn
1725 : *
1726 : * The returned object calls Unseal() initially, and when it is destroyed
1727 : * it calls Seal().
1728 : * This method should be called on a OGRFeatureDefn that has been sealed
1729 : * previously.
1730 : * GetTemporaryUnsealer() calls may be nested, in which case only the first
1731 : * one has an effect (similarly to a recursive mutex locked in a nested way
1732 : * from the same thread).
1733 : *
1734 : * This method should only be called by driver implementations.
1735 : *
1736 : * It is also possible to use the helper method whileUnsealing(). Example:
1737 : * whileUnsealing(poFeatureDefn)->some_method()
1738 : *
1739 : * @param bSealFields Whether fields and geometry fields should be unsealed and
1740 : * resealed.
1741 : * This is generally desirabled, but in case of deferred
1742 : * resolution of them, this parameter should be set to false.
1743 : * @since GDAL 3.9
1744 : */
1745 : OGRFeatureDefn::TemporaryUnsealer
1746 25256 : OGRFeatureDefn::GetTemporaryUnsealer(bool bSealFields)
1747 : {
1748 25256 : return TemporaryUnsealer(this, bSealFields);
1749 : }
1750 :
1751 : /*! @cond Doxygen_Suppress */
1752 :
1753 : /************************************************************************/
1754 : /* TemporaryUnsealer::TemporaryUnsealer() */
1755 : /************************************************************************/
1756 :
1757 25256 : OGRFeatureDefn::TemporaryUnsealer::TemporaryUnsealer(
1758 25256 : OGRFeatureDefn *poFeatureDefn, bool bSealFields)
1759 25256 : : m_poFeatureDefn(poFeatureDefn), m_bSealFields(bSealFields)
1760 : {
1761 25256 : if (m_poFeatureDefn->m_nTemporaryUnsealCount == 0)
1762 : {
1763 25254 : if (m_poFeatureDefn->m_bSealed)
1764 : {
1765 25253 : m_poFeatureDefn->Unseal(m_bSealFields);
1766 25253 : m_poFeatureDefn->m_nTemporaryUnsealCount = 1;
1767 : }
1768 : else
1769 : {
1770 1 : CPLError(CE_Warning, CPLE_AppDefined,
1771 : "OGRFeatureDefn::GetTemporaryUnsealer() called on "
1772 : "a unsealed object");
1773 1 : m_poFeatureDefn->m_nTemporaryUnsealCount = -1;
1774 : }
1775 : }
1776 2 : else if (m_poFeatureDefn->m_nTemporaryUnsealCount > 0)
1777 : {
1778 : // m_poFeatureDefn is already under an active TemporaryUnsealer.
1779 : // Just increment the counter
1780 1 : ++m_poFeatureDefn->m_nTemporaryUnsealCount;
1781 : }
1782 : else
1783 : {
1784 : // m_poFeatureDefn is already under a misused TemporaryUnsealer.
1785 : // Decrement again the counter
1786 1 : --m_poFeatureDefn->m_nTemporaryUnsealCount;
1787 : }
1788 25256 : }
1789 :
1790 : /************************************************************************/
1791 : /* TemporaryUnsealer::~TemporaryUnsealer() */
1792 : /************************************************************************/
1793 :
1794 50512 : OGRFeatureDefn::TemporaryUnsealer::~TemporaryUnsealer()
1795 : {
1796 25256 : if (m_poFeatureDefn->m_nTemporaryUnsealCount > 0)
1797 : {
1798 : // m_poFeatureDefn is already under an active TemporaryUnsealer.
1799 : // Decrement increment the counter and unseal when it reaches 0
1800 25254 : --m_poFeatureDefn->m_nTemporaryUnsealCount;
1801 25254 : if (m_poFeatureDefn->m_nTemporaryUnsealCount == 0)
1802 : {
1803 25253 : if (!m_poFeatureDefn->m_bSealed)
1804 : {
1805 25253 : m_poFeatureDefn->Seal(m_bSealFields);
1806 : }
1807 : else
1808 : {
1809 0 : CPLError(
1810 : CE_Failure, CPLE_AppDefined,
1811 : "Misuse of sealing functionality. "
1812 : "OGRFeatureDefn::TemporaryUnsealer::~TemporaryUnsealer() "
1813 : "claled on a sealed object");
1814 : }
1815 : }
1816 : }
1817 : else
1818 : {
1819 : // m_poFeatureDefn is already under a misused TemporaryUnsealer.
1820 : // Increment the counter
1821 2 : CPLAssert(m_poFeatureDefn->m_nTemporaryUnsealCount < 0);
1822 2 : ++m_poFeatureDefn->m_nTemporaryUnsealCount;
1823 : }
1824 25256 : }
1825 :
1826 : /*! @endcond */
|