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