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