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 CPL_CVSID("$Id: ogrfeaturedefn.cpp 2d686cadda65aebe1463aa2b7aaf7bfbcf992cdc 2020-10-03 17:16:57 -0400 Dylan Sutton $")
46 
47 /************************************************************************/
48 /*                           OGRFeatureDefn()                           */
49 /************************************************************************/
50 
51 /**
52  * \brief Constructor.
53  *
54  * The OGRFeatureDefn maintains a reference count, but this starts at
55  * zero.  It is mainly intended to represent a count of OGRFeature's
56  * based on this definition.
57  *
58  * This method is the same as the C function OGR_FD_Create().
59  *
60  * @param pszName the name to be assigned to this layer/class.  It does not
61  * need to be unique.
62  */
63 
OGRFeatureDefn(const char * pszName)64 OGRFeatureDefn::OGRFeatureDefn( const char * pszName ) :
65     nRefCount(0),
66     nFieldCount(0),
67     papoFieldDefn(nullptr),
68     nGeomFieldCount(1),
69     papoGeomFieldDefn(nullptr),
70     pszFeatureClassName(nullptr),
71     bIgnoreStyle(FALSE)
72 {
73     pszFeatureClassName = CPLStrdup( pszName );
74     papoGeomFieldDefn =
75         static_cast<OGRGeomFieldDefn**>(CPLMalloc(sizeof(OGRGeomFieldDefn*)));
76     papoGeomFieldDefn[0] = new OGRGeomFieldDefn("", wkbUnknown);
77 }
78 
79 /************************************************************************/
80 /*                           OGR_FD_Create()                            */
81 /************************************************************************/
82 /**
83  * \brief Create a new feature definition object to hold the field definitions.
84  *
85  * The OGRFeatureDefn maintains a reference count, but this starts at
86  * zero, and should normally be incremented by the owner.
87  *
88  * This function is the same as the C++ method
89  * OGRFeatureDefn::OGRFeatureDefn().
90  *
91  * @param pszName the name to be assigned to this layer/class.  It does not
92  * need to be unique.
93  * @return handle to the newly created feature definition.
94  */
95 
OGR_FD_Create(const char * pszName)96 OGRFeatureDefnH OGR_FD_Create( const char *pszName )
97 
98 {
99     return OGRFeatureDefn::ToHandle(new OGRFeatureDefn(pszName));
100 }
101 
102 /************************************************************************/
103 /*                          ~OGRFeatureDefn()                           */
104 /************************************************************************/
105 
~OGRFeatureDefn()106 OGRFeatureDefn::~OGRFeatureDefn()
107 
108 {
109     if( nRefCount != 0 )
110     {
111         CPLDebug( "OGRFeatureDefn",
112                   "OGRFeatureDefn %s with a ref count of %d deleted!",
113                   pszFeatureClassName, nRefCount );
114     }
115 
116     CPLFree( pszFeatureClassName );
117 
118     for( int i = 0; i < nFieldCount; i++ )
119     {
120         delete papoFieldDefn[i];
121     }
122 
123     CPLFree( papoFieldDefn );
124 
125     for( int i = 0; i < nGeomFieldCount; i++ )
126     {
127         delete papoGeomFieldDefn[i];
128     }
129 
130     CPLFree( papoGeomFieldDefn );
131 }
132 
133 /************************************************************************/
134 /*                           OGR_FD_Destroy()                           */
135 /************************************************************************/
136 /**
137  * \brief Destroy a feature definition object and release all memory associated
138  * with it.
139  *
140  * This function is the same as the C++ method
141  * OGRFeatureDefn::~OGRFeatureDefn().
142  *
143  * @param hDefn handle to the feature definition to be destroyed.
144  */
145 
OGR_FD_Destroy(OGRFeatureDefnH hDefn)146 void OGR_FD_Destroy( OGRFeatureDefnH hDefn )
147 
148 {
149     delete OGRFeatureDefn::FromHandle(hDefn);
150 }
151 
152 /************************************************************************/
153 /*                              Release()                               */
154 /************************************************************************/
155 
156 /**
157  * \fn void OGRFeatureDefn::Release();
158  *
159  * \brief Drop a reference to this object, and destroy if no longer referenced.
160  */
161 
Release()162 void OGRFeatureDefn::Release()
163 
164 {
165     if( Dereference() <= 0 )
166         delete this;
167 }
168 
169 /************************************************************************/
170 /*                           OGR_FD_Release()                           */
171 /************************************************************************/
172 
173 /**
174  * \brief Drop a reference, and destroy if unreferenced.
175  *
176  * This function is the same as the C++ method OGRFeatureDefn::Release().
177  *
178  * @param hDefn handle to the feature definition to be released.
179  */
180 
OGR_FD_Release(OGRFeatureDefnH hDefn)181 void OGR_FD_Release( OGRFeatureDefnH hDefn )
182 
183 {
184     OGRFeatureDefn::FromHandle(hDefn)->Release();
185 }
186 
187 /************************************************************************/
188 /*                               Clone()                                */
189 /************************************************************************/
190 
191 /**
192  * \fn OGRFeatureDefn *OGRFeatureDefn::Clone() const;
193  *
194  * \brief Create a copy of this feature definition.
195  *
196  * Creates a deep copy of the feature definition.
197  *
198  * @return the copy.
199  */
200 
Clone() const201 OGRFeatureDefn *OGRFeatureDefn::Clone() const
202 
203 {
204     OGRFeatureDefn *poCopy = new OGRFeatureDefn( GetName() );
205 
206     GetFieldCount();
207     for( int i = 0; i < nFieldCount; i++ )
208         poCopy->AddFieldDefn( const_cast<OGRFieldDefn*>(GetFieldDefn( i )) );
209 
210     // Remove the default geometry field created instantiation.
211     poCopy->DeleteGeomFieldDefn(0);
212     GetGeomFieldCount();
213     for( int i = 0; i < nGeomFieldCount; i++ )
214         poCopy->AddGeomFieldDefn( const_cast<OGRGeomFieldDefn*>(GetGeomFieldDefn( i )) );
215 
216     return poCopy;
217 }
218 
219 /************************************************************************/
220 /*                              SetName()                               */
221 /************************************************************************/
222 
223 /**
224  * \brief Change name of this OGRFeatureDefn.
225  *
226  * @param pszName feature definition name
227  * @since GDAL 2.3
228  */
SetName(const char * pszName)229 void OGRFeatureDefn::SetName( const char* pszName )
230 {
231     CPLFree(pszFeatureClassName);
232     pszFeatureClassName = CPLStrdup(pszName);
233 }
234 
235 /************************************************************************/
236 /*                              GetName()                               */
237 /************************************************************************/
238 
239 /**
240  * \fn const char *OGRFeatureDefn::GetName();
241  *
242  * \brief Get name of this OGRFeatureDefn.
243  *
244  * This method is the same as the C function OGR_FD_GetName().
245  *
246  * @return the name.  This name is internal and should not be modified, or
247  * freed.
248  */
GetName() const249 const char * OGRFeatureDefn::GetName() const
250 {
251     return pszFeatureClassName;
252 }
253 
254 /************************************************************************/
255 /*                           OGR_FD_GetName()                           */
256 /************************************************************************/
257 /**
258  * \brief Get name of the OGRFeatureDefn passed as an argument.
259  *
260  * This function is the same as the C++ method OGRFeatureDefn::GetName().
261  *
262  * @param hDefn handle to the feature definition to get the name from.
263  * @return the name.  This name is internal and should not be modified, or
264  * freed.
265  */
266 
OGR_FD_GetName(OGRFeatureDefnH hDefn)267 const char *OGR_FD_GetName( OGRFeatureDefnH hDefn )
268 
269 {
270     return OGRFeatureDefn::FromHandle(hDefn)->GetName();
271 }
272 
273 /************************************************************************/
274 /*                           GetFieldCount()                            */
275 /************************************************************************/
276 
277 /**
278  * \fn int OGRFeatureDefn::GetFieldCount() const;
279  *
280  * \brief Fetch number of fields on this feature.
281  *
282  * This method is the same as the C function OGR_FD_GetFieldCount().
283  * @return count of fields.
284  */
285 
GetFieldCount() const286 int OGRFeatureDefn::GetFieldCount() const
287 {
288     return nFieldCount;
289 }
290 
291 /************************************************************************/
292 /*                        OGR_FD_GetFieldCount()                        */
293 /************************************************************************/
294 
295 /**
296  * \brief Fetch number of fields on the passed feature definition.
297  *
298  * This function is the same as the C++ OGRFeatureDefn::GetFieldCount().
299  *
300  * @param hDefn handle to the feature definition to get the fields count from.
301  * @return count of fields.
302  */
303 
OGR_FD_GetFieldCount(OGRFeatureDefnH hDefn)304 int OGR_FD_GetFieldCount( OGRFeatureDefnH hDefn )
305 
306 {
307 #ifdef OGRAPISPY_ENABLED
308     if( bOGRAPISpyEnabled )
309         OGRAPISpy_FD_GetFieldCount(hDefn);
310 #endif
311 
312     return OGRFeatureDefn::FromHandle(hDefn)->GetFieldCount();
313 }
314 
315 /************************************************************************/
316 /*                            GetFieldDefn()                            */
317 /************************************************************************/
318 
319 /**
320  * \brief Fetch field definition.
321  *
322  * This method is the same as the C function OGR_FD_GetFieldDefn().
323  *
324  * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
325  *
326  * @return a pointer to an internal field definition object or NULL if invalid
327  * index.  This object should not be modified or freed by the application.
328  */
329 
GetFieldDefn(int iField)330 OGRFieldDefn *OGRFeatureDefn::GetFieldDefn( int iField )
331 
332 {
333     if( iField < 0 || iField >= GetFieldCount() )
334     {
335         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
336         return nullptr;
337     }
338 
339     return papoFieldDefn[iField];
340 }
341 
342 /**
343  * \brief Fetch field definition.
344  *
345  * This method is the same as the C function OGR_FD_GetFieldDefn().
346  *
347  * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
348  *
349  * @return a pointer to an internal field definition object or NULL if invalid
350  * index.  This object should not be modified or freed by the application.
351  *
352  * @since GDAL 2.3
353  */
354 
GetFieldDefn(int iField) const355 const OGRFieldDefn *OGRFeatureDefn::GetFieldDefn( int iField ) const
356 
357 {
358     if( iField < 0 || iField >= GetFieldCount() )
359     {
360         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
361         return nullptr;
362     }
363 
364     return papoFieldDefn[iField];
365 }
366 
367 /************************************************************************/
368 /*                        OGR_FD_GetFieldDefn()                         */
369 /************************************************************************/
370 
371 /**
372  * \brief Fetch field definition of the passed feature definition.
373  *
374  * This function is the same as the C++ method
375  * OGRFeatureDefn::GetFieldDefn().
376  *
377  * @param hDefn handle to the feature definition to get the field definition
378  * from.
379  * @param iField the field to fetch, between 0 and GetFieldCount()-1.
380  *
381  * @return a handle to an internal field definition object or NULL if invalid
382  * index.  This object should not be modified or freed by the application.
383  */
384 
OGR_FD_GetFieldDefn(OGRFeatureDefnH hDefn,int iField)385 OGRFieldDefnH OGR_FD_GetFieldDefn( OGRFeatureDefnH hDefn, int iField )
386 
387 {
388     OGRFieldDefnH hFieldDefnH =
389         OGRFieldDefn::ToHandle(
390             OGRFeatureDefn::FromHandle(hDefn)->GetFieldDefn(iField));
391 
392 #ifdef OGRAPISPY_ENABLED
393     if( bOGRAPISpyEnabled )
394         OGRAPISpy_FD_GetFieldDefn(hDefn, iField, hFieldDefnH);
395 #endif
396 
397     return hFieldDefnH;
398 }
399 
400 //! @cond Doxygen_Suppress
401 
402 /************************************************************************/
403 /*                        ReserveSpaceForFields()                       */
404 /************************************************************************/
405 
ReserveSpaceForFields(int nFieldCountIn)406 void OGRFeatureDefn::ReserveSpaceForFields(int nFieldCountIn)
407 {
408     papoFieldDefn = static_cast<OGRFieldDefn **>(
409         CPLRealloc(papoFieldDefn,
410                    sizeof(void *) * std::max(nFieldCount, nFieldCountIn)));
411 }
412 //! @endcond
413 
414 /************************************************************************/
415 /*                            AddFieldDefn()                            */
416 /************************************************************************/
417 
418 /**
419  * \brief Add a new field definition.
420  *
421  * To add a new field definition to a layer definition, do not use this
422  * function directly, but use OGRLayer::CreateField() instead.
423  *
424  * This method should only be called while there are no OGRFeature
425  * objects in existence based on this OGRFeatureDefn.  The OGRFieldDefn
426  * passed in is copied, and remains the responsibility of the caller.
427  *
428  * This method is the same as the C function OGR_FD_AddFieldDefn().
429  *
430  * @param poNewDefn the definition of the new field.
431  */
432 
AddFieldDefn(OGRFieldDefn * poNewDefn)433 void OGRFeatureDefn::AddFieldDefn( OGRFieldDefn * poNewDefn )
434 
435 {
436     GetFieldCount();
437     papoFieldDefn = static_cast<OGRFieldDefn **>(
438         CPLRealloc(papoFieldDefn, sizeof(void *) * (nFieldCount + 1)));
439 
440     papoFieldDefn[nFieldCount] = new OGRFieldDefn( poNewDefn );
441     nFieldCount++;
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 
OGR_FD_AddFieldDefn(OGRFeatureDefnH hDefn,OGRFieldDefnH hNewField)465 void OGR_FD_AddFieldDefn( OGRFeatureDefnH hDefn, OGRFieldDefnH hNewField )
466 
467 {
468     OGRFeatureDefn::FromHandle(hDefn)->
469         AddFieldDefn( OGRFieldDefn::FromHandle(hNewField));
470 }
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 
DeleteFieldDefn(int iField)492 OGRErr OGRFeatureDefn::DeleteFieldDefn( int iField )
493 
494 {
495     if( iField < 0 || iField >= GetFieldCount() )
496         return OGRERR_FAILURE;
497 
498     delete papoFieldDefn[iField];
499     papoFieldDefn[iField] = nullptr;
500 
501     if( iField < nFieldCount - 1 )
502     {
503         memmove(papoFieldDefn + iField,
504                 papoFieldDefn + iField + 1,
505                 (nFieldCount - 1 - iField) * sizeof(void *));
506     }
507 
508     nFieldCount--;
509 
510     return OGRERR_NONE;
511 }
512 
513 /************************************************************************/
514 /*                       OGR_FD_DeleteFieldDefn()                       */
515 /************************************************************************/
516 
517 /**
518  * \brief Delete an existing field definition.
519  *
520  * To delete an existing field definition from a layer definition, do not use
521  * this function directly, but use OGR_L_DeleteField() instead.
522  *
523  * This method should only be called while there are no OGRFeature
524  * objects in existence based on this OGRFeatureDefn.
525  *
526  * This method is the same as the C++ method OGRFeatureDefn::DeleteFieldDefn().
527  *
528  * @param hDefn handle to the feature definition.
529  * @param iField the index of the field definition.
530  * @return OGRERR_NONE in case of success.
531  * @since OGR 1.9.0
532  */
533 
OGR_FD_DeleteFieldDefn(OGRFeatureDefnH hDefn,int iField)534 OGRErr OGR_FD_DeleteFieldDefn( OGRFeatureDefnH hDefn, int iField )
535 
536 {
537     return OGRFeatureDefn::FromHandle(hDefn)->DeleteFieldDefn(iField);
538 }
539 
540 /************************************************************************/
541 /*                         ReorderFieldDefns()                          */
542 /************************************************************************/
543 
544 /**
545  * \brief Reorder the field definitions in the array of the feature definition
546  *
547  * To reorder the field definitions in a layer definition, do not use this
548  * function directly, but use OGR_L_ReorderFields() instead.
549  *
550  * This method should only be called while there are no OGRFeature
551  * objects in existence based on this OGRFeatureDefn.
552  *
553  * This method is the same as the C function OGR_FD_ReorderFieldDefns().
554  *
555  * @param panMap an array of GetFieldCount() elements which
556  * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
557  * for each field definition at position i after reordering,
558  * its position before reordering was panMap[i].
559  * @return OGRERR_NONE in case of success.
560  * @since OGR 1.9.0
561  */
562 
ReorderFieldDefns(int * panMap)563 OGRErr OGRFeatureDefn::ReorderFieldDefns( int* panMap )
564 
565 {
566     if( GetFieldCount() == 0 )
567         return OGRERR_NONE;
568 
569     const OGRErr eErr = OGRCheckPermutation(panMap, nFieldCount);
570     if( eErr != OGRERR_NONE )
571         return eErr;
572 
573     OGRFieldDefn** papoFieldDefnNew = static_cast<OGRFieldDefn**>(
574         CPLMalloc(sizeof(OGRFieldDefn*) * nFieldCount));
575 
576     for( int i = 0; i < nFieldCount; i++ )
577     {
578         papoFieldDefnNew[i] = papoFieldDefn[panMap[i]];
579     }
580 
581     CPLFree(papoFieldDefn);
582     papoFieldDefn = papoFieldDefnNew;
583 
584     return OGRERR_NONE;
585 }
586 
587 /************************************************************************/
588 /*                     OGR_FD_ReorderFieldDefns()                       */
589 /************************************************************************/
590 
591 /**
592  * \brief Reorder the field definitions in the array of the feature definition
593  *
594  * To reorder the field definitions in a layer definition, do not use this
595  * function directly, but use OGR_L_ReorderFields() instead.
596  *
597  * This method should only be called while there are no OGRFeature
598  * objects in existence based on this OGRFeatureDefn.
599  *
600  * This method is the same as the C++ method
601  * OGRFeatureDefn::ReorderFieldDefns().
602  *
603  * @param hDefn handle to the feature definition.
604  * @param panMap an array of GetFieldCount() elements which
605  * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
606  * for each field definition at position i after reordering,
607  * its position before reordering was panMap[i].
608  * @return OGRERR_NONE in case of success.
609  * @since OGR 2.1.0
610  */
611 
OGR_FD_ReorderFieldDefns(OGRFeatureDefnH hDefn,int * panMap)612 OGRErr OGR_FD_ReorderFieldDefns( OGRFeatureDefnH hDefn, int* panMap )
613 
614 {
615     return OGRFeatureDefn::FromHandle(hDefn)->ReorderFieldDefns(panMap);
616 }
617 
618 /************************************************************************/
619 /*                         GetGeomFieldCount()                          */
620 /************************************************************************/
621 
622 /**
623  * \fn int OGRFeatureDefn::GetGeomFieldCount() const;
624  *
625  * \brief Fetch number of geometry fields on this feature.
626  *
627  * This method is the same as the C function OGR_FD_GetGeomFieldCount().
628  * @return count of geometry fields.
629  *
630  * @since GDAL 1.11
631  */
GetGeomFieldCount() const632 int OGRFeatureDefn::GetGeomFieldCount() const
633 {
634     return nGeomFieldCount;
635 }
636 
637 /************************************************************************/
638 /*                      OGR_FD_GetGeomFieldCount()                      */
639 /************************************************************************/
640 
641 /**
642  * \brief Fetch number of geometry fields on the passed feature definition.
643  *
644  * This function is the same as the C++ OGRFeatureDefn::GetGeomFieldCount().
645  *
646  * @param hDefn handle to the feature definition to get the fields count from.
647  * @return count of geometry fields.
648  *
649  * @since GDAL 1.11
650  */
651 
OGR_FD_GetGeomFieldCount(OGRFeatureDefnH hDefn)652 int OGR_FD_GetGeomFieldCount( OGRFeatureDefnH hDefn )
653 
654 {
655 #ifdef OGRAPISPY_ENABLED
656     if( bOGRAPISpyEnabled )
657         OGRAPISpy_FD_GetGeomFieldCount(hDefn);
658 #endif
659 
660     return OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldCount();
661 }
662 
663 /************************************************************************/
664 /*                           GetGeomFieldDefn()                         */
665 /************************************************************************/
666 
667 /**
668  * \brief Fetch geometry field definition.
669  *
670  * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
671  *
672  * @param iGeomField the geometry field to fetch, between 0 and
673  * GetGeomFieldCount() - 1.
674  *
675  * @return a pointer to an internal field definition object or NULL if invalid
676  * index.  This object should not be modified or freed by the application.
677  *
678  * @since GDAL 1.11
679  */
680 
GetGeomFieldDefn(int iGeomField)681 OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn( int iGeomField )
682 
683 {
684     if( iGeomField < 0 || iGeomField >= GetGeomFieldCount() )
685     {
686         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
687         return nullptr;
688     }
689 
690     return papoGeomFieldDefn[iGeomField];
691 }
692 
693 /**
694  * \brief Fetch geometry field definition.
695  *
696  * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
697  *
698  * @param iGeomField the geometry field to fetch, between 0 and
699  * GetGeomFieldCount() - 1.
700  *
701  * @return a pointer to an internal field definition object or NULL if invalid
702  * index.  This object should not be modified or freed by the application.
703  *
704  * @since GDAL 2.3
705  */
706 
GetGeomFieldDefn(int iGeomField) const707 const OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn( int iGeomField ) const
708 
709 {
710     if( iGeomField < 0 || iGeomField >= GetGeomFieldCount() )
711     {
712         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
713         return nullptr;
714     }
715 
716     return papoGeomFieldDefn[iGeomField];
717 }
718 /************************************************************************/
719 /*                      OGR_FD_GetGeomFieldDefn()                       */
720 /************************************************************************/
721 
722 /**
723  * \brief Fetch geometry field definition of the passed feature definition.
724  *
725  * This function is the same as the C++ method
726  * OGRFeatureDefn::GetGeomFieldDefn().
727  *
728  * @param hDefn handle to the feature definition to get the field definition
729  * from.
730  * @param iGeomField the geometry field to fetch, between 0 and
731  * GetGeomFieldCount() - 1.
732  *
733  * @return a handle to an internal field definition object or NULL if invalid
734  * index.  This object should not be modified or freed by the application.
735  *
736  * @since GDAL 1.11
737  */
738 
OGR_FD_GetGeomFieldDefn(OGRFeatureDefnH hDefn,int iGeomField)739 OGRGeomFieldDefnH OGR_FD_GetGeomFieldDefn( OGRFeatureDefnH hDefn,
740                                            int iGeomField )
741 
742 {
743     OGRGeomFieldDefnH hGeomField =
744         OGRGeomFieldDefn::ToHandle(
745             OGRFeatureDefn::FromHandle(hDefn)->
746                 GetGeomFieldDefn(iGeomField));
747 
748 #ifdef OGRAPISPY_ENABLED
749     if( bOGRAPISpyEnabled )
750         OGRAPISpy_FD_GetGeomFieldDefn(hDefn, iGeomField, hGeomField);
751 #endif
752 
753     return hGeomField;
754 }
755 
756 /************************************************************************/
757 /*                          AddGeomFieldDefn()                          */
758 /************************************************************************/
759 
760 /**
761  * \brief Add a new geometry field definition.
762  *
763  * To add a new geometry field definition to a layer definition, do not use this
764  * function directly, but use OGRLayer::CreateGeomField() instead.
765  *
766  * This method does an internal copy of the passed geometry field definition,
767  * unless bCopy is set to FALSE (in which case it takes ownership of the
768  * field definition.
769  *
770  * This method should only be called while there are no OGRFeature
771  * objects in existence based on this OGRFeatureDefn.  The OGRGeomFieldDefn
772  * passed in is copied, and remains the responsibility of the caller.
773  *
774  * This method is the same as the C function OGR_FD_AddGeomFieldDefn().
775  *
776  * @param poNewDefn the definition of the new geometry field.
777  * @param bCopy whether poNewDefn should be copied.
778  *
779  * @since GDAL 1.11
780  */
781 
AddGeomFieldDefn(OGRGeomFieldDefn * poNewDefn,int bCopy)782 void OGRFeatureDefn::AddGeomFieldDefn( OGRGeomFieldDefn * poNewDefn,
783                                        int bCopy )
784 {
785     GetGeomFieldCount();
786     papoGeomFieldDefn = static_cast<OGRGeomFieldDefn **>(
787         CPLRealloc( papoGeomFieldDefn, sizeof(void*) * (nGeomFieldCount + 1) ));
788 
789     papoGeomFieldDefn[nGeomFieldCount] = bCopy ?
790         new OGRGeomFieldDefn( poNewDefn ) : poNewDefn;
791     nGeomFieldCount++;
792 }
793 
794 /************************************************************************/
795 /*                      OGR_FD_AddGeomFieldDefn()                       */
796 /************************************************************************/
797 
798 /**
799  * \brief Add a new field definition to the passed feature definition.
800  *
801  * To add a new field definition to a layer definition, do not use this
802  * function directly, but use OGR_L_CreateGeomField() instead.
803  *
804  * This function should only be called while there are no OGRFeature
805  * objects in existence based on this OGRFeatureDefn.  The OGRGeomFieldDefn
806  * passed in is copied, and remains the responsibility of the caller.
807  *
808  * This function is the same as the C++ method
809  * OGRFeatureDefn::AddGeomFieldDefn().
810  *
811  * @param hDefn handle to the feature definition to add the geometry field
812  * definition to.
813  * @param hNewGeomField handle to the new field definition.
814  *
815  * @since GDAL 1.11
816  */
817 
OGR_FD_AddGeomFieldDefn(OGRFeatureDefnH hDefn,OGRGeomFieldDefnH hNewGeomField)818 void OGR_FD_AddGeomFieldDefn( OGRFeatureDefnH hDefn,
819                               OGRGeomFieldDefnH hNewGeomField )
820 
821 {
822     OGRFeatureDefn::FromHandle(hDefn)->AddGeomFieldDefn(
823         OGRGeomFieldDefn::FromHandle(hNewGeomField));
824 }
825 
826 /************************************************************************/
827 /*                         DeleteGeomFieldDefn()                        */
828 /************************************************************************/
829 
830 /**
831  * \brief Delete an existing geometry field definition.
832  *
833  * To delete an existing field definition from a layer definition, do not use
834  * this function directly, but use OGRLayer::DeleteGeomField() instead.
835  *
836  * This method should only be called while there are no OGRFeature
837  * objects in existence based on this OGRFeatureDefn.
838  *
839  * This method is the same as the C function OGR_FD_DeleteGeomFieldDefn().
840  *
841  * @param iGeomField the index of the geometry field definition.
842  * @return OGRERR_NONE in case of success.
843  *
844  * @since GDAL 1.11
845  */
846 
DeleteGeomFieldDefn(int iGeomField)847 OGRErr OGRFeatureDefn::DeleteGeomFieldDefn( int iGeomField )
848 
849 {
850     if( iGeomField < 0 || iGeomField >= GetGeomFieldCount() )
851         return OGRERR_FAILURE;
852 
853     delete papoGeomFieldDefn[iGeomField];
854     papoGeomFieldDefn[iGeomField] = nullptr;
855 
856     if( iGeomField < nGeomFieldCount - 1 )
857     {
858         memmove(papoGeomFieldDefn + iGeomField,
859                 papoGeomFieldDefn + iGeomField + 1,
860                 (nGeomFieldCount - 1 - iGeomField) * sizeof(void*));
861     }
862 
863     nGeomFieldCount--;
864 
865     return OGRERR_NONE;
866 }
867 
868 /************************************************************************/
869 /*                     OGR_FD_DeleteGeomFieldDefn()                     */
870 /************************************************************************/
871 
872 /**
873  * \brief Delete an existing geometry field definition.
874  *
875  * To delete an existing geometry field definition from a layer definition, do
876  * not use this function directly, but use OGR_L_DeleteGeomField() instead
877  * (*not implemented yet*).
878  *
879  * This method should only be called while there are no OGRFeature
880  * objects in existence based on this OGRFeatureDefn.
881  *
882  * This method is the same as the C++ method
883  * OGRFeatureDefn::DeleteGeomFieldDefn().
884  *
885  * @param hDefn handle to the feature definition.
886  * @param iGeomField the index of the geometry field definition.
887  * @return OGRERR_NONE in case of success.
888  *
889  * @since GDAL 1.11
890  */
891 
OGR_FD_DeleteGeomFieldDefn(OGRFeatureDefnH hDefn,int iGeomField)892 OGRErr OGR_FD_DeleteGeomFieldDefn( OGRFeatureDefnH hDefn, int iGeomField )
893 
894 {
895     return OGRFeatureDefn::FromHandle(hDefn)->
896         DeleteGeomFieldDefn(iGeomField);
897 }
898 
899 /************************************************************************/
900 /*                         GetGeomFieldIndex()                          */
901 /************************************************************************/
902 
903 /**
904  * \brief Find geometry field by name.
905  *
906  * The geometry field index of the first geometry field matching the passed
907  * field name (case insensitively) is returned.
908  *
909  * This method is the same as the C function OGR_FD_GetGeomFieldIndex().
910  *
911  * @param pszGeomFieldName the geometry field name to search for.
912  *
913  * @return the geometry field index, or -1 if no match found.
914  */
915 
GetGeomFieldIndex(const char * pszGeomFieldName) const916 int OGRFeatureDefn::GetGeomFieldIndex( const char * pszGeomFieldName ) const
917 
918 {
919     GetGeomFieldCount();
920     for( int i = 0; i < nGeomFieldCount; i++ )
921     {
922         const OGRGeomFieldDefn* poGFldDefn = GetGeomFieldDefn(i);
923         if( poGFldDefn != nullptr && EQUAL(pszGeomFieldName,
924                                         poGFldDefn->GetNameRef() ) )
925             return i;
926     }
927 
928     return -1;
929 }
930 
931 /************************************************************************/
932 /*                      OGR_FD_GetGeomFieldIndex()                      */
933 /************************************************************************/
934 /**
935  * \brief Find geometry field by name.
936  *
937  * The geometry field index of the first geometry field matching the passed
938  * field name (case insensitively) is returned.
939  *
940  * This function is the same as the C++ method
941  * OGRFeatureDefn::GetGeomFieldIndex.
942  *
943  * @param hDefn handle to the feature definition to get field index from.
944  * @param pszGeomFieldName the geometry field name to search for.
945  *
946  * @return the geometry field index, or -1 if no match found.
947  */
948 
OGR_FD_GetGeomFieldIndex(OGRFeatureDefnH hDefn,const char * pszGeomFieldName)949 int OGR_FD_GetGeomFieldIndex( OGRFeatureDefnH hDefn,
950                               const char *pszGeomFieldName )
951 
952 {
953 #ifdef OGRAPISPY_ENABLED
954     if( bOGRAPISpyEnabled )
955         OGRAPISpy_FD_GetGeomFieldIndex(hDefn, pszGeomFieldName);
956 #endif
957 
958     return OGRFeatureDefn::FromHandle(hDefn)->
959         GetGeomFieldIndex(pszGeomFieldName);
960 }
961 
962 /************************************************************************/
963 /*                            GetGeomType()                             */
964 /************************************************************************/
965 
966 /**
967  * \fn OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const;
968  *
969  * \brief Fetch the geometry base type.
970  *
971  * Note that some drivers are unable to determine a specific geometry
972  * type for a layer, in which case wkbUnknown is returned.  A value of
973  * wkbNone indicates no geometry is available for the layer at all.
974  * Many drivers do not properly mark the geometry
975  * type as 25D even if some or all geometries are in fact 25D.  A few (broken)
976  * drivers return wkbPolygon for layers that also include wkbMultiPolygon.
977  *
978  * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
979  *
980  * This method is the same as the C function OGR_FD_GetGeomType().
981  *
982  * @return the base type for all geometry related to this definition.
983  */
GetGeomType() const984 OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const
985 {
986     if( GetGeomFieldCount() == 0 )
987         return wkbNone;
988     const OGRGeomFieldDefn* poGFldDefn = GetGeomFieldDefn(0);
989     if( poGFldDefn == nullptr )
990         return wkbNone;
991     OGRwkbGeometryType eType = poGFldDefn->GetType();
992     if( eType == (wkbUnknown | wkb25DBitInternalUse) &&
993         CPLTestBool(CPLGetConfigOption("QGIS_HACK", "NO")) )
994         eType = wkbUnknown;
995     return eType;
996 }
997 
998 /************************************************************************/
999 /*                         OGR_FD_GetGeomType()                         */
1000 /************************************************************************/
1001 /**
1002  * \brief Fetch the geometry base type of the passed feature definition.
1003  *
1004  * This function is the same as the C++ method OGRFeatureDefn::GetGeomType().
1005  *
1006  * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
1007  *
1008  * @param hDefn handle to the feature definition to get the geometry type from.
1009  * @return the base type for all geometry related to this definition.
1010  */
1011 
OGR_FD_GetGeomType(OGRFeatureDefnH hDefn)1012 OGRwkbGeometryType OGR_FD_GetGeomType( OGRFeatureDefnH hDefn )
1013 
1014 {
1015     OGRwkbGeometryType eType =
1016         OGRFeatureDefn::FromHandle(hDefn)->GetGeomType();
1017     if( OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag() )
1018     {
1019         eType = OGR_GT_GetLinear(eType);
1020     }
1021 #ifdef OGRAPISPY_ENABLED
1022     if( bOGRAPISpyEnabled )
1023         OGRAPISpy_FD_GetGeomType(hDefn);
1024 #endif
1025 
1026     return eType;
1027 }
1028 
1029 /************************************************************************/
1030 /*                            SetGeomType()                             */
1031 /************************************************************************/
1032 
1033 /**
1034  * \brief Assign the base geometry type for this layer.
1035  *
1036  * All geometry objects using this type must be of the defined type or
1037  * a derived type.  The default upon creation is wkbUnknown which allows for
1038  * any geometry type.  The geometry type should generally not be changed
1039  * after any OGRFeatures have been created against this definition.
1040  *
1041  * This method is the same as the C function OGR_FD_SetGeomType().
1042  *
1043  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
1044  *
1045  * @param eNewType the new type to assign.
1046  */
1047 
SetGeomType(OGRwkbGeometryType eNewType)1048 void OGRFeatureDefn::SetGeomType( OGRwkbGeometryType eNewType )
1049 
1050 {
1051     if( GetGeomFieldCount() > 0 )
1052     {
1053         if( GetGeomFieldCount() == 1 && eNewType == wkbNone )
1054             DeleteGeomFieldDefn(0);
1055         else
1056             GetGeomFieldDefn(0)->SetType(eNewType);
1057     }
1058     else if( eNewType != wkbNone )
1059     {
1060         OGRGeomFieldDefn oGeomFieldDefn( "", eNewType );
1061         AddGeomFieldDefn(&oGeomFieldDefn);
1062     }
1063 }
1064 
1065 /************************************************************************/
1066 /*                         OGR_FD_SetGeomType()                         */
1067 /************************************************************************/
1068 
1069 /**
1070  * \brief Assign the base geometry type for the passed layer (the same as the
1071  * feature definition).
1072  *
1073  * All geometry objects using this type must be of the defined type or
1074  * a derived type.  The default upon creation is wkbUnknown which allows for
1075  * any geometry type.  The geometry type should generally not be changed
1076  * after any OGRFeatures have been created against this definition.
1077  *
1078  * This function is the same as the C++ method OGRFeatureDefn::SetGeomType().
1079  *
1080  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
1081  *
1082  * @param hDefn handle to the layer or feature definition to set the geometry
1083  * type to.
1084  * @param eType the new type to assign.
1085  */
1086 
OGR_FD_SetGeomType(OGRFeatureDefnH hDefn,OGRwkbGeometryType eType)1087 void OGR_FD_SetGeomType( OGRFeatureDefnH hDefn, OGRwkbGeometryType eType )
1088 
1089 {
1090     OGRFeatureDefn::FromHandle(hDefn)->SetGeomType(eType);
1091 }
1092 
1093 /************************************************************************/
1094 /*                             Reference()                              */
1095 /************************************************************************/
1096 
1097 /**
1098  * \fn int OGRFeatureDefn::Reference();
1099  *
1100  * \brief Increments the reference count by one.
1101  *
1102  * The reference count is used keep track of the number of OGRFeature
1103  * objects referencing this definition.
1104  *
1105  * This method is the same as the C function OGR_FD_Reference().
1106  *
1107  * @return the updated reference count.
1108  */
1109 
1110 /************************************************************************/
1111 /*                          OGR_FD_Reference()                          */
1112 /************************************************************************/
1113 /**
1114  * \brief Increments the reference count by one.
1115  *
1116  * The reference count is used keep track of the number of OGRFeature
1117  * objects referencing this definition.
1118  *
1119  * This function is the same as the C++ method OGRFeatureDefn::Reference().
1120  *
1121  * @param hDefn handle to the feature definition on witch OGRFeature are
1122  * based on.
1123  * @return the updated reference count.
1124  */
1125 
OGR_FD_Reference(OGRFeatureDefnH hDefn)1126 int OGR_FD_Reference( OGRFeatureDefnH hDefn )
1127 
1128 {
1129     return OGRFeatureDefn::FromHandle(hDefn)->Reference();
1130 }
1131 
1132 /************************************************************************/
1133 /*                            Dereference()                             */
1134 /************************************************************************/
1135 
1136 /**
1137  * \fn int OGRFeatureDefn::Dereference();
1138  *
1139  * \brief Decrements the reference count by one.
1140  *
1141  * This method is the same as the C function OGR_FD_Dereference().
1142  *
1143  * @return the updated reference count.
1144  */
1145 
1146 /************************************************************************/
1147 /*                         OGR_FD_Dereference()                         */
1148 /************************************************************************/
1149 
1150 /**
1151  * \brief Decrements the reference count by one.
1152  *
1153  * This function is the same as the C++ method OGRFeatureDefn::Dereference().
1154  *
1155  * @param hDefn handle to the feature definition on witch OGRFeature are
1156  * based on.
1157  * @return the updated reference count.
1158  */
1159 
OGR_FD_Dereference(OGRFeatureDefnH hDefn)1160 int OGR_FD_Dereference( OGRFeatureDefnH hDefn )
1161 
1162 {
1163     return OGRFeatureDefn::FromHandle(hDefn)->Dereference();
1164 }
1165 
1166 /************************************************************************/
1167 /*                         GetReferenceCount()                          */
1168 /************************************************************************/
1169 
1170 /**
1171  * \fn int OGRFeatureDefn::GetReferenceCount();
1172  *
1173  * \brief Fetch current reference count.
1174  *
1175  * This method is the same as the C function OGR_FD_GetReferenceCount().
1176  *
1177  * @return the current reference count.
1178  */
1179 
1180 /************************************************************************/
1181 /*                      OGR_FD_GetReferenceCount()                      */
1182 /************************************************************************/
1183 
1184 /**
1185  * \brief Fetch current reference count.
1186  *
1187  * This function is the same as the C++ method
1188  * OGRFeatureDefn::GetReferenceCount().
1189  *
1190  * @param hDefn handle to the feature definition on witch OGRFeature are
1191  * based on.
1192  * @return the current reference count.
1193  */
1194 
OGR_FD_GetReferenceCount(OGRFeatureDefnH hDefn)1195 int OGR_FD_GetReferenceCount( OGRFeatureDefnH hDefn )
1196 
1197 {
1198     return OGRFeatureDefn::FromHandle(hDefn)->GetReferenceCount();
1199 }
1200 
1201 /************************************************************************/
1202 /*                           GetFieldIndex()                            */
1203 /************************************************************************/
1204 
1205 /**
1206  * \brief Find field by name.
1207  *
1208  * The field index of the first field matching the passed field name (case
1209  * insensitively) is returned.
1210  *
1211  * This method is the same as the C function OGR_FD_GetFieldIndex().
1212  *
1213  * @param pszFieldName the field name to search for.
1214  *
1215  * @return the field index, or -1 if no match found.
1216  */
1217 
GetFieldIndex(const char * pszFieldName) const1218 int OGRFeatureDefn::GetFieldIndex( const char * pszFieldName ) const
1219 
1220 {
1221     GetFieldCount();
1222     for( int i = 0; i < nFieldCount; i++ )
1223     {
1224         const OGRFieldDefn* poFDefn = GetFieldDefn(i);
1225         if( poFDefn != nullptr && EQUAL(pszFieldName, poFDefn->GetNameRef() ) )
1226             return i;
1227     }
1228 
1229     return -1;
1230 }
1231 
1232 /************************************************************************/
1233 /*                      GetFieldIndexCaseSensitive()                    */
1234 /************************************************************************/
1235 
1236 /**
1237  * \brief Find field by name, in a case sensitive way.
1238  *
1239  * The field index of the first field matching the passed field name is returned.
1240  *
1241  * @param pszFieldName the field name to search for.
1242  *
1243  * @return the field index, or -1 if no match found.
1244  */
1245 
GetFieldIndexCaseSensitive(const char * pszFieldName) const1246 int OGRFeatureDefn::GetFieldIndexCaseSensitive( const char * pszFieldName ) const
1247 
1248 {
1249     GetFieldCount();
1250     for( int i = 0; i < nFieldCount; i++ )
1251     {
1252         const OGRFieldDefn* poFDefn = GetFieldDefn(i);
1253         if( poFDefn != nullptr &&
1254             strcmp(pszFieldName, poFDefn->GetNameRef() ) == 0 )
1255         {
1256             return i;
1257         }
1258     }
1259 
1260     return -1;
1261 }
1262 
1263 /************************************************************************/
1264 /*                        OGR_FD_GetFieldIndex()                        */
1265 /************************************************************************/
1266 /**
1267  * \brief Find field by name.
1268  *
1269  * The field index of the first field matching the passed field name (case
1270  * insensitively) is returned.
1271  *
1272  * This function is the same as the C++ method OGRFeatureDefn::GetFieldIndex.
1273  *
1274  * @param hDefn handle to the feature definition to get field index from.
1275  * @param pszFieldName the field name to search for.
1276  *
1277  * @return the field index, or -1 if no match found.
1278  */
1279 
OGR_FD_GetFieldIndex(OGRFeatureDefnH hDefn,const char * pszFieldName)1280 int OGR_FD_GetFieldIndex( OGRFeatureDefnH hDefn, const char *pszFieldName )
1281 
1282 {
1283 #ifdef OGRAPISPY_ENABLED
1284     if( bOGRAPISpyEnabled )
1285         OGRAPISpy_FD_GetFieldIndex(hDefn, pszFieldName);
1286 #endif
1287 
1288     return
1289         OGRFeatureDefn::FromHandle(hDefn)->GetFieldIndex(pszFieldName);
1290 }
1291 
1292 /************************************************************************/
1293 /*                         IsGeometryIgnored()                          */
1294 /************************************************************************/
1295 
1296 /**
1297  * \fn int OGRFeatureDefn::IsGeometryIgnored() const;
1298  *
1299  * \brief Determine whether the geometry can be omitted when fetching features
1300  *
1301  * This method is the same as the C function OGR_FD_IsGeometryIgnored().
1302  *
1303  * Starting with GDAL 1.11, this method returns
1304  * GetGeomFieldDefn(0)->IsIgnored().
1305  *
1306  * @return ignore state
1307  */
1308 
IsGeometryIgnored() const1309 int OGRFeatureDefn::IsGeometryIgnored() const
1310 {
1311     if( GetGeomFieldCount() == 0 )
1312         return FALSE;
1313     const OGRGeomFieldDefn* poGFldDefn = GetGeomFieldDefn(0);
1314     if( poGFldDefn == nullptr )
1315         return FALSE;
1316     return poGFldDefn->IsIgnored();
1317 }
1318 
1319 /************************************************************************/
1320 /*                      OGR_FD_IsGeometryIgnored()                      */
1321 /************************************************************************/
1322 
1323 /**
1324  * \brief Determine whether the geometry can be omitted when fetching features
1325  *
1326  * This function is the same as the C++ method
1327  * OGRFeatureDefn::IsGeometryIgnored().
1328  *
1329  * Starting with GDAL 1.11, this method returns
1330  * GetGeomFieldDefn(0)->IsIgnored().
1331  *
1332  * @param hDefn handle to the feature definition on witch OGRFeature are
1333  * based on.
1334  * @return ignore state
1335  */
1336 
OGR_FD_IsGeometryIgnored(OGRFeatureDefnH hDefn)1337 int OGR_FD_IsGeometryIgnored( OGRFeatureDefnH hDefn )
1338 {
1339     return OGRFeatureDefn::FromHandle(hDefn)->IsGeometryIgnored();
1340 }
1341 
1342 /************************************************************************/
1343 /*                         SetGeometryIgnored()                         */
1344 /************************************************************************/
1345 
1346 /**
1347  * \fn void OGRFeatureDefn::SetGeometryIgnored( int bIgnore );
1348  *
1349  * \brief Set whether the geometry can be omitted when fetching features
1350  *
1351  * This method is the same as the C function OGR_FD_SetGeometryIgnored().
1352  *
1353  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
1354  *
1355  * @param bIgnore ignore state
1356  */
1357 
SetGeometryIgnored(int bIgnore)1358 void OGRFeatureDefn::SetGeometryIgnored( int bIgnore )
1359 {
1360     if( GetGeomFieldCount() > 0 )
1361     {
1362         OGRGeomFieldDefn* poGFldDefn = GetGeomFieldDefn(0);
1363         if( poGFldDefn != nullptr )
1364             poGFldDefn->SetIgnored(bIgnore);
1365     }
1366 }
1367 
1368 /************************************************************************/
1369 /*                      OGR_FD_SetGeometryIgnored()                     */
1370 /************************************************************************/
1371 
1372 /**
1373  * \brief Set whether the geometry can be omitted when fetching features
1374  *
1375  * This function is the same as the C++ method
1376  * OGRFeatureDefn::SetGeometryIgnored().
1377  *
1378  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
1379  *
1380  * @param hDefn handle to the feature definition on witch OGRFeature are
1381  * based on.
1382  * @param bIgnore ignore state
1383  */
1384 
OGR_FD_SetGeometryIgnored(OGRFeatureDefnH hDefn,int bIgnore)1385 void OGR_FD_SetGeometryIgnored( OGRFeatureDefnH hDefn, int bIgnore )
1386 {
1387     OGRFeatureDefn::FromHandle(hDefn)->SetGeometryIgnored( bIgnore );
1388 }
1389 
1390 /************************************************************************/
1391 /*                           IsStyleIgnored()                           */
1392 /************************************************************************/
1393 
1394 /**
1395  * \fn int OGRFeatureDefn::IsStyleIgnored() const;
1396  *
1397  * \brief Determine whether the style can be omitted when fetching features
1398  *
1399  * This method is the same as the C function OGR_FD_IsStyleIgnored().
1400  *
1401  * @return ignore state
1402  */
1403 
1404 /************************************************************************/
1405 /*                       OGR_FD_IsStyleIgnored()                        */
1406 /************************************************************************/
1407 
1408 /**
1409  * \brief Determine whether the style can be omitted when fetching features
1410  *
1411  * This function is the same as the C++ method
1412  * OGRFeatureDefn::IsStyleIgnored().
1413  *
1414  * @param hDefn handle to the feature definition on which OGRFeature are
1415  * based on.
1416  * @return ignore state
1417  */
1418 
OGR_FD_IsStyleIgnored(OGRFeatureDefnH hDefn)1419 int OGR_FD_IsStyleIgnored( OGRFeatureDefnH hDefn )
1420 {
1421     return OGRFeatureDefn::FromHandle(hDefn)->IsStyleIgnored();
1422 }
1423 
1424 /************************************************************************/
1425 /*                          SetStyleIgnored()                           */
1426 /************************************************************************/
1427 
1428 /**
1429  * \fn void OGRFeatureDefn::SetStyleIgnored( int bIgnore );
1430  *
1431  * \brief Set whether the style can be omitted when fetching features
1432  *
1433  * This method is the same as the C function OGR_FD_SetStyleIgnored().
1434  *
1435  * @param bIgnore ignore state
1436  */
1437 
1438 /************************************************************************/
1439 /*                       OGR_FD_SetStyleIgnored()                       */
1440 /************************************************************************/
1441 
1442 /**
1443  * \brief Set whether the style can be omitted when fetching features
1444  *
1445  * This function is the same as the C++ method
1446  * OGRFeatureDefn::SetStyleIgnored().
1447  *
1448  * @param hDefn handle to the feature definition on witch OGRFeature are
1449  * based on.
1450  * @param bIgnore ignore state
1451  */
1452 
OGR_FD_SetStyleIgnored(OGRFeatureDefnH hDefn,int bIgnore)1453 void OGR_FD_SetStyleIgnored( OGRFeatureDefnH hDefn, int bIgnore )
1454 {
1455     OGRFeatureDefn::FromHandle(hDefn)->SetStyleIgnored(bIgnore);
1456 }
1457 
1458 /************************************************************************/
1459 /*                         CreateFeatureDefn()                          */
1460 /************************************************************************/
1461 
1462 /** Create a new feature definition object.
1463  * @param pszName name
1464  * @return new feature definition object.
1465  */
CreateFeatureDefn(const char * pszName)1466 OGRFeatureDefn *OGRFeatureDefn::CreateFeatureDefn( const char *pszName )
1467 
1468 {
1469     return new OGRFeatureDefn( pszName );
1470 }
1471 
1472 /************************************************************************/
1473 /*                         DestroyFeatureDefn()                         */
1474 /************************************************************************/
1475 
1476 /** Destroy a feature definition.
1477  * @param poDefn feature definition.
1478  */
DestroyFeatureDefn(OGRFeatureDefn * poDefn)1479 void OGRFeatureDefn::DestroyFeatureDefn( OGRFeatureDefn *poDefn )
1480 
1481 {
1482     delete poDefn;
1483 }
1484 
1485 /************************************************************************/
1486 /*                             IsSame()                                 */
1487 /************************************************************************/
1488 
1489 /**
1490  * \brief Test if the feature definition is identical to the other one.
1491  *
1492  * @param poOtherFeatureDefn the other feature definition to compare to.
1493  * @return TRUE if the feature definition is identical to the other one.
1494  */
1495 
IsSame(const OGRFeatureDefn * poOtherFeatureDefn) const1496 int OGRFeatureDefn::IsSame( const OGRFeatureDefn * poOtherFeatureDefn ) const
1497 {
1498     if( strcmp(GetName(), poOtherFeatureDefn->GetName()) == 0 &&
1499         GetFieldCount() == poOtherFeatureDefn->GetFieldCount() &&
1500         GetGeomFieldCount() == poOtherFeatureDefn->GetGeomFieldCount() )
1501     {
1502         for( int i = 0; i < nFieldCount; i++ )
1503         {
1504             const OGRFieldDefn* poFldDefn = GetFieldDefn(i);
1505             const OGRFieldDefn* poOtherFldDefn =
1506                 poOtherFeatureDefn->GetFieldDefn(i);
1507             if( !poFldDefn->IsSame(poOtherFldDefn) )
1508             {
1509                 return FALSE;
1510             }
1511         }
1512         for( int i = 0; i < nGeomFieldCount; i++ )
1513         {
1514             const OGRGeomFieldDefn* poGFldDefn = GetGeomFieldDefn(i);
1515             const OGRGeomFieldDefn* poOtherGFldDefn =
1516                 poOtherFeatureDefn->GetGeomFieldDefn(i);
1517             if( !poGFldDefn->IsSame(poOtherGFldDefn) )
1518             {
1519                 return FALSE;
1520             }
1521         }
1522         return TRUE;
1523     }
1524     return FALSE;
1525 }
1526 
1527 /************************************************************************/
1528 /*                           OGR_FD_IsSame()                            */
1529 /************************************************************************/
1530 
1531 /**
1532  * \brief Test if the feature definition is identical to the other one.
1533  *
1534  * @param hFDefn handle to the feature definition on witch OGRFeature are
1535  * based on.
1536  * @param hOtherFDefn handle to the other feature definition to compare to.
1537  * @return TRUE if the feature definition is identical to the other one.
1538  *
1539  * @since OGR 1.11
1540  */
1541 
OGR_FD_IsSame(OGRFeatureDefnH hFDefn,OGRFeatureDefnH hOtherFDefn)1542 int OGR_FD_IsSame( OGRFeatureDefnH hFDefn, OGRFeatureDefnH hOtherFDefn )
1543 {
1544     VALIDATE_POINTER1( hFDefn, "OGR_FD_IsSame", FALSE );
1545     VALIDATE_POINTER1( hOtherFDefn, "OGR_FD_IsSame", FALSE );
1546 
1547     return OGRFeatureDefn::FromHandle(hFDefn)->
1548         IsSame(OGRFeatureDefn::FromHandle(hOtherFDefn));
1549 }
1550 
1551 /************************************************************************/
1552 /*                      ComputeMapForSetFrom()                          */
1553 /************************************************************************/
1554 
1555 /**
1556  * \brief Compute the map from source to target field that can be passed to
1557  * SetFrom().
1558  *
1559  * @param poSrcFDefn the feature definition of source features later passed to
1560  * SetFrom()
1561  *
1562  * @param bForgiving true if the operation should continue despite lacking
1563  * output fields matching some of the source fields.
1564  *
1565  * @return an array of size poSrcFDefn->GetFieldCount() if everything succeeds,
1566  * or empty in case a source field definition was not found in the target layer
1567  * and bForgiving == true.
1568  *
1569  * @since GDAL 2.3
1570  */
1571 
ComputeMapForSetFrom(const OGRFeatureDefn * poSrcFDefn,bool bForgiving) const1572 std::vector<int> OGRFeatureDefn::ComputeMapForSetFrom( const OGRFeatureDefn* poSrcFDefn,
1573                                                        bool bForgiving ) const
1574 {
1575     std::map<CPLString, int> oMapNameToTargetFieldIndex;
1576     std::map<CPLString, int> oMapNameToTargetFieldIndexUC;
1577     for( int i = 0; i < GetFieldCount(); i++ )
1578     {
1579         const OGRFieldDefn* poFldDefn = GetFieldDefn(i);
1580         assert(poFldDefn); /* Make GCC-8 -Wnull-dereference happy */
1581         const char* pszName = poFldDefn->GetNameRef();
1582 
1583         // In the insane case where there are several matches, arbitrarily
1584         // decide for the first one (preserve past behavior)
1585         if( oMapNameToTargetFieldIndex.find(pszName) ==
1586                                         oMapNameToTargetFieldIndex.end() )
1587         {
1588             oMapNameToTargetFieldIndex[pszName] = i;
1589         }
1590     }
1591     std::vector<int> aoMapSrcToTargetIdx;
1592     aoMapSrcToTargetIdx.resize(poSrcFDefn->GetFieldCount());
1593     for( int i = 0; i < poSrcFDefn->GetFieldCount(); i++ )
1594     {
1595         const OGRFieldDefn* poSrcFldDefn = poSrcFDefn->GetFieldDefn(i);
1596         assert(poSrcFldDefn); /* Make GCC-8 -Wnull-dereference happy */
1597         const char* pszSrcName = poSrcFldDefn->GetNameRef();
1598 
1599         auto oIter = oMapNameToTargetFieldIndex.find(pszSrcName);
1600         if( oIter == oMapNameToTargetFieldIndex.end() )
1601         {
1602             // Build case insensitive map only if needed
1603             if( oMapNameToTargetFieldIndexUC.empty() )
1604             {
1605                 for( int j = 0; j < GetFieldCount(); j++ )
1606                 {
1607                     const OGRFieldDefn* poFldDefn = GetFieldDefn(j);
1608                     assert(poFldDefn); /* Make GCC-8 -Wnull-dereference happy */
1609                     oMapNameToTargetFieldIndexUC[
1610                         CPLString(poFldDefn->GetNameRef()).toupper()] = j;
1611                 }
1612             }
1613             oIter = oMapNameToTargetFieldIndexUC.find(
1614                 CPLString(pszSrcName).toupper());
1615             if( oIter == oMapNameToTargetFieldIndexUC.end() )
1616             {
1617                 if( !bForgiving )
1618                 {
1619                     return std::vector<int>();
1620                 }
1621                 aoMapSrcToTargetIdx[i] = -1;
1622             }
1623             else
1624             {
1625                 aoMapSrcToTargetIdx[i] = oIter->second;
1626             }
1627         }
1628         else
1629         {
1630             aoMapSrcToTargetIdx[i] = oIter->second;
1631         }
1632     }
1633     return aoMapSrcToTargetIdx;
1634 }
1635