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