1 : /******************************************************************************
2 : * $Id: ogrfeature.cpp 25692 2013-03-01 15:16:20Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: The OGRFeature class implementation.
6 : * Author: Frank Warmerdam, warmerda@home.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
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 "ogr_feature.h"
31 : #include "ogr_api.h"
32 : #include "ogr_p.h"
33 : #include <vector>
34 :
35 : CPL_CVSID("$Id: ogrfeature.cpp 25692 2013-03-01 15:16:20Z rouault $");
36 :
37 : /************************************************************************/
38 : /* OGRFeature() */
39 : /************************************************************************/
40 :
41 : /**
42 : * \brief Constructor
43 : *
44 : * Note that the OGRFeature will increment the reference count of it's
45 : * defining OGRFeatureDefn. Destruction of the OGRFeatureDefn before
46 : * destruction of all OGRFeatures that depend on it is likely to result in
47 : * a crash.
48 : *
49 : * This method is the same as the C function OGR_F_Create().
50 : *
51 : * @param poDefnIn feature class (layer) definition to which the feature will
52 : * adhere.
53 : */
54 :
55 1780058 : OGRFeature::OGRFeature( OGRFeatureDefn * poDefnIn )
56 :
57 : {
58 1780058 : m_pszStyleString = NULL;
59 1780058 : m_poStyleTable = NULL;
60 1780058 : m_pszTmpFieldValue = NULL;
61 1780058 : poDefnIn->Reference();
62 1780058 : poDefn = poDefnIn;
63 :
64 1780058 : nFID = OGRNullFID;
65 :
66 1780058 : poGeometry = NULL;
67 :
68 : // Allocate array of fields and initialize them to the unset special value
69 : pauFields = (OGRField *) CPLMalloc( poDefn->GetFieldCount() *
70 1780058 : sizeof(OGRField) );
71 :
72 27463369 : for( int i = 0; i < poDefn->GetFieldCount(); i++ )
73 : {
74 25683311 : pauFields[i].Set.nMarker1 = OGRUnsetMarker;
75 25683311 : pauFields[i].Set.nMarker2 = OGRUnsetMarker;
76 : }
77 1780058 : }
78 :
79 : /************************************************************************/
80 : /* OGR_F_Create() */
81 : /************************************************************************/
82 : /**
83 : * \brief Feature factory.
84 : *
85 : * Note that the OGRFeature will increment the reference count of it's
86 : * defining OGRFeatureDefn. Destruction of the OGRFeatureDefn before
87 : * destruction of all OGRFeatures that depend on it is likely to result in
88 : * a crash.
89 : *
90 : * This function is the same as the C++ method OGRFeature::OGRFeature().
91 : *
92 : * @param hDefn handle to the feature class (layer) definition to
93 : * which the feature will adhere.
94 : *
95 : * @return an handle to the new feature object with null fields and
96 : * no geometry.
97 : */
98 :
99 33816 : OGRFeatureH OGR_F_Create( OGRFeatureDefnH hDefn )
100 :
101 : {
102 33816 : VALIDATE_POINTER1( hDefn, "OGR_F_Create", NULL );
103 :
104 33816 : return (OGRFeatureH) new OGRFeature( (OGRFeatureDefn *) hDefn );
105 : }
106 :
107 : /************************************************************************/
108 : /* ~OGRFeature() */
109 : /************************************************************************/
110 :
111 1780058 : OGRFeature::~OGRFeature()
112 :
113 : {
114 1780058 : if( poGeometry != NULL )
115 808159 : delete poGeometry;
116 :
117 27463740 : for( int i = 0; i < poDefn->GetFieldCount(); i++ )
118 : {
119 25683682 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(i);
120 :
121 25683682 : if( !IsFieldSet(i) )
122 10972270 : continue;
123 :
124 14711412 : switch( poFDefn->GetType() )
125 : {
126 : case OFTString:
127 5422801 : if( pauFields[i].String != NULL )
128 5422801 : VSIFree( pauFields[i].String );
129 5422801 : break;
130 :
131 : case OFTBinary:
132 344 : if( pauFields[i].Binary.paData != NULL )
133 344 : VSIFree( pauFields[i].Binary.paData );
134 344 : break;
135 :
136 : case OFTStringList:
137 114 : CSLDestroy( pauFields[i].StringList.paList );
138 114 : break;
139 :
140 : case OFTIntegerList:
141 : case OFTRealList:
142 71279 : CPLFree( pauFields[i].IntegerList.paList );
143 : break;
144 :
145 : default:
146 : // should add support for wide strings.
147 : break;
148 : }
149 : }
150 :
151 1780058 : poDefn->Release();
152 :
153 1780058 : CPLFree( pauFields );
154 1780058 : CPLFree(m_pszStyleString);
155 1780058 : CPLFree(m_pszTmpFieldValue);
156 1780058 : }
157 :
158 : /************************************************************************/
159 : /* OGR_F_Destroy() */
160 : /************************************************************************/
161 : /**
162 : * \brief Destroy feature
163 : *
164 : * The feature is deleted, but within the context of the GDAL/OGR heap.
165 : * This is necessary when higher level applications use GDAL/OGR from a
166 : * DLL and they want to delete a feature created within the DLL. If the
167 : * delete is done in the calling application the memory will be freed onto
168 : * the application heap which is inappropriate.
169 : *
170 : * This function is the same as the C++ method OGRFeature::DestroyFeature().
171 : *
172 : * @param hFeat handle to the feature to destroy.
173 : */
174 :
175 95596 : void OGR_F_Destroy( OGRFeatureH hFeat )
176 :
177 : {
178 95596 : delete (OGRFeature *) hFeat;
179 95596 : }
180 :
181 : /************************************************************************/
182 : /* CreateFeature() */
183 : /************************************************************************/
184 :
185 : /**
186 : * \brief Feature factory.
187 : *
188 : * This is essentially a feature factory, useful for
189 : * applications creating features but wanting to ensure they
190 : * are created out of the OGR/GDAL heap.
191 : *
192 : * This method is the same as the C function OGR_F_Create().
193 : *
194 : * @param poDefn Feature definition defining schema.
195 : *
196 : * @return new feature object with null fields and no geometry. May be
197 : * deleted with delete.
198 : */
199 :
200 126051 : OGRFeature *OGRFeature::CreateFeature( OGRFeatureDefn *poDefn )
201 :
202 : {
203 126051 : return new OGRFeature( poDefn );
204 : }
205 :
206 : /************************************************************************/
207 : /* DestroyFeature() */
208 : /************************************************************************/
209 :
210 : /**
211 : * \brief Destroy feature
212 : *
213 : * The feature is deleted, but within the context of the GDAL/OGR heap.
214 : * This is necessary when higher level applications use GDAL/OGR from a
215 : * DLL and they want to delete a feature created within the DLL. If the
216 : * delete is done in the calling application the memory will be freed onto
217 : * the application heap which is inappropriate.
218 : *
219 : * This method is the same as the C function OGR_F_Destroy().
220 : *
221 : * @param poFeature the feature to delete.
222 : */
223 :
224 591251 : void OGRFeature::DestroyFeature( OGRFeature *poFeature )
225 :
226 : {
227 591251 : delete poFeature;
228 591251 : }
229 :
230 : /************************************************************************/
231 : /* GetDefnRef() */
232 : /************************************************************************/
233 :
234 : /**
235 : * \fn OGRFeatureDefn *OGRFeature::GetDefnRef();
236 : *
237 : * \brief Fetch feature definition.
238 : *
239 : * This method is the same as the C function OGR_F_GetDefnRef().
240 : *
241 : * @return a reference to the feature definition object.
242 : */
243 :
244 : /************************************************************************/
245 : /* OGR_F_GetDefnRef() */
246 : /************************************************************************/
247 :
248 : /**
249 : * \brief Fetch feature definition.
250 : *
251 : * This function is the same as the C++ method OGRFeature::GetDefnRef().
252 : *
253 : * @param hFeat handle to the feature to get the feature definition from.
254 : *
255 : * @return an handle to the feature definition object on which feature
256 : * depends.
257 : */
258 :
259 114 : OGRFeatureDefnH OGR_F_GetDefnRef( OGRFeatureH hFeat )
260 :
261 : {
262 114 : VALIDATE_POINTER1( hFeat, "OGR_F_GetDefnRef", NULL );
263 :
264 114 : return (OGRFeatureDefnH) ((OGRFeature *) hFeat)->GetDefnRef();
265 : }
266 :
267 : /************************************************************************/
268 : /* SetGeometryDirectly() */
269 : /************************************************************************/
270 :
271 : /**
272 : * \brief Set feature geometry.
273 : *
274 : * This method updates the features geometry, and operate exactly as
275 : * SetGeometry(), except that this method assumes ownership of the
276 : * passed geometry.
277 : *
278 : * This method is the same as the C function OGR_F_SetGeometryDirectly().
279 : *
280 : * @param poGeomIn new geometry to apply to feature. Passing NULL value here
281 : * is correct and it will result in deallocation of currently assigned geometry
282 : * without assigning new one.
283 : *
284 : * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if
285 : * the geometry type is illegal for the OGRFeatureDefn (checking not yet
286 : * implemented).
287 : */
288 :
289 743757 : OGRErr OGRFeature::SetGeometryDirectly( OGRGeometry * poGeomIn )
290 :
291 : {
292 743757 : delete poGeometry;
293 743757 : poGeometry = poGeomIn;
294 :
295 : // I should be verifying that the geometry matches the defn's type.
296 :
297 743757 : return OGRERR_NONE;
298 : }
299 :
300 : /************************************************************************/
301 : /* OGR_F_SetGeometryDirectly() */
302 : /************************************************************************/
303 :
304 : /**
305 : * \brief Set feature geometry.
306 : *
307 : * This function updates the features geometry, and operate exactly as
308 : * SetGeometry(), except that this function assumes ownership of the
309 : * passed geometry.
310 : *
311 : * This function is the same as the C++ method
312 : * OGRFeature::SetGeometryDirectly.
313 : *
314 : * @param hFeat handle to the feature on which to apply the geometry.
315 : * @param hGeom handle to the new geometry to apply to feature.
316 : *
317 : * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if
318 : * the geometry type is illegal for the OGRFeatureDefn (checking not yet
319 : * implemented).
320 : */
321 :
322 1266 : OGRErr OGR_F_SetGeometryDirectly( OGRFeatureH hFeat, OGRGeometryH hGeom )
323 :
324 : {
325 1266 : VALIDATE_POINTER1( hFeat, "OGR_F_SetGeometryDirectly", CE_Failure );
326 :
327 1266 : return ((OGRFeature *) hFeat)->SetGeometryDirectly((OGRGeometry *) hGeom);
328 : }
329 :
330 : /************************************************************************/
331 : /* SetGeometry() */
332 : /************************************************************************/
333 :
334 : /**
335 : * \brief Set feature geometry.
336 : *
337 : * This method updates the features geometry, and operate exactly as
338 : * SetGeometryDirectly(), except that this method does not assume ownership
339 : * of the passed geometry, but instead makes a copy of it.
340 : *
341 : * This method is the same as the C function OGR_F_SetGeometry().
342 : *
343 : * @param poGeomIn new geometry to apply to feature. Passing NULL value here
344 : * is correct and it will result in deallocation of currently assigned geometry
345 : * without assigning new one.
346 : *
347 : * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if
348 : * the geometry type is illegal for the OGRFeatureDefn (checking not yet
349 : * implemented).
350 : */
351 :
352 219774 : OGRErr OGRFeature::SetGeometry( OGRGeometry * poGeomIn )
353 :
354 : {
355 219774 : delete poGeometry;
356 :
357 219774 : if( poGeomIn != NULL )
358 90482 : poGeometry = poGeomIn->clone();
359 : else
360 129292 : poGeometry = NULL;
361 :
362 : // I should be verifying that the geometry matches the defn's type.
363 :
364 219774 : return OGRERR_NONE;
365 : }
366 :
367 : /************************************************************************/
368 : /* OGR_F_SetGeometry() */
369 : /************************************************************************/
370 :
371 : /**
372 : * \brief Set feature geometry.
373 : *
374 : * This function updates the features geometry, and operate exactly as
375 : * SetGeometryDirectly(), except that this function does not assume ownership
376 : * of the passed geometry, but instead makes a copy of it.
377 : *
378 : * This function is the same as the C++ OGRFeature::SetGeometry().
379 : *
380 : * @param hFeat handle to the feature on which new geometry is applied to.
381 : * @param hGeom handle to the new geometry to apply to feature.
382 : *
383 : * @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if
384 : * the geometry type is illegal for the OGRFeatureDefn (checking not yet
385 : * implemented).
386 : */
387 :
388 28984 : OGRErr OGR_F_SetGeometry( OGRFeatureH hFeat, OGRGeometryH hGeom )
389 :
390 : {
391 28984 : VALIDATE_POINTER1( hFeat, "OGR_F_SetGeometry", CE_Failure );
392 :
393 28984 : return ((OGRFeature *) hFeat)->SetGeometry((OGRGeometry *) hGeom);
394 : }
395 :
396 : /************************************************************************/
397 : /* StealGeometry() */
398 : /************************************************************************/
399 :
400 : /**
401 : * \brief Take away ownership of geometry.
402 : *
403 : * Fetch the geometry from this feature, and clear the reference to the
404 : * geometry on the feature. This is a mechanism for the application to
405 : * take over ownship of the geometry from the feature without copying.
406 : * Sort of an inverse to SetGeometryDirectly().
407 : *
408 : * After this call the OGRFeature will have a NULL geometry.
409 : *
410 : * @return the pointer to the geometry.
411 : */
412 :
413 126447 : OGRGeometry *OGRFeature::StealGeometry()
414 :
415 : {
416 126447 : OGRGeometry *poReturn = poGeometry;
417 126447 : poGeometry = NULL;
418 126447 : return poReturn;
419 : }
420 :
421 : /************************************************************************/
422 : /* OGR_F_StealGeometry() */
423 : /************************************************************************/
424 :
425 : /**
426 : * \brief Take away ownership of geometry.
427 : *
428 : * Fetch the geometry from this feature, and clear the reference to the
429 : * geometry on the feature. This is a mechanism for the application to
430 : * take over ownship of the geometry from the feature without copying.
431 : * Sort of an inverse to OGR_FSetGeometryDirectly().
432 : *
433 : * After this call the OGRFeature will have a NULL geometry.
434 : *
435 : * @return the pointer to the geometry.
436 : */
437 :
438 0 : OGRGeometryH OGR_F_StealGeometry( OGRFeatureH hFeat )
439 :
440 : {
441 0 : VALIDATE_POINTER1( hFeat, "OGR_F_StealGeometry", NULL );
442 :
443 0 : return (OGRGeometryH) ((OGRFeature *) hFeat)->StealGeometry();
444 : }
445 :
446 : /************************************************************************/
447 : /* GetGeometryRef() */
448 : /************************************************************************/
449 :
450 : /**
451 : * \fn OGRGeometry *OGRFeature::GetGeometryRef();
452 : *
453 : * \brief Fetch pointer to feature geometry.
454 : *
455 : * This method is the same as the C function OGR_F_GetGeometryRef().
456 : *
457 : * @return pointer to internal feature geometry. This object should
458 : * not be modified.
459 : */
460 :
461 : /************************************************************************/
462 : /* OGR_F_GetGeometryRef() */
463 : /************************************************************************/
464 :
465 : /**
466 : * \brief Fetch an handle to feature geometry.
467 : *
468 : * This function is the same as the C++ method OGRFeature::GetGeometryRef().
469 : *
470 : * @param hFeat handle to the feature to get geometry from.
471 : * @return an handle to internal feature geometry. This object should
472 : * not be modified.
473 : */
474 :
475 58348 : OGRGeometryH OGR_F_GetGeometryRef( OGRFeatureH hFeat )
476 :
477 : {
478 58348 : VALIDATE_POINTER1( hFeat, "OGR_F_GetGeometryRef", NULL );
479 :
480 58348 : return (OGRGeometryH) ((OGRFeature *) hFeat)->GetGeometryRef();
481 : }
482 :
483 : /************************************************************************/
484 : /* Clone() */
485 : /************************************************************************/
486 :
487 : /**
488 : * \brief Duplicate feature.
489 : *
490 : * The newly created feature is owned by the caller, and will have it's own
491 : * reference to the OGRFeatureDefn.
492 : *
493 : * This method is the same as the C function OGR_F_Clone().
494 : *
495 : * @return new feature, exactly matching this feature.
496 : */
497 :
498 5034 : OGRFeature *OGRFeature::Clone()
499 :
500 : {
501 5034 : OGRFeature *poNew = new OGRFeature( poDefn );
502 :
503 5034 : poNew->SetGeometry( poGeometry );
504 :
505 41422 : for( int i = 0; i < poDefn->GetFieldCount(); i++ )
506 : {
507 36388 : poNew->SetField( i, pauFields + i );
508 : }
509 :
510 5034 : if( GetStyleString() != NULL )
511 459 : poNew->SetStyleString(GetStyleString());
512 :
513 5034 : poNew->SetFID( GetFID() );
514 :
515 5034 : return poNew;
516 : }
517 :
518 : /************************************************************************/
519 : /* OGR_F_Clone() */
520 : /************************************************************************/
521 :
522 : /**
523 : * \brief Duplicate feature.
524 : *
525 : * The newly created feature is owned by the caller, and will have it's own
526 : * reference to the OGRFeatureDefn.
527 : *
528 : * This function is the same as the C++ method OGRFeature::Clone().
529 : *
530 : * @param hFeat handle to the feature to clone.
531 : * @return an handle to the new feature, exactly matching this feature.
532 : */
533 :
534 36 : OGRFeatureH OGR_F_Clone( OGRFeatureH hFeat )
535 :
536 : {
537 36 : VALIDATE_POINTER1( hFeat, "OGR_F_Clone", NULL );
538 :
539 36 : return (OGRFeatureH) ((OGRFeature *) hFeat)->Clone();
540 : }
541 :
542 : /************************************************************************/
543 : /* GetFieldCount() */
544 : /************************************************************************/
545 :
546 : /**
547 : * \fn int OGRFeature::GetFieldCount();
548 : *
549 : * \brief Fetch number of fields on this feature.
550 : * This will always be the same
551 : * as the field count for the OGRFeatureDefn.
552 : *
553 : * This method is the same as the C function OGR_F_GetFieldCount().
554 : *
555 : * @return count of fields.
556 : */
557 :
558 : /************************************************************************/
559 : /* OGR_F_GetFieldCount() */
560 : /************************************************************************/
561 :
562 : /**
563 : * \brief Fetch number of fields on this feature
564 : * This will always be the same
565 : * as the field count for the OGRFeatureDefn.
566 : *
567 : * This function is the same as the C++ method OGRFeature::GetFieldCount().
568 : *
569 : * @param hFeat handle to the feature to get the fields count from.
570 : * @return count of fields.
571 : */
572 :
573 5098 : int OGR_F_GetFieldCount( OGRFeatureH hFeat )
574 :
575 : {
576 5098 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldCount", 0 );
577 :
578 5098 : return ((OGRFeature *) hFeat)->GetFieldCount();
579 : }
580 :
581 : /************************************************************************/
582 : /* GetFieldDefnRef() */
583 : /************************************************************************/
584 :
585 : /**
586 : * \fn OGRFieldDefn *OGRFeature::GetFieldDefnRef( int iField );
587 : *
588 : * \brief Fetch definition for this field.
589 : *
590 : * This method is the same as the C function OGR_F_GetFieldDefnRef().
591 : *
592 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
593 : *
594 : * @return the field definition (from the OGRFeatureDefn). This is an
595 : * internal reference, and should not be deleted or modified.
596 : */
597 :
598 : /************************************************************************/
599 : /* OGR_F_GetFieldDefnRef() */
600 : /************************************************************************/
601 :
602 : /**
603 : * \brief Fetch definition for this field.
604 : *
605 : * This function is the same as the C++ method OGRFeature::GetFieldDefnRef().
606 : *
607 : * @param hFeat handle to the feature on which the field is found.
608 : * @param i the field to fetch, from 0 to GetFieldCount()-1.
609 : *
610 : * @return an handle to the field definition (from the OGRFeatureDefn).
611 : * This is an internal reference, and should not be deleted or modified.
612 : */
613 :
614 4167 : OGRFieldDefnH OGR_F_GetFieldDefnRef( OGRFeatureH hFeat, int i )
615 :
616 : {
617 4167 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldDefnRef", NULL );
618 :
619 4167 : return (OGRFieldDefnH) ((OGRFeature *) hFeat)->GetFieldDefnRef(i);
620 : }
621 :
622 : /************************************************************************/
623 : /* GetFieldIndex() */
624 : /************************************************************************/
625 :
626 : /**
627 : * \fn int OGRFeature::GetFieldIndex( const char * pszName );
628 : *
629 : * \brief Fetch the field index given field name.
630 : *
631 : * This is a cover for the OGRFeatureDefn::GetFieldIndex() method.
632 : *
633 : * This method is the same as the C function OGR_F_GetFieldIndex().
634 : *
635 : * @param pszName the name of the field to search for.
636 : *
637 : * @return the field index, or -1 if no matching field is found.
638 : */
639 :
640 : /************************************************************************/
641 : /* OGR_F_GetFieldIndex() */
642 : /************************************************************************/
643 :
644 : /**
645 : * \brief Fetch the field index given field name.
646 : *
647 : * This is a cover for the OGRFeatureDefn::GetFieldIndex() method.
648 : *
649 : * This function is the same as the C++ method OGRFeature::GetFieldIndex().
650 : *
651 : * @param hFeat handle to the feature on which the field is found.
652 : * @param pszName the name of the field to search for.
653 : *
654 : * @return the field index, or -1 if no matching field is found.
655 : */
656 :
657 4309 : int OGR_F_GetFieldIndex( OGRFeatureH hFeat, const char *pszName )
658 :
659 : {
660 4309 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldIndex", 0 );
661 :
662 4309 : return ((OGRFeature *) hFeat)->GetFieldIndex( pszName );
663 : }
664 :
665 : /************************************************************************/
666 : /* IsFieldSet() */
667 : /************************************************************************/
668 :
669 : /**
670 : * \fn int OGRFeature::IsFieldSet( int iField ) const;
671 : *
672 : * \brief Test if a field has ever been assigned a value or not.
673 : *
674 : * This method is the same as the C function OGR_F_IsFieldSet().
675 : *
676 : * @param iField the field to test.
677 : *
678 : * @return TRUE if the field has been set, otherwise false.
679 : */
680 :
681 42542679 : int OGRFeature::IsFieldSet( int iField ) const
682 :
683 : {
684 42542679 : int iSpecialField = iField - poDefn->GetFieldCount();
685 42542679 : if (iSpecialField >= 0)
686 : {
687 : // special field value accessors
688 1380 : switch (iSpecialField)
689 : {
690 : case SPF_FID:
691 1246 : return ((OGRFeature *)this)->GetFID() != OGRNullFID;
692 :
693 : case SPF_OGR_GEOM_WKT:
694 : case SPF_OGR_GEOMETRY:
695 121 : return poGeometry != NULL;
696 :
697 : case SPF_OGR_STYLE:
698 0 : return ((OGRFeature *)this)->GetStyleString() != NULL;
699 :
700 : case SPF_OGR_GEOM_AREA:
701 13 : if( poGeometry == NULL )
702 0 : return FALSE;
703 :
704 13 : return OGR_G_Area((OGRGeometryH)poGeometry) != 0.0;
705 :
706 : default:
707 0 : return FALSE;
708 : }
709 : }
710 : else
711 : {
712 42541299 : return pauFields[iField].Set.nMarker1 != OGRUnsetMarker
713 42541299 : || pauFields[iField].Set.nMarker2 != OGRUnsetMarker;
714 : }
715 : }
716 :
717 : /************************************************************************/
718 : /* OGR_F_IsFieldSet() */
719 : /************************************************************************/
720 :
721 : /**
722 : * \brief Test if a field has ever been assigned a value or not.
723 : *
724 : * This function is the same as the C++ method OGRFeature::IsFieldSet().
725 : *
726 : * @param hFeat handle to the feature on which the field is.
727 : * @param iField the field to test.
728 : *
729 : * @return TRUE if the field has been set, otherwise false.
730 : */
731 :
732 5103 : int OGR_F_IsFieldSet( OGRFeatureH hFeat, int iField )
733 :
734 : {
735 5103 : VALIDATE_POINTER1( hFeat, "OGR_F_IsFieldSet", 0 );
736 :
737 5103 : OGRFeature* poFeature = (OGRFeature* )hFeat;
738 :
739 5103 : if (iField < 0 || iField >= poFeature->GetFieldCount())
740 : {
741 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
742 0 : return FALSE;
743 : }
744 :
745 5103 : return poFeature->IsFieldSet( iField );
746 : }
747 :
748 : /************************************************************************/
749 : /* UnsetField() */
750 : /************************************************************************/
751 :
752 : /**
753 : * \brief Clear a field, marking it as unset.
754 : *
755 : * This method is the same as the C function OGR_F_UnsetField().
756 : *
757 : * @param iField the field to unset.
758 : */
759 :
760 934827 : void OGRFeature::UnsetField( int iField )
761 :
762 : {
763 934827 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
764 :
765 934827 : if( poFDefn == NULL || !IsFieldSet(iField) )
766 934800 : return;
767 :
768 27 : switch( poFDefn->GetType() )
769 : {
770 : case OFTRealList:
771 : case OFTIntegerList:
772 0 : CPLFree( pauFields[iField].IntegerList.paList );
773 0 : break;
774 :
775 : case OFTStringList:
776 0 : CSLDestroy( pauFields[iField].StringList.paList );
777 0 : break;
778 :
779 : case OFTString:
780 14 : CPLFree( pauFields[iField].String );
781 14 : break;
782 :
783 : case OFTBinary:
784 0 : CPLFree( pauFields[iField].Binary.paData );
785 : break;
786 :
787 : default:
788 : break;
789 : }
790 :
791 27 : pauFields[iField].Set.nMarker1 = OGRUnsetMarker;
792 27 : pauFields[iField].Set.nMarker2 = OGRUnsetMarker;
793 : }
794 :
795 : /************************************************************************/
796 : /* OGR_F_UnsetField() */
797 : /************************************************************************/
798 :
799 : /**
800 : * \brief Clear a field, marking it as unset.
801 : *
802 : * This function is the same as the C++ method OGRFeature::UnsetField().
803 : *
804 : * @param hFeat handle to the feature on which the field is.
805 : * @param iField the field to unset.
806 : */
807 :
808 23 : void OGR_F_UnsetField( OGRFeatureH hFeat, int iField )
809 :
810 : {
811 23 : VALIDATE_POINTER0( hFeat, "OGR_F_UnsetField" );
812 :
813 23 : ((OGRFeature *) hFeat)->UnsetField( iField );
814 : }
815 :
816 : /************************************************************************/
817 : /* GetRawFieldRef() */
818 : /************************************************************************/
819 :
820 : /**
821 : * \fn OGRField *OGRFeature::GetRawFieldRef( int iField );
822 : *
823 : * \brief Fetch a pointer to the internal field value given the index.
824 : *
825 : * This method is the same as the C function OGR_F_GetRawFieldRef().
826 : *
827 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
828 : *
829 : * @return the returned pointer is to an internal data structure, and should
830 : * not be freed, or modified.
831 : */
832 :
833 : /************************************************************************/
834 : /* OGR_F_GetRawFieldRef() */
835 : /************************************************************************/
836 :
837 : /**
838 : * \brief Fetch an handle to the internal field value given the index.
839 : *
840 : * This function is the same as the C++ method OGRFeature::GetRawFieldRef().
841 : *
842 : * @param hFeat handle to the feature on which field is found.
843 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
844 : *
845 : * @return the returned handle is to an internal data structure, and should
846 : * not be freed, or modified.
847 : */
848 :
849 0 : OGRField *OGR_F_GetRawFieldRef( OGRFeatureH hFeat, int iField )
850 :
851 : {
852 0 : VALIDATE_POINTER1( hFeat, "OGR_F_GetRawFieldRef", NULL );
853 :
854 0 : return ((OGRFeature *)hFeat)->GetRawFieldRef( iField );
855 : }
856 :
857 : /************************************************************************/
858 : /* GetFieldAsInteger() */
859 : /************************************************************************/
860 :
861 : /**
862 : * \brief Fetch field value as integer.
863 : *
864 : * OFTString features will be translated using atoi(). OFTReal fields
865 : * will be cast to integer. Other field types, or errors will result in
866 : * a return value of zero.
867 : *
868 : * This method is the same as the C function OGR_F_GetFieldAsInteger().
869 : *
870 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
871 : *
872 : * @return the field value.
873 : */
874 :
875 1858636 : int OGRFeature::GetFieldAsInteger( int iField )
876 :
877 : {
878 1858636 : int iSpecialField = iField - poDefn->GetFieldCount();
879 1858636 : if (iSpecialField >= 0)
880 : {
881 : // special field value accessors
882 1250 : switch (iSpecialField)
883 : {
884 : case SPF_FID:
885 1250 : return GetFID();
886 :
887 : case SPF_OGR_GEOM_AREA:
888 0 : if( poGeometry == NULL )
889 0 : return 0;
890 0 : return (int)OGR_G_Area((OGRGeometryH)poGeometry);
891 :
892 : default:
893 0 : return 0;
894 : }
895 : }
896 :
897 1857386 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
898 :
899 1857386 : if( poFDefn == NULL )
900 0 : return 0;
901 :
902 1857386 : if( !IsFieldSet(iField) )
903 181 : return 0;
904 :
905 1857205 : if( poFDefn->GetType() == OFTInteger )
906 1837375 : return pauFields[iField].Integer;
907 19830 : else if( poFDefn->GetType() == OFTReal )
908 7 : return (int) pauFields[iField].Real;
909 19823 : else if( poFDefn->GetType() == OFTString )
910 : {
911 19823 : if( pauFields[iField].String == NULL )
912 0 : return 0;
913 : else
914 19823 : return atoi(pauFields[iField].String);
915 : }
916 : else
917 0 : return 0;
918 : }
919 :
920 : /************************************************************************/
921 : /* OGR_F_GetFieldAsInteger() */
922 : /************************************************************************/
923 :
924 : /**
925 : * \brief Fetch field value as integer.
926 : *
927 : * OFTString features will be translated using atoi(). OFTReal fields
928 : * will be cast to integer. Other field types, or errors will result in
929 : * a return value of zero.
930 : *
931 : * This function is the same as the C++ method OGRFeature::GetFieldAsInteger().
932 : *
933 : * @param hFeat handle to the feature that owned the field.
934 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
935 : *
936 : * @return the field value.
937 : */
938 :
939 3039 : int OGR_F_GetFieldAsInteger( OGRFeatureH hFeat, int iField )
940 :
941 : {
942 3039 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsInteger", 0 );
943 :
944 3039 : return ((OGRFeature *)hFeat)->GetFieldAsInteger(iField);
945 : }
946 :
947 : /************************************************************************/
948 : /* GetFieldAsDouble() */
949 : /************************************************************************/
950 :
951 : /**
952 : * \brief Fetch field value as a double.
953 : *
954 : * OFTString features will be translated using atof(). OFTInteger fields
955 : * will be cast to double. Other field types, or errors will result in
956 : * a return value of zero.
957 : *
958 : * This method is the same as the C function OGR_F_GetFieldAsDouble().
959 : *
960 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
961 : *
962 : * @return the field value.
963 : */
964 :
965 44483 : double OGRFeature::GetFieldAsDouble( int iField )
966 :
967 : {
968 44483 : int iSpecialField = iField - poDefn->GetFieldCount();
969 44483 : if (iSpecialField >= 0)
970 : {
971 : // special field value accessors
972 4 : switch (iSpecialField)
973 : {
974 : case SPF_FID:
975 0 : return GetFID();
976 :
977 : case SPF_OGR_GEOM_AREA:
978 4 : if( poGeometry == NULL )
979 0 : return 0.0;
980 4 : return OGR_G_Area((OGRGeometryH)poGeometry);
981 :
982 : default:
983 0 : return 0.0;
984 : }
985 : }
986 :
987 44479 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
988 :
989 44479 : if( poFDefn == NULL )
990 2 : return 0.0;
991 :
992 44477 : if( !IsFieldSet(iField) )
993 58 : return 0.0;
994 :
995 44419 : if( poFDefn->GetType() == OFTReal )
996 13187 : return pauFields[iField].Real;
997 31232 : else if( poFDefn->GetType() == OFTInteger )
998 0 : return pauFields[iField].Integer;
999 31232 : else if( poFDefn->GetType() == OFTString )
1000 : {
1001 31232 : if( pauFields[iField].String == NULL )
1002 0 : return 0;
1003 : else
1004 31232 : return atof(pauFields[iField].String);
1005 : }
1006 : else
1007 0 : return 0.0;
1008 : }
1009 :
1010 : /************************************************************************/
1011 : /* OGR_F_GetFieldAsDouble() */
1012 : /************************************************************************/
1013 :
1014 : /**
1015 : * \brief Fetch field value as a double.
1016 : *
1017 : * OFTString features will be translated using atof(). OFTInteger fields
1018 : * will be cast to double. Other field types, or errors will result in
1019 : * a return value of zero.
1020 : *
1021 : * This function is the same as the C++ method OGRFeature::GetFieldAsDouble().
1022 : *
1023 : * @param hFeat handle to the feature that owned the field.
1024 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1025 : *
1026 : * @return the field value.
1027 : */
1028 :
1029 754 : double OGR_F_GetFieldAsDouble( OGRFeatureH hFeat, int iField )
1030 :
1031 : {
1032 754 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsDouble", 0 );
1033 :
1034 754 : return ((OGRFeature *)hFeat)->GetFieldAsDouble(iField);
1035 : }
1036 :
1037 : /************************************************************************/
1038 : /* GetFieldAsString() */
1039 : /************************************************************************/
1040 :
1041 : /**
1042 : * \brief Fetch field value as a string.
1043 : *
1044 : * OFTReal and OFTInteger fields will be translated to string using
1045 : * sprintf(), but not necessarily using the established formatting rules.
1046 : * Other field types, or errors will result in a return value of zero.
1047 : *
1048 : * This method is the same as the C function OGR_F_GetFieldAsString().
1049 : *
1050 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1051 : *
1052 : * @return the field value. This string is internal, and should not be
1053 : * modified, or freed. Its lifetime may be very brief.
1054 : */
1055 :
1056 1683556 : const char *OGRFeature::GetFieldAsString( int iField )
1057 :
1058 : {
1059 : #define TEMP_BUFFER_SIZE 80
1060 : char szTempBuffer[TEMP_BUFFER_SIZE];
1061 :
1062 1683556 : CPLFree(m_pszTmpFieldValue);
1063 1683556 : m_pszTmpFieldValue = NULL;
1064 :
1065 1683556 : int iSpecialField = iField - poDefn->GetFieldCount();
1066 1683556 : if (iSpecialField >= 0)
1067 : {
1068 : // special field value accessors
1069 155 : switch (iSpecialField)
1070 : {
1071 : case SPF_FID:
1072 0 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "%ld", GetFID() );
1073 0 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1074 :
1075 : case SPF_OGR_GEOMETRY:
1076 141 : if( poGeometry )
1077 138 : return poGeometry->getGeometryName();
1078 : else
1079 3 : return "";
1080 :
1081 : case SPF_OGR_STYLE:
1082 2 : if( GetStyleString() == NULL )
1083 0 : return "";
1084 : else
1085 2 : return GetStyleString();
1086 :
1087 : case SPF_OGR_GEOM_WKT:
1088 : {
1089 2 : if( poGeometry == NULL )
1090 0 : return "";
1091 :
1092 2 : if (poGeometry->exportToWkt( &m_pszTmpFieldValue ) == OGRERR_NONE )
1093 2 : return m_pszTmpFieldValue;
1094 : else
1095 0 : return "";
1096 : }
1097 :
1098 : case SPF_OGR_GEOM_AREA:
1099 10 : if( poGeometry == NULL )
1100 0 : return "";
1101 :
1102 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "%.16g",
1103 10 : OGR_G_Area((OGRGeometryH)poGeometry) );
1104 10 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1105 :
1106 : default:
1107 0 : return "";
1108 : }
1109 : }
1110 :
1111 1683401 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1112 :
1113 1683401 : if( poFDefn == NULL )
1114 0 : return "";
1115 :
1116 1683401 : if( !IsFieldSet(iField) )
1117 508 : return "";
1118 :
1119 1682893 : if( poFDefn->GetType() == OFTString )
1120 : {
1121 1667329 : if( pauFields[iField].String == NULL )
1122 0 : return "";
1123 : else
1124 1667329 : return pauFields[iField].String;
1125 : }
1126 15564 : else if( poFDefn->GetType() == OFTInteger )
1127 : {
1128 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE,
1129 14452 : "%d", pauFields[iField].Integer );
1130 14452 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1131 : }
1132 1112 : else if( poFDefn->GetType() == OFTReal )
1133 : {
1134 : char szFormat[64];
1135 :
1136 761 : if( poFDefn->GetWidth() != 0 )
1137 : {
1138 : snprintf( szFormat, sizeof(szFormat), "%%.%df",
1139 556 : poFDefn->GetPrecision() );
1140 : }
1141 : else
1142 205 : strcpy( szFormat, "%.15g" );
1143 :
1144 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE,
1145 761 : szFormat, pauFields[iField].Real );
1146 :
1147 761 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1148 : }
1149 351 : else if( poFDefn->GetType() == OFTDateTime )
1150 : {
1151 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE,
1152 : "%04d/%02d/%02d %02d:%02d:%02d",
1153 147 : pauFields[iField].Date.Year,
1154 147 : pauFields[iField].Date.Month,
1155 147 : pauFields[iField].Date.Day,
1156 147 : pauFields[iField].Date.Hour,
1157 147 : pauFields[iField].Date.Minute,
1158 882 : pauFields[iField].Date.Second );
1159 :
1160 147 : if( pauFields[iField].Date.TZFlag > 1 )
1161 : {
1162 47 : int nOffset = (pauFields[iField].Date.TZFlag - 100) * 15;
1163 47 : int nHours = (int) (nOffset / 60); // round towards zero
1164 47 : int nMinutes = ABS(nOffset - nHours * 60);
1165 :
1166 47 : if( nOffset < 0 )
1167 : {
1168 6 : strcat( szTempBuffer, "-" );
1169 6 : nHours = ABS(nHours);
1170 : }
1171 : else
1172 41 : strcat( szTempBuffer, "+" );
1173 :
1174 47 : if( nMinutes == 0 )
1175 : snprintf( szTempBuffer+strlen(szTempBuffer),
1176 43 : TEMP_BUFFER_SIZE-strlen(szTempBuffer), "%02d", nHours );
1177 : else
1178 : snprintf( szTempBuffer+strlen(szTempBuffer),
1179 4 : TEMP_BUFFER_SIZE-strlen(szTempBuffer), "%02d%02d", nHours, nMinutes );
1180 : }
1181 :
1182 147 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1183 : }
1184 204 : else if( poFDefn->GetType() == OFTDate )
1185 : {
1186 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "%04d/%02d/%02d",
1187 69 : pauFields[iField].Date.Year,
1188 69 : pauFields[iField].Date.Month,
1189 207 : pauFields[iField].Date.Day );
1190 :
1191 69 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1192 : }
1193 135 : else if( poFDefn->GetType() == OFTTime )
1194 : {
1195 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "%2d:%02d:%02d",
1196 43 : pauFields[iField].Date.Hour,
1197 43 : pauFields[iField].Date.Minute,
1198 129 : pauFields[iField].Date.Second );
1199 :
1200 43 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1201 : }
1202 92 : else if( poFDefn->GetType() == OFTIntegerList )
1203 : {
1204 : char szItem[32];
1205 15 : int i, nCount = pauFields[iField].IntegerList.nCount;
1206 :
1207 15 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "(%d:", nCount );
1208 46 : for( i = 0; i < nCount; i++ )
1209 : {
1210 : snprintf( szItem, sizeof(szItem), "%d",
1211 31 : pauFields[iField].IntegerList.paList[i] );
1212 31 : if( strlen(szTempBuffer) + strlen(szItem) + 6
1213 : >= sizeof(szTempBuffer) )
1214 : {
1215 0 : break;
1216 : }
1217 :
1218 31 : if( i > 0 )
1219 16 : strcat( szTempBuffer, "," );
1220 :
1221 31 : strcat( szTempBuffer, szItem );
1222 : }
1223 :
1224 15 : if( i < nCount )
1225 0 : strcat( szTempBuffer, ",...)" );
1226 : else
1227 15 : strcat( szTempBuffer, ")" );
1228 :
1229 15 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1230 : }
1231 77 : else if( poFDefn->GetType() == OFTRealList )
1232 : {
1233 : char szItem[40];
1234 : char szFormat[64];
1235 11 : int i, nCount = pauFields[iField].RealList.nCount;
1236 :
1237 11 : if( poFDefn->GetWidth() != 0 )
1238 : {
1239 : snprintf( szFormat, sizeof(szFormat), "%%%d.%df",
1240 0 : poFDefn->GetWidth(), poFDefn->GetPrecision() );
1241 : }
1242 : else
1243 11 : strcpy( szFormat, "%.16g" );
1244 :
1245 11 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "(%d:", nCount );
1246 33 : for( i = 0; i < nCount; i++ )
1247 : {
1248 : snprintf( szItem, sizeof(szItem), szFormat,
1249 22 : pauFields[iField].RealList.paList[i] );
1250 22 : if( strlen(szTempBuffer) + strlen(szItem) + 6
1251 : >= sizeof(szTempBuffer) )
1252 : {
1253 0 : break;
1254 : }
1255 :
1256 22 : if( i > 0 )
1257 11 : strcat( szTempBuffer, "," );
1258 :
1259 22 : strcat( szTempBuffer, szItem );
1260 : }
1261 :
1262 11 : if( i < nCount )
1263 0 : strcat( szTempBuffer, ",...)" );
1264 : else
1265 11 : strcat( szTempBuffer, ")" );
1266 :
1267 11 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1268 : }
1269 66 : else if( poFDefn->GetType() == OFTStringList )
1270 : {
1271 43 : int i, nCount = pauFields[iField].StringList.nCount;
1272 :
1273 43 : snprintf( szTempBuffer, TEMP_BUFFER_SIZE, "(%d:", nCount );
1274 129 : for( i = 0; i < nCount; i++ )
1275 : {
1276 86 : const char *pszItem = pauFields[iField].StringList.paList[i];
1277 :
1278 86 : if( strlen(szTempBuffer) + strlen(pszItem) + 6
1279 : >= sizeof(szTempBuffer) )
1280 : {
1281 0 : break;
1282 : }
1283 :
1284 86 : if( i > 0 )
1285 43 : strcat( szTempBuffer, "," );
1286 :
1287 86 : strcat( szTempBuffer, pszItem );
1288 : }
1289 :
1290 43 : if( i < nCount )
1291 0 : strcat( szTempBuffer, ",...)" );
1292 : else
1293 43 : strcat( szTempBuffer, ")" );
1294 :
1295 43 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1296 : }
1297 23 : else if( poFDefn->GetType() == OFTBinary )
1298 : {
1299 23 : int nCount = pauFields[iField].Binary.nCount;
1300 : char *pszHex;
1301 :
1302 23 : if( nCount > (int) sizeof(szTempBuffer) / 2 - 4 )
1303 0 : nCount = sizeof(szTempBuffer) / 2 - 4;
1304 :
1305 23 : pszHex = CPLBinaryToHex( nCount, pauFields[iField].Binary.paData );
1306 :
1307 23 : memcpy( szTempBuffer, pszHex, 2 * nCount );
1308 23 : szTempBuffer[nCount*2] = '\0';
1309 23 : if( nCount < pauFields[iField].Binary.nCount )
1310 0 : strcat( szTempBuffer, "..." );
1311 :
1312 23 : CPLFree( pszHex );
1313 :
1314 23 : return m_pszTmpFieldValue = CPLStrdup( szTempBuffer );
1315 : }
1316 : else
1317 0 : return "";
1318 : #undef TEMP_BUFFER_SIZE
1319 : }
1320 :
1321 : /************************************************************************/
1322 : /* OGR_F_GetFieldAsString() */
1323 : /************************************************************************/
1324 :
1325 : /**
1326 : * \brief Fetch field value as a string.
1327 : *
1328 : * OFTReal and OFTInteger fields will be translated to string using
1329 : * sprintf(), but not necessarily using the established formatting rules.
1330 : * Other field types, or errors will result in a return value of zero.
1331 : *
1332 : * This function is the same as the C++ method OGRFeature::GetFieldAsString().
1333 : *
1334 : * @param hFeat handle to the feature that owned the field.
1335 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1336 : *
1337 : * @return the field value. This string is internal, and should not be
1338 : * modified, or freed. Its lifetime may be very brief.
1339 : */
1340 :
1341 3780 : const char *OGR_F_GetFieldAsString( OGRFeatureH hFeat, int iField )
1342 :
1343 : {
1344 3780 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsString", NULL );
1345 :
1346 3780 : return ((OGRFeature *)hFeat)->GetFieldAsString(iField);
1347 : }
1348 :
1349 : /************************************************************************/
1350 : /* GetFieldAsIntegerList() */
1351 : /************************************************************************/
1352 :
1353 : /**
1354 : * \brief Fetch field value as a list of integers.
1355 : *
1356 : * Currently this method only works for OFTIntegerList fields.
1357 : *
1358 : * This method is the same as the C function OGR_F_GetFieldAsIntegerList().
1359 : *
1360 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1361 : * @param pnCount an integer to put the list count (number of integers) into.
1362 : *
1363 : * @return the field value. This list is internal, and should not be
1364 : * modified, or freed. Its lifetime may be very brief. If *pnCount is zero
1365 : * on return the returned pointer may be NULL or non-NULL.
1366 : */
1367 :
1368 5715 : const int *OGRFeature::GetFieldAsIntegerList( int iField, int *pnCount )
1369 :
1370 : {
1371 5715 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1372 :
1373 5715 : if( poFDefn != NULL && IsFieldSet(iField) &&
1374 : poFDefn->GetType() == OFTIntegerList )
1375 : {
1376 5715 : if( pnCount != NULL )
1377 5715 : *pnCount = pauFields[iField].IntegerList.nCount;
1378 :
1379 5715 : return pauFields[iField].IntegerList.paList;
1380 : }
1381 : else
1382 : {
1383 0 : if( pnCount != NULL )
1384 0 : *pnCount = 0;
1385 :
1386 0 : return NULL;
1387 : }
1388 : }
1389 :
1390 : /************************************************************************/
1391 : /* OGR_F_GetFieldAsIntegerList() */
1392 : /************************************************************************/
1393 :
1394 : /**
1395 : * \brief Fetch field value as a list of integers.
1396 : *
1397 : * Currently this function only works for OFTIntegerList fields.
1398 : *
1399 : * This function is the same as the C++ method
1400 : * OGRFeature::GetFieldAsIntegerList().
1401 : *
1402 : * @param hFeat handle to the feature that owned the field.
1403 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1404 : * @param pnCount an integer to put the list count (number of integers) into.
1405 : *
1406 : * @return the field value. This list is internal, and should not be
1407 : * modified, or freed. Its lifetime may be very brief. If *pnCount is zero
1408 : * on return the returned pointer may be NULL or non-NULL.
1409 : */
1410 :
1411 6 : const int *OGR_F_GetFieldAsIntegerList( OGRFeatureH hFeat, int iField,
1412 : int *pnCount )
1413 :
1414 : {
1415 6 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsIntegerList", NULL );
1416 :
1417 6 : return ((OGRFeature *)hFeat)->GetFieldAsIntegerList(iField, pnCount);
1418 : }
1419 :
1420 : /************************************************************************/
1421 : /* GetFieldAsDoubleList() */
1422 : /************************************************************************/
1423 :
1424 : /**
1425 : * \brief Fetch field value as a list of doubles.
1426 : *
1427 : * Currently this method only works for OFTRealList fields.
1428 : *
1429 : * This method is the same as the C function OGR_F_GetFieldAsDoubleList().
1430 : *
1431 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1432 : * @param pnCount an integer to put the list count (number of doubles) into.
1433 : *
1434 : * @return the field value. This list is internal, and should not be
1435 : * modified, or freed. Its lifetime may be very brief. If *pnCount is zero
1436 : * on return the returned pointer may be NULL or non-NULL.
1437 : */
1438 :
1439 120 : const double *OGRFeature::GetFieldAsDoubleList( int iField, int *pnCount )
1440 :
1441 : {
1442 120 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1443 :
1444 120 : if( poFDefn != NULL && IsFieldSet(iField) &&
1445 : poFDefn->GetType() == OFTRealList )
1446 : {
1447 117 : if( pnCount != NULL )
1448 117 : *pnCount = pauFields[iField].RealList.nCount;
1449 :
1450 117 : return pauFields[iField].RealList.paList;
1451 : }
1452 : else
1453 : {
1454 3 : if( pnCount != NULL )
1455 3 : *pnCount = 0;
1456 :
1457 3 : return NULL;
1458 : }
1459 : }
1460 :
1461 : /************************************************************************/
1462 : /* OGR_F_GetFieldAsDoubleList() */
1463 : /************************************************************************/
1464 :
1465 : /**
1466 : * \brief Fetch field value as a list of doubles.
1467 : *
1468 : * Currently this function only works for OFTRealList fields.
1469 : *
1470 : * This function is the same as the C++ method
1471 : * OGRFeature::GetFieldAsDoubleList().
1472 : *
1473 : * @param hFeat handle to the feature that owned the field.
1474 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1475 : * @param pnCount an integer to put the list count (number of doubles) into.
1476 : *
1477 : * @return the field value. This list is internal, and should not be
1478 : * modified, or freed. Its lifetime may be very brief. If *pnCount is zero
1479 : * on return the returned pointer may be NULL or non-NULL.
1480 : */
1481 :
1482 19 : const double *OGR_F_GetFieldAsDoubleList( OGRFeatureH hFeat, int iField,
1483 : int *pnCount )
1484 :
1485 : {
1486 19 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsDoubleList", NULL );
1487 :
1488 19 : return ((OGRFeature *)hFeat)->GetFieldAsDoubleList(iField, pnCount);
1489 : }
1490 :
1491 : /************************************************************************/
1492 : /* GetFieldAsStringList() */
1493 : /************************************************************************/
1494 :
1495 : /**
1496 : * \brief Fetch field value as a list of strings.
1497 : *
1498 : * Currently this method only works for OFTStringList fields.
1499 : *
1500 : * The returned list is terminated by a NULL pointer. The number of
1501 : * elements can also be calculated using CSLCount().
1502 : *
1503 : * This method is the same as the C function OGR_F_GetFieldAsStringList().
1504 : *
1505 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1506 : *
1507 : * @return the field value. This list is internal, and should not be
1508 : * modified, or freed. Its lifetime may be very brief.
1509 : */
1510 :
1511 69 : char **OGRFeature::GetFieldAsStringList( int iField ) const
1512 :
1513 : {
1514 69 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1515 :
1516 69 : if( poFDefn == NULL )
1517 0 : return NULL;
1518 :
1519 69 : if( !IsFieldSet(iField) )
1520 0 : return NULL;
1521 :
1522 69 : if( poFDefn->GetType() == OFTStringList )
1523 : {
1524 69 : return pauFields[iField].StringList.paList;
1525 : }
1526 : else
1527 : {
1528 0 : return NULL;
1529 : }
1530 : }
1531 :
1532 : /************************************************************************/
1533 : /* OGR_F_GetFieldAsStringList() */
1534 : /************************************************************************/
1535 :
1536 : /**
1537 : * \brief Fetch field value as a list of strings.
1538 : *
1539 : * Currently this method only works for OFTStringList fields.
1540 : *
1541 : * The returned list is terminated by a NULL pointer. The number of
1542 : * elements can also be calculated using CSLCount().
1543 : *
1544 : * This function is the same as the C++ method
1545 : * OGRFeature::GetFieldAsStringList().
1546 : *
1547 : * @param hFeat handle to the feature that owned the field.
1548 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1549 : *
1550 : * @return the field value. This list is internal, and should not be
1551 : * modified, or freed. Its lifetime may be very brief.
1552 : */
1553 :
1554 3 : char **OGR_F_GetFieldAsStringList( OGRFeatureH hFeat, int iField )
1555 :
1556 : {
1557 3 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsStringList", NULL );
1558 :
1559 3 : return ((OGRFeature *)hFeat)->GetFieldAsStringList(iField);
1560 : }
1561 :
1562 : /************************************************************************/
1563 : /* GetFieldAsBinary() */
1564 : /************************************************************************/
1565 :
1566 : /**
1567 : * \brief Fetch field value as binary data.
1568 : *
1569 : * Currently this method only works for OFTBinary fields.
1570 : *
1571 : * This method is the same as the C function OGR_F_GetFieldAsBinary().
1572 : *
1573 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1574 : * @param pnBytes location to put the number of bytes returned.
1575 : *
1576 : * @return the field value. This data is internal, and should not be
1577 : * modified, or freed. Its lifetime may be very brief.
1578 : */
1579 :
1580 198 : GByte *OGRFeature::GetFieldAsBinary( int iField, int *pnBytes )
1581 :
1582 : {
1583 198 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1584 :
1585 198 : *pnBytes = 0;
1586 :
1587 198 : if( poFDefn == NULL )
1588 0 : return NULL;
1589 :
1590 198 : if( !IsFieldSet(iField) )
1591 0 : return NULL;
1592 :
1593 198 : if( poFDefn->GetType() == OFTBinary )
1594 : {
1595 198 : *pnBytes = pauFields[iField].Binary.nCount;
1596 198 : return pauFields[iField].Binary.paData;
1597 : }
1598 : else
1599 : {
1600 0 : return NULL;
1601 : }
1602 : }
1603 :
1604 : /************************************************************************/
1605 : /* OGR_F_GetFieldAsBinary() */
1606 : /************************************************************************/
1607 :
1608 : /**
1609 : * \brief Fetch field value as binary.
1610 : *
1611 : * Currently this method only works for OFTBinary fields.
1612 : *
1613 : * This function is the same as the C++ method
1614 : * OGRFeature::GetFieldAsBinary().
1615 : *
1616 : * @param hFeat handle to the feature that owned the field.
1617 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1618 : * @param pnBytes location to place count of bytes returned.
1619 : *
1620 : * @return the field value. This list is internal, and should not be
1621 : * modified, or freed. Its lifetime may be very brief.
1622 : */
1623 :
1624 70 : GByte *OGR_F_GetFieldAsBinary( OGRFeatureH hFeat, int iField, int *pnBytes )
1625 :
1626 : {
1627 70 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsBinary", NULL );
1628 70 : VALIDATE_POINTER1( pnBytes, "OGR_F_GetFieldAsBinary", NULL );
1629 :
1630 70 : return ((OGRFeature *)hFeat)->GetFieldAsBinary(iField,pnBytes);
1631 : }
1632 :
1633 : /************************************************************************/
1634 : /* GetFieldAsDateTime() */
1635 : /************************************************************************/
1636 :
1637 : /**
1638 : * \brief Fetch field value as date and time.
1639 : *
1640 : * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.
1641 : *
1642 : * This method is the same as the C function OGR_F_GetFieldAsDateTime().
1643 : *
1644 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1645 : * @param pnYear (including century)
1646 : * @param pnMonth (1-12)
1647 : * @param pnDay (1-31)
1648 : * @param pnHour (0-23)
1649 : * @param pnMinute (0-59)
1650 : * @param pnSecond (0-59)
1651 : * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)
1652 : *
1653 : * @return TRUE on success or FALSE on failure.
1654 : */
1655 :
1656 467 : int OGRFeature::GetFieldAsDateTime( int iField,
1657 : int *pnYear, int *pnMonth, int *pnDay,
1658 : int *pnHour, int *pnMinute, int *pnSecond,
1659 : int *pnTZFlag )
1660 :
1661 : {
1662 467 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1663 :
1664 467 : if( poFDefn == NULL )
1665 0 : return FALSE;
1666 :
1667 467 : if( !IsFieldSet(iField) )
1668 0 : return FALSE;
1669 :
1670 467 : if( poFDefn->GetType() == OFTDate
1671 : || poFDefn->GetType() == OFTTime
1672 : || poFDefn->GetType() == OFTDateTime )
1673 :
1674 : {
1675 467 : if( pnYear )
1676 467 : *pnYear = pauFields[iField].Date.Year;
1677 467 : if( pnMonth )
1678 467 : *pnMonth = pauFields[iField].Date.Month;
1679 467 : if( pnDay )
1680 467 : *pnDay = pauFields[iField].Date.Day;
1681 467 : if( pnHour )
1682 466 : *pnHour = pauFields[iField].Date.Hour;
1683 467 : if( pnMinute )
1684 466 : *pnMinute = pauFields[iField].Date.Minute;
1685 467 : if( pnSecond )
1686 466 : *pnSecond = pauFields[iField].Date.Second;
1687 467 : if( pnTZFlag )
1688 465 : *pnTZFlag = pauFields[iField].Date.TZFlag;
1689 :
1690 467 : return TRUE;
1691 : }
1692 : else
1693 : {
1694 0 : return FALSE;
1695 : }
1696 : }
1697 :
1698 : /************************************************************************/
1699 : /* OGR_F_GetFieldAsDateTime() */
1700 : /************************************************************************/
1701 :
1702 : /**
1703 : * \brief Fetch field value as date and time.
1704 : *
1705 : * Currently this method only works for OFTDate, OFTTime and OFTDateTime fields.
1706 : *
1707 : * This function is the same as the C++ method
1708 : * OGRFeature::GetFieldAsDateTime().
1709 : *
1710 : * @param hFeat handle to the feature that owned the field.
1711 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1712 : * @param pnYear (including century)
1713 : * @param pnMonth (1-12)
1714 : * @param pnDay (1-31)
1715 : * @param pnHour (0-23)
1716 : * @param pnMinute (0-59)
1717 : * @param pnSecond (0-59)
1718 : * @param pnTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)
1719 : *
1720 : * @return TRUE on success or FALSE on failure.
1721 : */
1722 :
1723 1 : int OGR_F_GetFieldAsDateTime( OGRFeatureH hFeat, int iField,
1724 : int *pnYear, int *pnMonth, int *pnDay,
1725 : int *pnHour, int *pnMinute, int *pnSecond,
1726 : int *pnTZFlag )
1727 :
1728 : {
1729 1 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFieldAsDateTime", 0 );
1730 :
1731 : return ((OGRFeature *)hFeat)->GetFieldAsDateTime( iField,
1732 : pnYear, pnMonth, pnDay,
1733 : pnHour, pnMinute,pnSecond,
1734 1 : pnTZFlag );
1735 : }
1736 :
1737 : /************************************************************************/
1738 : /* SetField() */
1739 : /************************************************************************/
1740 :
1741 : /**
1742 : * \brief Set field to integer value.
1743 : *
1744 : * OFTInteger and OFTReal fields will be set directly. OFTString fields
1745 : * will be assigned a string representation of the value, but not necessarily
1746 : * taking into account formatting constraints on this field. Other field
1747 : * types may be unaffected.
1748 : *
1749 : * This method is the same as the C function OGR_F_SetFieldInteger().
1750 : *
1751 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1752 : * @param nValue the value to assign.
1753 : */
1754 :
1755 917093 : void OGRFeature::SetField( int iField, int nValue )
1756 :
1757 : {
1758 917093 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1759 :
1760 917093 : if( poFDefn == NULL )
1761 0 : return;
1762 :
1763 917093 : if( poFDefn->GetType() == OFTInteger )
1764 : {
1765 916962 : pauFields[iField].Integer = nValue;
1766 916962 : pauFields[iField].Set.nMarker2 = 0;
1767 : }
1768 131 : else if( poFDefn->GetType() == OFTReal )
1769 : {
1770 36 : pauFields[iField].Real = nValue;
1771 : }
1772 95 : else if( poFDefn->GetType() == OFTIntegerList )
1773 : {
1774 1 : SetField( iField, 1, &nValue );
1775 : }
1776 94 : else if( poFDefn->GetType() == OFTRealList )
1777 : {
1778 1 : double dfValue = nValue;
1779 1 : SetField( iField, 1, &dfValue );
1780 : }
1781 93 : else if( poFDefn->GetType() == OFTString )
1782 : {
1783 : char szTempBuffer[64];
1784 :
1785 88 : sprintf( szTempBuffer, "%d", nValue );
1786 :
1787 88 : if( IsFieldSet( iField) )
1788 83 : CPLFree( pauFields[iField].String );
1789 :
1790 88 : pauFields[iField].String = CPLStrdup( szTempBuffer );
1791 : }
1792 : else
1793 : /* do nothing for other field types */;
1794 : }
1795 :
1796 : /************************************************************************/
1797 : /* OGR_F_SetFieldInteger() */
1798 : /************************************************************************/
1799 :
1800 : /**
1801 : * \brief Set field to integer value.
1802 : *
1803 : * OFTInteger and OFTReal fields will be set directly. OFTString fields
1804 : * will be assigned a string representation of the value, but not necessarily
1805 : * taking into account formatting constraints on this field. Other field
1806 : * types may be unaffected.
1807 : *
1808 : * This function is the same as the C++ method OGRFeature::SetField().
1809 : *
1810 : * @param hFeat handle to the feature that owned the field.
1811 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1812 : * @param nValue the value to assign.
1813 : */
1814 :
1815 10530 : void OGR_F_SetFieldInteger( OGRFeatureH hFeat, int iField, int nValue )
1816 :
1817 : {
1818 10530 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldInteger" );
1819 :
1820 10530 : ((OGRFeature *)hFeat)->SetField( iField, nValue );
1821 : }
1822 :
1823 : /************************************************************************/
1824 : /* SetField() */
1825 : /************************************************************************/
1826 :
1827 : /**
1828 : * \brief Set field to double value.
1829 : *
1830 : * OFTInteger and OFTReal fields will be set directly. OFTString fields
1831 : * will be assigned a string representation of the value, but not necessarily
1832 : * taking into account formatting constraints on this field. Other field
1833 : * types may be unaffected.
1834 : *
1835 : * This method is the same as the C function OGR_F_SetFieldDouble().
1836 : *
1837 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1838 : * @param dfValue the value to assign.
1839 : */
1840 :
1841 162249 : void OGRFeature::SetField( int iField, double dfValue )
1842 :
1843 : {
1844 162249 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1845 :
1846 162249 : if( poFDefn == NULL )
1847 0 : return;
1848 :
1849 162249 : if( poFDefn->GetType() == OFTReal )
1850 : {
1851 162011 : pauFields[iField].Real = dfValue;
1852 : }
1853 238 : else if( poFDefn->GetType() == OFTInteger )
1854 : {
1855 179 : pauFields[iField].Integer = (int) dfValue;
1856 179 : pauFields[iField].Set.nMarker2 = 0;
1857 : }
1858 59 : else if( poFDefn->GetType() == OFTRealList )
1859 : {
1860 1 : SetField( iField, 1, &dfValue );
1861 : }
1862 58 : else if( poFDefn->GetType() == OFTIntegerList )
1863 : {
1864 1 : int nValue = (int) dfValue;
1865 1 : SetField( iField, 1, &nValue );
1866 : }
1867 57 : else if( poFDefn->GetType() == OFTString )
1868 : {
1869 : char szTempBuffer[128];
1870 :
1871 52 : sprintf( szTempBuffer, "%.16g", dfValue );
1872 :
1873 52 : if( IsFieldSet( iField) )
1874 7 : CPLFree( pauFields[iField].String );
1875 :
1876 52 : pauFields[iField].String = CPLStrdup( szTempBuffer );
1877 : }
1878 : else
1879 : /* do nothing for other field types */;
1880 : }
1881 :
1882 : /************************************************************************/
1883 : /* OGR_F_SetFieldDouble() */
1884 : /************************************************************************/
1885 :
1886 : /**
1887 : * \brief Set field to double value.
1888 : *
1889 : * OFTInteger and OFTReal fields will be set directly. OFTString fields
1890 : * will be assigned a string representation of the value, but not necessarily
1891 : * taking into account formatting constraints on this field. Other field
1892 : * types may be unaffected.
1893 : *
1894 : * This function is the same as the C++ method OGRFeature::SetField().
1895 : *
1896 : * @param hFeat handle to the feature that owned the field.
1897 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1898 : * @param dfValue the value to assign.
1899 : */
1900 :
1901 314 : void OGR_F_SetFieldDouble( OGRFeatureH hFeat, int iField, double dfValue )
1902 :
1903 : {
1904 314 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldDouble" );
1905 :
1906 314 : ((OGRFeature *)hFeat)->SetField( iField, dfValue );
1907 : }
1908 :
1909 : /************************************************************************/
1910 : /* SetField() */
1911 : /************************************************************************/
1912 :
1913 : /**
1914 : * \brief Set field to string value.
1915 : *
1916 : * OFTInteger fields will be set based on an atoi() conversion of the string.
1917 : * OFTReal fields will be set based on an atof() conversion of the string.
1918 : * Other field types may be unaffected.
1919 : *
1920 : * This method is the same as the C function OGR_F_SetFieldString().
1921 : *
1922 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
1923 : * @param pszValue the value to assign.
1924 : */
1925 :
1926 13165047 : void OGRFeature::SetField( int iField, const char * pszValue )
1927 :
1928 : {
1929 : static int bWarn = -1;
1930 13165047 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
1931 : char *pszLast;
1932 :
1933 13165047 : if( bWarn < 0 )
1934 164 : bWarn = CSLTestBoolean( CPLGetConfigOption( "OGR_SETFIELD_NUMERIC_WARNING", "NO" ) );
1935 :
1936 13165047 : if( poFDefn == NULL )
1937 0 : return;
1938 :
1939 13165047 : if( poFDefn->GetType() == OFTString )
1940 : {
1941 5202715 : if( IsFieldSet(iField) )
1942 398 : CPLFree( pauFields[iField].String );
1943 :
1944 5202715 : pauFields[iField].String = CPLStrdup( pszValue );
1945 : }
1946 7962332 : else if( poFDefn->GetType() == OFTInteger )
1947 : {
1948 7411869 : long nVal = strtol(pszValue, &pszLast, 10);
1949 7411869 : pauFields[iField].Integer = (nVal > INT_MAX) ? INT_MAX : (nVal < INT_MIN) ? INT_MIN : (int) nVal;
1950 7411869 : if( bWarn && (nVal != (long)pauFields[iField].Integer || !pszLast || *pszLast ) )
1951 : CPLError(CE_Warning, CPLE_AppDefined,
1952 : "Value '%s' of field %s.%s parsed incompletely to integer %d.",
1953 0 : pszValue, poDefn->GetName(), poFDefn->GetNameRef(), pauFields[iField].Integer );
1954 7411869 : pauFields[iField].Set.nMarker2 = OGRUnsetMarker;
1955 : }
1956 550463 : else if( poFDefn->GetType() == OFTReal )
1957 : {
1958 550259 : pauFields[iField].Real = CPLStrtod(pszValue, &pszLast);
1959 550259 : if( bWarn && ( !pszLast || *pszLast ) )
1960 : CPLError(CE_Warning, CPLE_AppDefined,
1961 : "Value '%s' of field %s.%s parsed incompletely to real %.16g.",
1962 0 : pszValue, poDefn->GetName(), poFDefn->GetNameRef(), pauFields[iField].Real );
1963 : }
1964 204 : else if( poFDefn->GetType() == OFTDate
1965 : || poFDefn->GetType() == OFTTime
1966 : || poFDefn->GetType() == OFTDateTime )
1967 : {
1968 : OGRField sWrkField;
1969 :
1970 180 : if( OGRParseDate( pszValue, &sWrkField, 0 ) )
1971 177 : memcpy( pauFields+iField, &sWrkField, sizeof(sWrkField));
1972 : }
1973 24 : else if( poFDefn->GetType() == OFTIntegerList
1974 : || poFDefn->GetType() == OFTRealList )
1975 : {
1976 12 : char **papszValueList = NULL;
1977 :
1978 12 : if( pszValue[0] == '(' && strchr(pszValue,':') != NULL )
1979 : {
1980 : papszValueList = CSLTokenizeString2(
1981 10 : pszValue, ",:()", 0 );
1982 : }
1983 :
1984 22 : if( CSLCount(papszValueList) == 0
1985 10 : || atoi(papszValueList[0]) != CSLCount(papszValueList)-1 )
1986 : {
1987 : /* do nothing - the count does not match entries */
1988 : }
1989 10 : else if( poFDefn->GetType() == OFTIntegerList )
1990 : {
1991 10 : int i, nCount = atoi(papszValueList[0]);
1992 10 : std::vector<int> anValues;
1993 :
1994 40 : for( i=0; i < nCount; i++ )
1995 30 : anValues.push_back( atoi(papszValueList[i+1]) );
1996 10 : SetField( iField, nCount, &(anValues[0]) );
1997 : }
1998 0 : else if( poFDefn->GetType() == OFTRealList )
1999 : {
2000 0 : int i, nCount = atoi(papszValueList[0]);
2001 0 : std::vector<double> adfValues;
2002 :
2003 0 : for( i=0; i < nCount; i++ )
2004 0 : adfValues.push_back( atof(papszValueList[i+1]) );
2005 0 : SetField( iField, nCount, &(adfValues[0]) );
2006 : }
2007 :
2008 12 : CSLDestroy(papszValueList);
2009 : }
2010 : else
2011 : /* do nothing for other field types */;
2012 : }
2013 :
2014 : /************************************************************************/
2015 : /* OGR_F_SetFieldString() */
2016 : /************************************************************************/
2017 :
2018 : /**
2019 : * \brief Set field to string value.
2020 : *
2021 : * OFTInteger fields will be set based on an atoi() conversion of the string.
2022 : * OFTReal fields will be set based on an atof() conversion of the string.
2023 : * Other field types may be unaffected.
2024 : *
2025 : * This function is the same as the C++ method OGRFeature::SetField().
2026 : *
2027 : * @param hFeat handle to the feature that owned the field.
2028 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
2029 : * @param pszValue the value to assign.
2030 : */
2031 :
2032 3777 : void OGR_F_SetFieldString( OGRFeatureH hFeat, int iField, const char *pszValue)
2033 :
2034 : {
2035 3777 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldString" );
2036 :
2037 3777 : ((OGRFeature *)hFeat)->SetField( iField, pszValue );
2038 : }
2039 :
2040 : /************************************************************************/
2041 : /* SetField() */
2042 : /************************************************************************/
2043 :
2044 : /**
2045 : * \brief Set field to list of integers value.
2046 : *
2047 : * This method currently on has an effect of OFTIntegerList fields.
2048 : *
2049 : * This method is the same as the C function OGR_F_SetFieldIntegerList().
2050 : *
2051 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2052 : * @param nCount the number of values in the list being assigned.
2053 : * @param panValues the values to assign.
2054 : */
2055 :
2056 59540 : void OGRFeature::SetField( int iField, int nCount, int *panValues )
2057 :
2058 : {
2059 59540 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2060 :
2061 59540 : if( poFDefn == NULL )
2062 0 : return;
2063 :
2064 59540 : if( poFDefn->GetType() == OFTIntegerList )
2065 : {
2066 : OGRField uField;
2067 :
2068 59532 : uField.IntegerList.nCount = nCount;
2069 59532 : uField.Set.nMarker2 = 0;
2070 59532 : uField.IntegerList.paList = panValues;
2071 :
2072 59532 : SetField( iField, &uField );
2073 : }
2074 8 : else if( poFDefn->GetType() == OFTRealList )
2075 : {
2076 1 : std::vector<double> adfValues;
2077 :
2078 4 : for( int i=0; i < nCount; i++ )
2079 3 : adfValues.push_back( (double) panValues[i] );
2080 :
2081 1 : SetField( iField, nCount, &adfValues[0] );
2082 : }
2083 7 : else if( (poFDefn->GetType() == OFTInteger || poFDefn->GetType() == OFTReal)
2084 : && nCount == 1 )
2085 : {
2086 2 : SetField( iField, panValues[0] );
2087 : }
2088 : }
2089 :
2090 : /************************************************************************/
2091 : /* OGR_F_SetFieldIntegerList() */
2092 : /************************************************************************/
2093 :
2094 : /**
2095 : * \brief Set field to list of integers value.
2096 : *
2097 : * This function currently on has an effect of OFTIntegerList fields.
2098 : *
2099 : * This function is the same as the C++ method OGRFeature::SetField().
2100 : *
2101 : * @param hFeat handle to the feature that owned the field.
2102 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2103 : * @param nCount the number of values in the list being assigned.
2104 : * @param panValues the values to assign.
2105 : */
2106 :
2107 6 : void OGR_F_SetFieldIntegerList( OGRFeatureH hFeat, int iField,
2108 : int nCount, int *panValues )
2109 :
2110 : {
2111 6 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldIntegerList" );
2112 :
2113 6 : ((OGRFeature *)hFeat)->SetField( iField, nCount, panValues );
2114 : }
2115 :
2116 : /************************************************************************/
2117 : /* SetField() */
2118 : /************************************************************************/
2119 :
2120 : /**
2121 : * \brief Set field to list of doubles value.
2122 : *
2123 : * This method currently on has an effect of OFTRealList fields.
2124 : *
2125 : * This method is the same as the C function OGR_F_SetFieldDoubleList().
2126 : *
2127 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2128 : * @param nCount the number of values in the list being assigned.
2129 : * @param padfValues the values to assign.
2130 : */
2131 :
2132 11691 : void OGRFeature::SetField( int iField, int nCount, double * padfValues )
2133 :
2134 : {
2135 11691 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2136 :
2137 11691 : if( poFDefn == NULL )
2138 0 : return;
2139 :
2140 11691 : if( poFDefn->GetType() == OFTRealList )
2141 : {
2142 : OGRField uField;
2143 :
2144 11683 : uField.RealList.nCount = nCount;
2145 11683 : uField.Set.nMarker2 = 0;
2146 11683 : uField.RealList.paList = padfValues;
2147 :
2148 11683 : SetField( iField, &uField );
2149 : }
2150 8 : else if( poFDefn->GetType() == OFTIntegerList )
2151 : {
2152 1 : std::vector<int> anValues;
2153 :
2154 3 : for( int i=0; i < nCount; i++ )
2155 2 : anValues.push_back( (int) padfValues[i] );
2156 :
2157 1 : SetField( iField, nCount, &anValues[0] );
2158 : }
2159 7 : else if( (poFDefn->GetType() == OFTInteger || poFDefn->GetType() == OFTReal)
2160 : && nCount == 1 )
2161 : {
2162 2 : SetField( iField, padfValues[0] );
2163 : }
2164 : }
2165 :
2166 : /************************************************************************/
2167 : /* OGR_F_SetFieldDoubleList() */
2168 : /************************************************************************/
2169 :
2170 : /**
2171 : * \brief Set field to list of doubles value.
2172 : *
2173 : * This function currently on has an effect of OFTRealList fields.
2174 : *
2175 : * This function is the same as the C++ method OGRFeature::SetField().
2176 : *
2177 : * @param hFeat handle to the feature that owned the field.
2178 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2179 : * @param nCount the number of values in the list being assigned.
2180 : * @param padfValues the values to assign.
2181 : */
2182 :
2183 29 : void OGR_F_SetFieldDoubleList( OGRFeatureH hFeat, int iField,
2184 : int nCount, double *padfValues )
2185 :
2186 : {
2187 29 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldDoubleList" );
2188 :
2189 29 : ((OGRFeature *)hFeat)->SetField( iField, nCount, padfValues );
2190 : }
2191 :
2192 : /************************************************************************/
2193 : /* SetField() */
2194 : /************************************************************************/
2195 :
2196 : /**
2197 : * \brief Set field to list of strings value.
2198 : *
2199 : * This method currently on has an effect of OFTStringList fields.
2200 : *
2201 : * This method is the same as the C function OGR_F_SetFieldStringList().
2202 : *
2203 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2204 : * @param papszValues the values to assign.
2205 : */
2206 :
2207 68 : void OGRFeature::SetField( int iField, char ** papszValues )
2208 :
2209 : {
2210 68 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2211 :
2212 68 : if( poFDefn == NULL )
2213 0 : return;
2214 :
2215 68 : if( poFDefn->GetType() == OFTStringList )
2216 : {
2217 : OGRField uField;
2218 :
2219 68 : uField.StringList.nCount = CSLCount(papszValues);
2220 68 : uField.Set.nMarker2 = 0;
2221 68 : uField.StringList.paList = papszValues;
2222 :
2223 68 : SetField( iField, &uField );
2224 : }
2225 : }
2226 :
2227 : /************************************************************************/
2228 : /* OGR_F_SetFieldStringList() */
2229 : /************************************************************************/
2230 :
2231 : /**
2232 : * \brief Set field to list of strings value.
2233 : *
2234 : * This function currently on has an effect of OFTStringList fields.
2235 : *
2236 : * This function is the same as the C++ method OGRFeature::SetField().
2237 : *
2238 : * @param hFeat handle to the feature that owned the field.
2239 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2240 : * @param papszValues the values to assign.
2241 : */
2242 :
2243 14 : void OGR_F_SetFieldStringList( OGRFeatureH hFeat, int iField,
2244 : char ** papszValues )
2245 :
2246 : {
2247 14 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldStringList" );
2248 :
2249 14 : ((OGRFeature *)hFeat)->SetField( iField, papszValues );
2250 : }
2251 :
2252 : /************************************************************************/
2253 : /* SetField() */
2254 : /************************************************************************/
2255 :
2256 : /**
2257 : * \brief Set field to binary data.
2258 : *
2259 : * This method currently on has an effect of OFTBinary fields.
2260 : *
2261 : * This method is the same as the C function OGR_F_SetFieldBinary().
2262 : *
2263 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2264 : * @param nBytes bytes of data being set.
2265 : * @param pabyData the raw data being applied.
2266 : */
2267 :
2268 216 : void OGRFeature::SetField( int iField, int nBytes, GByte *pabyData )
2269 :
2270 : {
2271 216 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2272 :
2273 216 : if( poFDefn == NULL )
2274 0 : return;
2275 :
2276 216 : if( poFDefn->GetType() == OFTBinary )
2277 : {
2278 : OGRField uField;
2279 :
2280 216 : uField.Binary.nCount = nBytes;
2281 216 : uField.Set.nMarker2 = 0;
2282 216 : uField.Binary.paData = pabyData;
2283 :
2284 216 : SetField( iField, &uField );
2285 : }
2286 : }
2287 :
2288 : /************************************************************************/
2289 : /* OGR_F_SetFieldBinary() */
2290 : /************************************************************************/
2291 :
2292 : /**
2293 : * \brief Set field to binary data.
2294 : *
2295 : * This function currently on has an effect of OFTBinary fields.
2296 : *
2297 : * This function is the same as the C++ method OGRFeature::SetField().
2298 : *
2299 : * @param hFeat handle to the feature that owned the field.
2300 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2301 : * @param nBytes the number of bytes in pabyData array.
2302 : * @param pabyData the data to apply.
2303 : */
2304 :
2305 22 : void OGR_F_SetFieldBinary( OGRFeatureH hFeat, int iField,
2306 : int nBytes, GByte *pabyData )
2307 :
2308 : {
2309 22 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldBinary" );
2310 :
2311 22 : ((OGRFeature *)hFeat)->SetField( iField, nBytes, pabyData );
2312 : }
2313 :
2314 : /************************************************************************/
2315 : /* SetField() */
2316 : /************************************************************************/
2317 :
2318 : /**
2319 : * \brief Set field to date.
2320 : *
2321 : * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime
2322 : * fields.
2323 : *
2324 : * This method is the same as the C function OGR_F_SetFieldDateTime().
2325 : *
2326 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2327 : * @param nYear (including century)
2328 : * @param nMonth (1-12)
2329 : * @param nDay (1-31)
2330 : * @param nHour (0-23)
2331 : * @param nMinute (0-59)
2332 : * @param nSecond (0-59)
2333 : * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)
2334 : */
2335 :
2336 501 : void OGRFeature::SetField( int iField, int nYear, int nMonth, int nDay,
2337 : int nHour, int nMinute, int nSecond,
2338 : int nTZFlag )
2339 :
2340 : {
2341 501 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2342 :
2343 501 : if( poFDefn == NULL )
2344 0 : return;
2345 :
2346 501 : if( poFDefn->GetType() == OFTDate
2347 : || poFDefn->GetType() == OFTTime
2348 : || poFDefn->GetType() == OFTDateTime )
2349 : {
2350 501 : if( (GInt16)nYear != nYear )
2351 : {
2352 : CPLError(CE_Failure, CPLE_NotSupported,
2353 0 : "Years < -32768 or > 32767 are not supported");
2354 0 : return;
2355 : }
2356 :
2357 501 : pauFields[iField].Date.Year = (GInt16)nYear;
2358 501 : pauFields[iField].Date.Month = (GByte)nMonth;
2359 501 : pauFields[iField].Date.Day = (GByte)nDay;
2360 501 : pauFields[iField].Date.Hour = (GByte)nHour;
2361 501 : pauFields[iField].Date.Minute = (GByte)nMinute;
2362 501 : pauFields[iField].Date.Second = (GByte)nSecond;
2363 501 : pauFields[iField].Date.TZFlag = (GByte)nTZFlag;
2364 : }
2365 : }
2366 :
2367 : /************************************************************************/
2368 : /* OGR_F_SetFieldDateTime() */
2369 : /************************************************************************/
2370 :
2371 : /**
2372 : * \brief Set field to datetime.
2373 : *
2374 : * This method currently only has an effect for OFTDate, OFTTime and OFTDateTime
2375 : * fields.
2376 : *
2377 : * @param hFeat handle to the feature that owned the field.
2378 : * @param iField the field to set, from 0 to GetFieldCount()-1.
2379 : * @param nYear (including century)
2380 : * @param nMonth (1-12)
2381 : * @param nDay (1-31)
2382 : * @param nHour (0-23)
2383 : * @param nMinute (0-59)
2384 : * @param nSecond (0-59)
2385 : * @param nTZFlag (0=unknown, 1=localtime, 100=GMT, see data model for details)
2386 : */
2387 :
2388 25 : void OGR_F_SetFieldDateTime( OGRFeatureH hFeat, int iField,
2389 : int nYear, int nMonth, int nDay,
2390 : int nHour, int nMinute, int nSecond,
2391 : int nTZFlag )
2392 :
2393 :
2394 : {
2395 25 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldDateTime" );
2396 :
2397 : ((OGRFeature *)hFeat)->SetField( iField, nYear, nMonth, nDay,
2398 25 : nHour, nMinute, nSecond, nTZFlag );
2399 : }
2400 :
2401 : /************************************************************************/
2402 : /* SetField() */
2403 : /************************************************************************/
2404 :
2405 : /**
2406 : * \brief Set field.
2407 : *
2408 : * The passed value OGRField must be of exactly the same type as the
2409 : * target field, or an application crash may occur. The passed value
2410 : * is copied, and will not be affected. It remains the responsibility of
2411 : * the caller.
2412 : *
2413 : * This method is the same as the C function OGR_F_SetFieldRaw().
2414 : *
2415 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
2416 : * @param puValue the value to assign.
2417 : */
2418 :
2419 482639 : void OGRFeature::SetField( int iField, OGRField * puValue )
2420 :
2421 : {
2422 482639 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
2423 :
2424 482639 : if( poFDefn == NULL )
2425 0 : return;
2426 :
2427 482639 : if( poFDefn->GetType() == OFTInteger )
2428 : {
2429 61387 : pauFields[iField] = *puValue;
2430 : }
2431 421252 : else if( poFDefn->GetType() == OFTReal )
2432 : {
2433 118884 : pauFields[iField] = *puValue;
2434 : }
2435 302368 : else if( poFDefn->GetType() == OFTString )
2436 : {
2437 228156 : if( IsFieldSet( iField ) )
2438 12 : CPLFree( pauFields[iField].String );
2439 :
2440 228156 : if( puValue->String == NULL )
2441 0 : pauFields[iField].String = NULL;
2442 235871 : else if( puValue->Set.nMarker1 == OGRUnsetMarker
2443 : && puValue->Set.nMarker2 == OGRUnsetMarker )
2444 7715 : pauFields[iField] = *puValue;
2445 : else
2446 220441 : pauFields[iField].String = CPLStrdup( puValue->String );
2447 : }
2448 74212 : else if( poFDefn->GetType() == OFTDate
2449 : || poFDefn->GetType() == OFTTime
2450 : || poFDefn->GetType() == OFTDateTime )
2451 : {
2452 2440 : memcpy( pauFields+iField, puValue, sizeof(OGRField) );
2453 : }
2454 71772 : else if( poFDefn->GetType() == OFTIntegerList )
2455 : {
2456 59568 : int nCount = puValue->IntegerList.nCount;
2457 :
2458 59568 : if( IsFieldSet( iField ) )
2459 4 : CPLFree( pauFields[iField].IntegerList.paList );
2460 :
2461 59568 : if( puValue->Set.nMarker1 == OGRUnsetMarker
2462 : && puValue->Set.nMarker2 == OGRUnsetMarker )
2463 : {
2464 0 : pauFields[iField] = *puValue;
2465 : }
2466 : else
2467 : {
2468 59568 : pauFields[iField].IntegerList.paList =
2469 59568 : (int *) CPLMalloc(sizeof(int) * nCount);
2470 59568 : memcpy( pauFields[iField].IntegerList.paList,
2471 : puValue->IntegerList.paList,
2472 119136 : sizeof(int) * nCount );
2473 59568 : pauFields[iField].IntegerList.nCount = nCount;
2474 : }
2475 : }
2476 12204 : else if( poFDefn->GetType() == OFTRealList )
2477 : {
2478 11732 : int nCount = puValue->RealList.nCount;
2479 :
2480 11732 : if( IsFieldSet( iField ) )
2481 14 : CPLFree( pauFields[iField].RealList.paList );
2482 :
2483 11735 : if( puValue->Set.nMarker1 == OGRUnsetMarker
2484 : && puValue->Set.nMarker2 == OGRUnsetMarker )
2485 : {
2486 3 : pauFields[iField] = *puValue;
2487 : }
2488 : else
2489 : {
2490 11729 : pauFields[iField].RealList.paList =
2491 11729 : (double *) CPLMalloc(sizeof(double) * nCount);
2492 11729 : memcpy( pauFields[iField].RealList.paList,
2493 : puValue->RealList.paList,
2494 23458 : sizeof(double) * nCount );
2495 11729 : pauFields[iField].RealList.nCount = nCount;
2496 : }
2497 : }
2498 472 : else if( poFDefn->GetType() == OFTStringList )
2499 : {
2500 116 : if( IsFieldSet( iField ) )
2501 2 : CSLDestroy( pauFields[iField].StringList.paList );
2502 :
2503 116 : if( puValue->Set.nMarker1 == OGRUnsetMarker
2504 : && puValue->Set.nMarker2 == OGRUnsetMarker )
2505 : {
2506 0 : pauFields[iField] = *puValue;
2507 : }
2508 : else
2509 : {
2510 116 : pauFields[iField].StringList.paList =
2511 116 : CSLDuplicate( puValue->StringList.paList );
2512 :
2513 116 : pauFields[iField].StringList.nCount = puValue->StringList.nCount;
2514 : CPLAssert( CSLCount(puValue->StringList.paList)
2515 116 : == puValue->StringList.nCount );
2516 : }
2517 : }
2518 356 : else if( poFDefn->GetType() == OFTBinary )
2519 : {
2520 356 : if( IsFieldSet( iField ) )
2521 0 : CPLFree( pauFields[iField].Binary.paData );
2522 :
2523 368 : if( puValue->Set.nMarker1 == OGRUnsetMarker
2524 : && puValue->Set.nMarker2 == OGRUnsetMarker )
2525 : {
2526 12 : pauFields[iField] = *puValue;
2527 : }
2528 : else
2529 : {
2530 344 : pauFields[iField].Binary.nCount = puValue->Binary.nCount;
2531 344 : pauFields[iField].Binary.paData =
2532 344 : (GByte *) CPLMalloc(puValue->Binary.nCount);
2533 344 : memcpy( pauFields[iField].Binary.paData,
2534 : puValue->Binary.paData,
2535 688 : puValue->Binary.nCount );
2536 : }
2537 : }
2538 : else
2539 : /* do nothing for other field types */;
2540 : }
2541 :
2542 : /************************************************************************/
2543 : /* OGR_F_SetFieldRaw() */
2544 : /************************************************************************/
2545 :
2546 : /**
2547 : * \brief Set field.
2548 : *
2549 : * The passed value OGRField must be of exactly the same type as the
2550 : * target field, or an application crash may occur. The passed value
2551 : * is copied, and will not be affected. It remains the responsibility of
2552 : * the caller.
2553 : *
2554 : * This function is the same as the C++ method OGRFeature::SetField().
2555 : *
2556 : * @param hFeat handle to the feature that owned the field.
2557 : * @param iField the field to fetch, from 0 to GetFieldCount()-1.
2558 : * @param psValue handle on the value to assign.
2559 : */
2560 :
2561 0 : void OGR_F_SetFieldRaw( OGRFeatureH hFeat, int iField, OGRField *psValue )
2562 :
2563 : {
2564 0 : VALIDATE_POINTER0( hFeat, "OGR_F_SetFieldRaw" );
2565 :
2566 0 : ((OGRFeature *)hFeat)->SetField( iField, psValue );
2567 : }
2568 :
2569 : /************************************************************************/
2570 : /* DumpReadable() */
2571 : /************************************************************************/
2572 :
2573 : /**
2574 : * \brief Dump this feature in a human readable form.
2575 : *
2576 : * This dumps the attributes, and geometry; however, it doesn't definition
2577 : * information (other than field types and names), nor does it report the
2578 : * geometry spatial reference system.
2579 : *
2580 : * A few options can be defined to change the default dump :
2581 : * <ul>
2582 : * <li>DISPLAY_FIELDS=NO : to hide the dump of the attributes</li>
2583 : * <li>DISPLAY_STYLE=NO : to hide the dump of the style string</li>
2584 : * <li>DISPLAY_GEOMETRY=NO : to hide the dump of the geometry</li>
2585 : * <li>DISPLAY_GEOMETRY=SUMMARY : to get only a summary of the geometry</li>
2586 : * </ul>
2587 : *
2588 : * This method is the same as the C function OGR_F_DumpReadable().
2589 : *
2590 : * @param fpOut the stream to write to, such as stdout. If NULL stdout will
2591 : * be used.
2592 : * @param papszOptions NULL terminated list of options (may be NULL)
2593 : */
2594 :
2595 67 : void OGRFeature::DumpReadable( FILE * fpOut, char** papszOptions )
2596 :
2597 : {
2598 67 : if( fpOut == NULL )
2599 67 : fpOut = stdout;
2600 :
2601 67 : fprintf( fpOut, "OGRFeature(%s):%ld\n", poDefn->GetName(), GetFID() );
2602 :
2603 : const char* pszDisplayFields =
2604 67 : CSLFetchNameValue(papszOptions, "DISPLAY_FIELDS");
2605 67 : if (pszDisplayFields == NULL || CSLTestBoolean(pszDisplayFields))
2606 : {
2607 225 : for( int iField = 0; iField < GetFieldCount(); iField++ )
2608 : {
2609 168 : OGRFieldDefn *poFDefn = poDefn->GetFieldDefn(iField);
2610 :
2611 : fprintf( fpOut, " %s (%s) = ",
2612 : poFDefn->GetNameRef(),
2613 168 : OGRFieldDefn::GetFieldTypeName(poFDefn->GetType()) );
2614 :
2615 168 : if( IsFieldSet( iField ) )
2616 168 : fprintf( fpOut, "%s\n", GetFieldAsString( iField ) );
2617 : else
2618 0 : fprintf( fpOut, "(null)\n" );
2619 :
2620 : }
2621 : }
2622 :
2623 :
2624 67 : if( GetStyleString() != NULL )
2625 : {
2626 : const char* pszDisplayStyle =
2627 0 : CSLFetchNameValue(papszOptions, "DISPLAY_STYLE");
2628 0 : if (pszDisplayStyle == NULL || CSLTestBoolean(pszDisplayStyle))
2629 : {
2630 0 : fprintf( fpOut, " Style = %s\n", GetStyleString() );
2631 : }
2632 : }
2633 :
2634 67 : if( poGeometry != NULL )
2635 : {
2636 : const char* pszDisplayGeometry =
2637 67 : CSLFetchNameValue(papszOptions, "DISPLAY_GEOMETRY");
2638 67 : if ( ! (pszDisplayGeometry != NULL && EQUAL(pszDisplayGeometry, "NO") ) )
2639 57 : poGeometry->dumpReadable( fpOut, " ", papszOptions );
2640 : }
2641 :
2642 67 : fprintf( fpOut, "\n" );
2643 67 : }
2644 :
2645 : /************************************************************************/
2646 : /* OGR_F_DumpReadable() */
2647 : /************************************************************************/
2648 :
2649 : /**
2650 : * \brief Dump this feature in a human readable form.
2651 : *
2652 : * This dumps the attributes, and geometry; however, it doesn't definition
2653 : * information (other than field types and names), nor does it report the
2654 : * geometry spatial reference system.
2655 : *
2656 : * This function is the same as the C++ method OGRFeature::DumpReadable().
2657 : *
2658 : * @param hFeat handle to the feature to dump.
2659 : * @param fpOut the stream to write to, such as strout.
2660 : */
2661 :
2662 0 : void OGR_F_DumpReadable( OGRFeatureH hFeat, FILE *fpOut )
2663 :
2664 : {
2665 0 : VALIDATE_POINTER0( hFeat, "OGR_F_DumpReadable" );
2666 :
2667 0 : ((OGRFeature *) hFeat)->DumpReadable( fpOut );
2668 : }
2669 :
2670 : /************************************************************************/
2671 : /* GetFID() */
2672 : /************************************************************************/
2673 :
2674 : /**
2675 : * \fn long OGRFeature::GetFID();
2676 : *
2677 : * \brief Get feature identifier.
2678 : *
2679 : * This method is the same as the C function OGR_F_GetFID().
2680 : *
2681 : * @return feature id or OGRNullFID if none has been assigned.
2682 : */
2683 :
2684 : /************************************************************************/
2685 : /* OGR_F_GetFID() */
2686 : /************************************************************************/
2687 :
2688 : /**
2689 : * \brief Get feature identifier.
2690 : *
2691 : * This function is the same as the C++ method OGRFeature::GetFID().
2692 : *
2693 : * @param hFeat handle to the feature from which to get the feature
2694 : * identifier.
2695 : * @return feature id or OGRNullFID if none has been assigned.
2696 : */
2697 :
2698 431 : long OGR_F_GetFID( OGRFeatureH hFeat )
2699 :
2700 : {
2701 431 : VALIDATE_POINTER1( hFeat, "OGR_F_GetFID", 0 );
2702 :
2703 431 : return ((OGRFeature *) hFeat)->GetFID();
2704 : }
2705 :
2706 : /************************************************************************/
2707 : /* SetFID() */
2708 : /************************************************************************/
2709 :
2710 : /**
2711 : * \brief Set the feature identifier.
2712 : *
2713 : * For specific types of features this operation may fail on illegal
2714 : * features ids. Generally it always succeeds. Feature ids should be
2715 : * greater than or equal to zero, with the exception of OGRNullFID (-1)
2716 : * indicating that the feature id is unknown.
2717 : *
2718 : * This method is the same as the C function OGR_F_SetFID().
2719 : *
2720 : * @param nFID the new feature identifier value to assign.
2721 : *
2722 : * @return On success OGRERR_NONE, or on failure some other value.
2723 : */
2724 :
2725 1819035 : OGRErr OGRFeature::SetFID( long nFID )
2726 :
2727 : {
2728 1819035 : this->nFID = nFID;
2729 :
2730 1819035 : return OGRERR_NONE;
2731 : }
2732 :
2733 : /************************************************************************/
2734 : /* OGR_F_SetFID() */
2735 : /************************************************************************/
2736 :
2737 : /**
2738 : * \brief Set the feature identifier.
2739 : *
2740 : * For specific types of features this operation may fail on illegal
2741 : * features ids. Generally it always succeeds. Feature ids should be
2742 : * greater than or equal to zero, with the exception of OGRNullFID (-1)
2743 : * indicating that the feature id is unknown.
2744 : *
2745 : * This function is the same as the C++ method OGRFeature::SetFID().
2746 : *
2747 : * @param hFeat handle to the feature to set the feature id to.
2748 : * @param nFID the new feature identifier value to assign.
2749 : *
2750 : * @return On success OGRERR_NONE, or on failure some other value.
2751 : */
2752 :
2753 128 : OGRErr OGR_F_SetFID( OGRFeatureH hFeat, long nFID )
2754 :
2755 : {
2756 128 : VALIDATE_POINTER1( hFeat, "OGR_F_SetFID", CE_Failure );
2757 :
2758 128 : return ((OGRFeature *) hFeat)->SetFID(nFID);
2759 : }
2760 :
2761 : /************************************************************************/
2762 : /* Equal() */
2763 : /************************************************************************/
2764 :
2765 : /**
2766 : * \brief Test if two features are the same.
2767 : *
2768 : * Two features are considered equal if the share them (pointer equality)
2769 : * same OGRFeatureDefn, have the same field values, and the same geometry
2770 : * (as tested by OGRGeometry::Equal()) as well as the same feature id.
2771 : *
2772 : * This method is the same as the C function OGR_F_Equal().
2773 : *
2774 : * @param poFeature the other feature to test this one against.
2775 : *
2776 : * @return TRUE if they are equal, otherwise FALSE.
2777 : */
2778 :
2779 21275 : OGRBoolean OGRFeature::Equal( OGRFeature * poFeature )
2780 :
2781 : {
2782 21275 : if( poFeature == this )
2783 1 : return TRUE;
2784 :
2785 21274 : if( GetFID() != poFeature->GetFID() )
2786 20895 : return FALSE;
2787 :
2788 379 : if( GetDefnRef() != poFeature->GetDefnRef() )
2789 0 : return FALSE;
2790 :
2791 : int i;
2792 379 : int nFields = GetDefnRef()->GetFieldCount();
2793 2826 : for(i=0; i<nFields; i++)
2794 : {
2795 2479 : if( IsFieldSet(i) != poFeature->IsFieldSet(i) )
2796 0 : return FALSE;
2797 :
2798 2479 : if( !IsFieldSet(i) )
2799 561 : continue;
2800 :
2801 1918 : switch (GetDefnRef()->GetFieldDefn(i)->GetType() )
2802 : {
2803 : case OFTInteger:
2804 755 : if( GetFieldAsInteger(i) !=
2805 : poFeature->GetFieldAsInteger(i) )
2806 1 : return FALSE;
2807 754 : break;
2808 :
2809 : case OFTReal:
2810 389 : if( GetFieldAsDouble(i) !=
2811 : poFeature->GetFieldAsDouble(i) )
2812 3 : return FALSE;
2813 386 : break;
2814 :
2815 : case OFTString:
2816 616 : if ( strcmp(GetFieldAsString(i),
2817 : poFeature->GetFieldAsString(i)) != 0 )
2818 1 : return FALSE;
2819 615 : break;
2820 :
2821 : case OFTIntegerList:
2822 : {
2823 : int nCount1, nCount2;
2824 34 : const int* pnList1 = GetFieldAsIntegerList(i, &nCount1);
2825 : const int* pnList2 =
2826 34 : poFeature->GetFieldAsIntegerList(i, &nCount2);
2827 34 : if( nCount1 != nCount2 )
2828 1 : return FALSE;
2829 : int j;
2830 95 : for(j=0;j<nCount1;j++)
2831 : {
2832 63 : if( pnList1[j] != pnList2[j] )
2833 1 : return FALSE;
2834 : }
2835 32 : break;
2836 : }
2837 :
2838 : case OFTRealList:
2839 : {
2840 : int nCount1, nCount2;
2841 : const double* padfList1 =
2842 29 : GetFieldAsDoubleList(i, &nCount1);
2843 : const double* padfList2 =
2844 29 : poFeature->GetFieldAsDoubleList(i, &nCount2);
2845 29 : if( nCount1 != nCount2 )
2846 1 : return FALSE;
2847 : int j;
2848 83 : for(j=0;j<nCount1;j++)
2849 : {
2850 56 : if( padfList1[j] != padfList2[j] )
2851 1 : return FALSE;
2852 : }
2853 27 : break;
2854 : }
2855 :
2856 : case OFTStringList:
2857 : {
2858 : int nCount1, nCount2;
2859 27 : char** papszList1 = GetFieldAsStringList(i);
2860 27 : char** papszList2 = poFeature->GetFieldAsStringList(i);
2861 27 : nCount1 = CSLCount(papszList1);
2862 27 : nCount2 = CSLCount(papszList2);
2863 27 : if( nCount1 != nCount2 )
2864 1 : return FALSE;
2865 : int j;
2866 77 : for(j=0;j<nCount1;j++)
2867 : {
2868 52 : if( strcmp(papszList1[j], papszList2[j]) != 0 )
2869 1 : return FALSE;
2870 : }
2871 25 : break;
2872 : }
2873 :
2874 : case OFTTime:
2875 : case OFTDate:
2876 : case OFTDateTime:
2877 : {
2878 : int nYear1, nMonth1, nDay1, nHour1,
2879 : nMinute1, nSecond1, nTZFlag1;
2880 : int nYear2, nMonth2, nDay2, nHour2,
2881 : nMinute2, nSecond2, nTZFlag2;
2882 : GetFieldAsDateTime(i, &nYear1, &nMonth1, &nDay1,
2883 68 : &nHour1, &nMinute1, &nSecond1, &nTZFlag1);
2884 : poFeature->GetFieldAsDateTime(i, &nYear2, &nMonth2, &nDay2,
2885 68 : &nHour2, &nMinute2, &nSecond2, &nTZFlag2);
2886 :
2887 68 : if( !(nYear1 == nYear2 && nMonth1 == nMonth2 &&
2888 : nDay1 == nDay2 && nHour1 == nHour2 &&
2889 : nMinute1 == nMinute2 && nSecond1 == nSecond2 &&
2890 : nTZFlag1 == nTZFlag2) )
2891 21 : return FALSE;
2892 47 : break;
2893 : }
2894 :
2895 : case OFTBinary:
2896 : {
2897 : int nCount1, nCount2;
2898 0 : GByte* pabyData1 = GetFieldAsBinary(i, &nCount1);
2899 0 : GByte* pabyData2 = poFeature->GetFieldAsBinary(i, &nCount2);
2900 0 : if( nCount1 != nCount2 )
2901 0 : return FALSE;
2902 0 : if( memcmp(pabyData1, pabyData2, nCount1) != 0 )
2903 0 : return FALSE;
2904 0 : break;
2905 : }
2906 :
2907 : default:
2908 0 : if( strcmp(GetFieldAsString(i),
2909 : poFeature->GetFieldAsString(i)) != 0 )
2910 0 : return FALSE;
2911 : break;
2912 : }
2913 : }
2914 :
2915 347 : if( GetGeometryRef() == NULL && poFeature->GetGeometryRef() != NULL )
2916 1 : return FALSE;
2917 :
2918 346 : if( GetGeometryRef() != NULL && poFeature->GetGeometryRef() == NULL )
2919 1 : return FALSE;
2920 :
2921 610 : if( GetGeometryRef() != NULL && poFeature->GetGeometryRef() != NULL
2922 265 : && (!GetGeometryRef()->Equals( poFeature->GetGeometryRef() ) ) )
2923 0 : return FALSE;
2924 :
2925 345 : return TRUE;
2926 : }
2927 :
2928 : /************************************************************************/
2929 : /* OGR_F_Equal() */
2930 : /************************************************************************/
2931 :
2932 : /**
2933 : * \brief Test if two features are the same.
2934 : *
2935 : * Two features are considered equal if the share them (handle equality)
2936 : * same OGRFeatureDefn, have the same field values, and the same geometry
2937 : * (as tested by OGR_G_Equal()) as well as the same feature id.
2938 : *
2939 : * This function is the same as the C++ method OGRFeature::Equal().
2940 : *
2941 : * @param hFeat handle to one of the feature.
2942 : * @param hOtherFeat handle to the other feature to test this one against.
2943 : *
2944 : * @return TRUE if they are equal, otherwise FALSE.
2945 : */
2946 :
2947 52 : int OGR_F_Equal( OGRFeatureH hFeat, OGRFeatureH hOtherFeat )
2948 :
2949 : {
2950 52 : VALIDATE_POINTER1( hFeat, "OGR_F_Equal", 0 );
2951 52 : VALIDATE_POINTER1( hOtherFeat, "OGR_F_Equal", 0 );
2952 :
2953 52 : return ((OGRFeature *) hFeat)->Equal( (OGRFeature *) hOtherFeat );
2954 : }
2955 :
2956 :
2957 : /************************************************************************/
2958 : /* SetFrom() */
2959 : /************************************************************************/
2960 :
2961 : /**
2962 : * \brief Set one feature from another.
2963 : *
2964 : * Overwrite the contents of this feature from the geometry and attributes
2965 : * of another. The poSrcFeature does not need to have the same
2966 : * OGRFeatureDefn. Field values are copied by corresponding field names.
2967 : * Field types do not have to exactly match. SetField() method conversion
2968 : * rules will be applied as needed.
2969 : *
2970 : * This method is the same as the C function OGR_F_SetFrom().
2971 : *
2972 : * @param poSrcFeature the feature from which geometry, and field values will
2973 : * be copied.
2974 : *
2975 : * @param bForgiving TRUE if the operation should continue despite lacking
2976 : * output fields matching some of the source fields.
2977 : *
2978 : * @return OGRERR_NONE if the operation succeeds, even if some values are
2979 : * not transferred, otherwise an error code.
2980 : */
2981 :
2982 502 : OGRErr OGRFeature::SetFrom( OGRFeature * poSrcFeature, int bForgiving )
2983 :
2984 : {
2985 : /* -------------------------------------------------------------------- */
2986 : /* Retrieve the field ids by name. */
2987 : /* -------------------------------------------------------------------- */
2988 : int iField, *panMap;
2989 : OGRErr eErr;
2990 :
2991 502 : panMap = (int *) VSIMalloc( sizeof(int) * poSrcFeature->GetFieldCount() );
2992 6428 : for( iField = 0; iField < poSrcFeature->GetFieldCount(); iField++ )
2993 : {
2994 5926 : panMap[iField] = GetFieldIndex(
2995 5926 : poSrcFeature->GetFieldDefnRef(iField)->GetNameRef() );
2996 :
2997 5926 : if( panMap[iField] == -1 )
2998 : {
2999 105 : if( bForgiving )
3000 105 : continue;
3001 : else
3002 : {
3003 0 : VSIFree(panMap);
3004 0 : return OGRERR_FAILURE;
3005 : }
3006 : }
3007 : }
3008 :
3009 502 : eErr = SetFrom( poSrcFeature, panMap, bForgiving );
3010 :
3011 502 : VSIFree(panMap);
3012 :
3013 502 : return eErr;
3014 : }
3015 :
3016 : /************************************************************************/
3017 : /* OGR_F_SetFrom() */
3018 : /************************************************************************/
3019 :
3020 : /**
3021 : * \brief Set one feature from another.
3022 : *
3023 : * Overwrite the contents of this feature from the geometry and attributes
3024 : * of another. The hOtherFeature does not need to have the same
3025 : * OGRFeatureDefn. Field values are copied by corresponding field names.
3026 : * Field types do not have to exactly match. OGR_F_SetField*() function
3027 : * conversion rules will be applied as needed.
3028 : *
3029 : * This function is the same as the C++ method OGRFeature::SetFrom().
3030 : *
3031 : * @param hFeat handle to the feature to set to.
3032 : * @param hOtherFeat handle to the feature from which geometry,
3033 : * and field values will be copied.
3034 : *
3035 : * @param bForgiving TRUE if the operation should continue despite lacking
3036 : * output fields matching some of the source fields.
3037 : *
3038 : * @return OGRERR_NONE if the operation succeeds, even if some values are
3039 : * not transferred, otherwise an error code.
3040 : */
3041 :
3042 241 : OGRErr OGR_F_SetFrom( OGRFeatureH hFeat, OGRFeatureH hOtherFeat,
3043 : int bForgiving )
3044 :
3045 : {
3046 241 : VALIDATE_POINTER1( hFeat, "OGR_F_SetFrom", CE_Failure );
3047 241 : VALIDATE_POINTER1( hOtherFeat, "OGR_F_SetFrom", CE_Failure );
3048 :
3049 : return ((OGRFeature *) hFeat)->SetFrom( (OGRFeature *) hOtherFeat,
3050 241 : bForgiving );
3051 : }
3052 :
3053 : /************************************************************************/
3054 : /* SetFrom() */
3055 : /************************************************************************/
3056 :
3057 : /**
3058 : * \brief Set one feature from another.
3059 : *
3060 : * Overwrite the contents of this feature from the geometry and attributes
3061 : * of another. The poSrcFeature does not need to have the same
3062 : * OGRFeatureDefn. Field values are copied according to the provided indices
3063 : * map. Field types do not have to exactly match. SetField() method
3064 : * conversion rules will be applied as needed. This is more efficient than
3065 : * OGR_F_SetFrom() in that this doesn't lookup the fields by their names.
3066 : * Particularly useful when the field names don't match.
3067 : *
3068 : * This method is the same as the C function OGR_F_SetFromWithMap().
3069 : *
3070 : * @param poSrcFeature the feature from which geometry, and field values will
3071 : * be copied.
3072 : *
3073 : * @param panMap Array of the indices of the feature's fields
3074 : * stored at the corresponding index of the source feature's fields. A value of
3075 : * -1 should be used to ignore the source's field. The array should not be NULL
3076 : * and be as long as the number of fields in the source feature.
3077 : *
3078 : * @param bForgiving TRUE if the operation should continue despite lacking
3079 : * output fields matching some of the source fields.
3080 : *
3081 : * @return OGRERR_NONE if the operation succeeds, even if some values are
3082 : * not transferred, otherwise an error code.
3083 : */
3084 :
3085 128238 : OGRErr OGRFeature::SetFrom( OGRFeature * poSrcFeature, int *panMap ,
3086 : int bForgiving )
3087 :
3088 : {
3089 : OGRErr eErr;
3090 :
3091 128238 : SetFID( OGRNullFID );
3092 :
3093 : /* -------------------------------------------------------------------- */
3094 : /* Set the geometry. */
3095 : /* -------------------------------------------------------------------- */
3096 128238 : eErr = SetGeometry( poSrcFeature->GetGeometryRef() );
3097 128238 : if( eErr != OGRERR_NONE )
3098 0 : return eErr;
3099 :
3100 : /* -------------------------------------------------------------------- */
3101 : /* Copy feature style string. */
3102 : /* -------------------------------------------------------------------- */
3103 128238 : SetStyleString( poSrcFeature->GetStyleString() );
3104 :
3105 : /* -------------------------------------------------------------------- */
3106 : /* Set the fields by name. */
3107 : /* -------------------------------------------------------------------- */
3108 :
3109 128238 : eErr = SetFieldsFrom( poSrcFeature, panMap, bForgiving );
3110 128238 : if( eErr != OGRERR_NONE )
3111 0 : return eErr;
3112 :
3113 128238 : return OGRERR_NONE;
3114 : }
3115 :
3116 : /************************************************************************/
3117 : /* OGR_F_SetFromWithMap() */
3118 : /************************************************************************/
3119 :
3120 : /**
3121 : * \brief Set one feature from another.
3122 : *
3123 : * Overwrite the contents of this feature from the geometry and attributes
3124 : * of another. The hOtherFeature does not need to have the same
3125 : * OGRFeatureDefn. Field values are copied according to the provided indices
3126 : * map. Field types do not have to exactly match. OGR_F_SetField*() function
3127 : * conversion rules will be applied as needed. This is more efficient than
3128 : * OGR_F_SetFrom() in that this doesn't lookup the fields by their names.
3129 : * Particularly useful when the field names don't match.
3130 : *
3131 : * This function is the same as the C++ method OGRFeature::SetFrom().
3132 : *
3133 : * @param hFeat handle to the feature to set to.
3134 : * @param hOtherFeat handle to the feature from which geometry,
3135 : * and field values will be copied.
3136 : *
3137 : * @param panMap Array of the indices of the destination feature's fields
3138 : * stored at the corresponding index of the source feature's fields. A value of
3139 : * -1 should be used to ignore the source's field. The array should not be NULL
3140 : * and be as long as the number of fields in the source feature.
3141 : *
3142 : * @param bForgiving TRUE if the operation should continue despite lacking
3143 : * output fields matching some of the source fields.
3144 : *
3145 : * @return OGRERR_NONE if the operation succeeds, even if some values are
3146 : * not transferred, otherwise an error code.
3147 : */
3148 :
3149 381 : OGRErr OGR_F_SetFromWithMap( OGRFeatureH hFeat, OGRFeatureH hOtherFeat,
3150 : int bForgiving, int *panMap )
3151 :
3152 : {
3153 381 : VALIDATE_POINTER1( hFeat, "OGR_F_SetFrom", CE_Failure );
3154 381 : VALIDATE_POINTER1( hOtherFeat, "OGR_F_SetFrom", CE_Failure );
3155 381 : VALIDATE_POINTER1( panMap, "OGR_F_SetFrom", CE_Failure);
3156 :
3157 : return ((OGRFeature *) hFeat)->SetFrom( (OGRFeature *) hOtherFeat,
3158 381 : panMap, bForgiving );
3159 : }
3160 :
3161 : /************************************************************************/
3162 : /* SetFieldsFrom() */
3163 : /************************************************************************/
3164 :
3165 : /**
3166 : * \brief Set fields from another feature.
3167 : *
3168 : * Overwrite the fields of this feature from the attributes of
3169 : * another. The FID and the style string are not set. The poSrcFeature
3170 : * does not need to have the same OGRFeatureDefn. Field values are
3171 : * copied according to the provided indices map. Field types do not
3172 : * have to exactly match. SetField() method conversion rules will be
3173 : * applied as needed. This is more efficient than OGR_F_SetFrom() in
3174 : * that this doesn't lookup the fields by their names. Particularly
3175 : * useful when the field names don't match.
3176 : *
3177 : * @param poSrcFeature the feature from which geometry, and field values will
3178 : * be copied.
3179 : *
3180 : * @param panMap Array of the indices of the feature's fields
3181 : * stored at the corresponding index of the source feature's fields. A value of
3182 : * -1 should be used to ignore the source's field. The array should not be NULL
3183 : * and be as long as the number of fields in the source feature.
3184 : *
3185 : * @param bForgiving TRUE if the operation should continue despite lacking
3186 : * output fields matching some of the source fields.
3187 : *
3188 : * @return OGRERR_NONE if the operation succeeds, even if some values are
3189 : * not transferred, otherwise an error code.
3190 : */
3191 :
3192 128305 : OGRErr OGRFeature::SetFieldsFrom( OGRFeature * poSrcFeature, int *panMap ,
3193 : int bForgiving )
3194 :
3195 : {
3196 : int iField, iDstField;
3197 :
3198 2215074 : for( iField = 0; iField < poSrcFeature->GetFieldCount(); iField++ )
3199 : {
3200 2086769 : iDstField = panMap[iField];
3201 :
3202 2086769 : if( iDstField < 0 )
3203 292 : continue;
3204 :
3205 2086477 : if( GetFieldCount() <= iDstField )
3206 0 : return OGRERR_FAILURE;
3207 :
3208 2086477 : if( !poSrcFeature->IsFieldSet(iField) )
3209 : {
3210 934796 : UnsetField( iDstField );
3211 934796 : continue;
3212 : }
3213 :
3214 1151681 : switch( poSrcFeature->GetFieldDefnRef(iField)->GetType() )
3215 : {
3216 : case OFTInteger:
3217 730313 : SetField( iDstField, poSrcFeature->GetFieldAsInteger( iField ) );
3218 730313 : break;
3219 :
3220 : case OFTReal:
3221 4345 : SetField( iDstField, poSrcFeature->GetFieldAsDouble( iField ) );
3222 4345 : break;
3223 :
3224 : case OFTString:
3225 414089 : SetField( iDstField, poSrcFeature->GetFieldAsString( iField ) );
3226 414089 : break;
3227 :
3228 : case OFTIntegerList:
3229 : {
3230 2826 : if (GetFieldDefnRef(iDstField)->GetType() == OFTString)
3231 : {
3232 1 : SetField( iDstField, poSrcFeature->GetFieldAsString(iField) );
3233 : }
3234 : else
3235 : {
3236 : int nCount;
3237 2825 : const int *panValues = poSrcFeature->GetFieldAsIntegerList( iField, &nCount);
3238 2825 : SetField( iDstField, nCount, (int*) panValues );
3239 : }
3240 : }
3241 2826 : break;
3242 :
3243 : case OFTRealList:
3244 : {
3245 18 : if (GetFieldDefnRef(iDstField)->GetType() == OFTString)
3246 : {
3247 1 : SetField( iDstField, poSrcFeature->GetFieldAsString(iField) );
3248 : }
3249 : else
3250 : {
3251 : int nCount;
3252 17 : const double *padfValues = poSrcFeature->GetFieldAsDoubleList( iField, &nCount);
3253 17 : SetField( iDstField, nCount, (double*) padfValues );
3254 : }
3255 : }
3256 18 : break;
3257 :
3258 : case OFTDate:
3259 : case OFTDateTime:
3260 : case OFTTime:
3261 62 : if (GetFieldDefnRef(iDstField)->GetType() == OFTDate ||
3262 : GetFieldDefnRef(iDstField)->GetType() == OFTTime ||
3263 : GetFieldDefnRef(iDstField)->GetType() == OFTDateTime)
3264 : {
3265 41 : SetField( iDstField, poSrcFeature->GetRawFieldRef( iField ) );
3266 : }
3267 21 : else if (GetFieldDefnRef(iDstField)->GetType() == OFTString)
3268 : {
3269 3 : SetField( iDstField, poSrcFeature->GetFieldAsString( iField ) );
3270 : }
3271 18 : else if( !bForgiving )
3272 0 : return OGRERR_FAILURE;
3273 62 : break;
3274 :
3275 : default:
3276 28 : if( poSrcFeature->GetFieldDefnRef(iField)->GetType()
3277 : == GetFieldDefnRef(iDstField)->GetType() )
3278 : {
3279 19 : SetField( iDstField, poSrcFeature->GetRawFieldRef(iField) );
3280 : }
3281 9 : else if (GetFieldDefnRef(iDstField)->GetType() == OFTString)
3282 : {
3283 1 : SetField( iDstField, poSrcFeature->GetFieldAsString( iField ) );
3284 : }
3285 8 : else if( !bForgiving )
3286 0 : return OGRERR_FAILURE;
3287 : break;
3288 : }
3289 : }
3290 :
3291 128305 : return OGRERR_NONE;
3292 : }
3293 :
3294 : /************************************************************************/
3295 : /* GetStyleString() */
3296 : /************************************************************************/
3297 :
3298 : /**
3299 : * \brief Fetch style string for this feature.
3300 : *
3301 : * Set the OGR Feature Style Specification for details on the format of
3302 : * this string, and ogr_featurestyle.h for services available to parse it.
3303 : *
3304 : * This method is the same as the C function OGR_F_GetStyleString().
3305 : *
3306 : * @return a reference to a representation in string format, or NULL if
3307 : * there isn't one.
3308 : */
3309 :
3310 202084 : const char *OGRFeature::GetStyleString()
3311 : {
3312 : int iStyleFieldIndex;
3313 :
3314 202084 : if (m_pszStyleString)
3315 1353 : return m_pszStyleString;
3316 :
3317 200731 : iStyleFieldIndex = GetFieldIndex("OGR_STYLE");
3318 200731 : if (iStyleFieldIndex >= 0)
3319 6 : return GetFieldAsString(iStyleFieldIndex);
3320 :
3321 200725 : return NULL;
3322 : }
3323 :
3324 : /************************************************************************/
3325 : /* OGR_F_GetStyleString() */
3326 : /************************************************************************/
3327 :
3328 : /**
3329 : * \brief Fetch style string for this feature.
3330 : *
3331 : * Set the OGR Feature Style Specification for details on the format of
3332 : * this string, and ogr_featurestyle.h for services available to parse it.
3333 : *
3334 : * This function is the same as the C++ method OGRFeature::GetStyleString().
3335 : *
3336 : * @param hFeat handle to the feature to get the style from.
3337 : * @return a reference to a representation in string format, or NULL if
3338 : * there isn't one.
3339 : */
3340 :
3341 89 : const char *OGR_F_GetStyleString( OGRFeatureH hFeat )
3342 : {
3343 89 : VALIDATE_POINTER1( hFeat, "OGR_F_GetStyleString", NULL );
3344 :
3345 89 : return ((OGRFeature *)hFeat)->GetStyleString();
3346 : }
3347 :
3348 : /************************************************************************/
3349 : /* SetStyleString() */
3350 : /************************************************************************/
3351 :
3352 : /**
3353 : * \brief Set feature style string.
3354 : * This method operate exactly as
3355 : * OGRFeature::SetStyleStringDirectly() except that it does not assume
3356 : * ownership of the passed string, but instead makes a copy of it.
3357 : *
3358 : * This method is the same as the C function OGR_F_SetStyleString().
3359 : *
3360 : * @param pszString the style string to apply to this feature, cannot be NULL.
3361 : */
3362 :
3363 186720 : void OGRFeature::SetStyleString(const char *pszString)
3364 : {
3365 186720 : if (m_pszStyleString)
3366 : {
3367 16 : CPLFree(m_pszStyleString);
3368 16 : m_pszStyleString = NULL;
3369 : }
3370 :
3371 186720 : if( pszString )
3372 1379 : m_pszStyleString = CPLStrdup(pszString);
3373 186720 : }
3374 :
3375 : /************************************************************************/
3376 : /* OGR_F_SetStyleString() */
3377 : /************************************************************************/
3378 :
3379 : /**
3380 : * \brief Set feature style string.
3381 : * This method operate exactly as
3382 : * OGR_F_SetStyleStringDirectly() except that it does not assume ownership
3383 : * of the passed string, but instead makes a copy of it.
3384 : *
3385 : * This function is the same as the C++ method OGRFeature::SetStyleString().
3386 : *
3387 : * @param hFeat handle to the feature to set style to.
3388 : * @param pszStyle the style string to apply to this feature, cannot be NULL.
3389 : */
3390 :
3391 35 : void OGR_F_SetStyleString( OGRFeatureH hFeat, const char *pszStyle )
3392 :
3393 : {
3394 35 : VALIDATE_POINTER0( hFeat, "OGR_F_SetStyleString" );
3395 :
3396 35 : ((OGRFeature *)hFeat)->SetStyleString( pszStyle );
3397 : }
3398 :
3399 : /************************************************************************/
3400 : /* SetStyleStringDirectly() */
3401 : /************************************************************************/
3402 :
3403 : /**
3404 : * \brief Set feature style string.
3405 : * This method operate exactly as
3406 : * OGRFeature::SetStyleString() except that it assumes ownership of the passed
3407 : * string.
3408 : *
3409 : * This method is the same as the C function OGR_F_SetStyleStringDirectly().
3410 : *
3411 : * @param pszString the style string to apply to this feature, cannot be NULL.
3412 : */
3413 :
3414 0 : void OGRFeature::SetStyleStringDirectly(char *pszString)
3415 : {
3416 0 : if (m_pszStyleString)
3417 0 : CPLFree(m_pszStyleString);
3418 0 : m_pszStyleString = pszString;
3419 0 : }
3420 :
3421 : /************************************************************************/
3422 : /* OGR_F_SetStyleStringDirectly() */
3423 : /************************************************************************/
3424 :
3425 : /**
3426 : * \brief Set feature style string.
3427 : * This method operate exactly as
3428 : * OGR_F_SetStyleString() except that it assumes ownership of the passed
3429 : * string.
3430 : *
3431 : * This function is the same as the C++ method
3432 : * OGRFeature::SetStyleStringDirectly().
3433 : *
3434 : * @param hFeat handle to the feature to set style to.
3435 : * @param pszStyle the style string to apply to this feature, cannot be NULL.
3436 : */
3437 :
3438 0 : void OGR_F_SetStyleStringDirectly( OGRFeatureH hFeat, char *pszStyle )
3439 :
3440 : {
3441 0 : VALIDATE_POINTER0( hFeat, "OGR_F_SetStyleStringDirectly" );
3442 :
3443 0 : ((OGRFeature *)hFeat)->SetStyleStringDirectly( pszStyle );
3444 : }
3445 :
3446 : //************************************************************************/
3447 : /* SetStyleTable() */
3448 : /************************************************************************/
3449 0 : void OGRFeature::SetStyleTable(OGRStyleTable *poStyleTable)
3450 : {
3451 0 : if ( m_poStyleTable )
3452 0 : delete m_poStyleTable;
3453 0 : m_poStyleTable = ( poStyleTable ) ? poStyleTable->Clone() : NULL;
3454 0 : }
3455 :
3456 : /************************************************************************/
3457 : /* RemapFields() */
3458 : /* */
3459 : /* This is used to transform a feature "in place" from one */
3460 : /* feature defn to another with minimum work. */
3461 : /************************************************************************/
3462 :
3463 435 : OGRErr OGRFeature::RemapFields( OGRFeatureDefn *poNewDefn,
3464 : int *panRemapSource )
3465 :
3466 : {
3467 : int iDstField;
3468 : OGRField *pauNewFields;
3469 :
3470 435 : if( poNewDefn == NULL )
3471 435 : poNewDefn = poDefn;
3472 :
3473 : pauNewFields = (OGRField *) CPLCalloc( poNewDefn->GetFieldCount(),
3474 435 : sizeof(OGRField) );
3475 :
3476 4911 : for( iDstField = 0; iDstField < poDefn->GetFieldCount(); iDstField++ )
3477 : {
3478 4476 : if( panRemapSource[iDstField] == -1 )
3479 : {
3480 395 : pauNewFields[iDstField].Set.nMarker1 = OGRUnsetMarker;
3481 395 : pauNewFields[iDstField].Set.nMarker2 = OGRUnsetMarker;
3482 : }
3483 : else
3484 : {
3485 : memcpy( pauNewFields + iDstField,
3486 4081 : pauFields + panRemapSource[iDstField],
3487 8162 : sizeof(OGRField) );
3488 : }
3489 : }
3490 :
3491 : /*
3492 : ** We really should be freeing memory for old columns that
3493 : ** are no longer present. We don't for now because it is a bit messy
3494 : ** and would take too long to test.
3495 : */
3496 :
3497 : /* -------------------------------------------------------------------- */
3498 : /* Apply new definition and fields. */
3499 : /* -------------------------------------------------------------------- */
3500 435 : CPLFree( pauFields );
3501 435 : pauFields = pauNewFields;
3502 :
3503 435 : poDefn = poNewDefn;
3504 :
3505 435 : return OGRERR_NONE;
3506 : }
3507 :
3508 : /************************************************************************/
3509 : /* OGR_F_GetStyleTable() */
3510 : /************************************************************************/
3511 :
3512 0 : OGRStyleTableH OGR_F_GetStyleTable( OGRFeatureH hFeat )
3513 :
3514 : {
3515 0 : VALIDATE_POINTER1( hFeat, "OGR_F_GetStyleTable", NULL );
3516 :
3517 0 : return (OGRStyleTableH) ((OGRFeature *) hFeat)->GetStyleTable( );
3518 : }
3519 :
3520 : /************************************************************************/
3521 : /* OGR_F_SetStyleTableDirectly() */
3522 : /************************************************************************/
3523 :
3524 0 : void OGR_F_SetStyleTableDirectly( OGRFeatureH hFeat,
3525 : OGRStyleTableH hStyleTable )
3526 :
3527 : {
3528 0 : VALIDATE_POINTER0( hFeat, "OGR_F_SetStyleTableDirectly" );
3529 :
3530 0 : ((OGRFeature *) hFeat)->SetStyleTableDirectly( (OGRStyleTable *) hStyleTable);
3531 : }
3532 :
3533 : /************************************************************************/
3534 : /* OGR_F_SetStyleTable() */
3535 : /************************************************************************/
3536 :
3537 0 : void OGR_F_SetStyleTable( OGRFeatureH hFeat,
3538 : OGRStyleTableH hStyleTable )
3539 :
3540 : {
3541 0 : VALIDATE_POINTER0( hFeat, "OGR_F_SetStyleTable" );
3542 0 : VALIDATE_POINTER0( hStyleTable, "OGR_F_SetStyleTable" );
3543 :
3544 0 : ((OGRFeature *) hFeat)->SetStyleTable( (OGRStyleTable *) hStyleTable);
3545 : }
|