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