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