1.. _vector_api_tut:
2
3================================================================================
4Vector API tutorial
5================================================================================
6
7This document is intended to document using the OGR C++ classes to read
8and write data from a file.  It is strongly advised that the reader first
9review the :ref:`vector_data_model` document describing
10the key classes and their roles in OGR.
11
12It also includes code snippets for the corresponding functions in C and Python.
13
14Reading From OGR
15----------------
16
17For purposes of demonstrating reading with OGR, we will construct a small
18utility for dumping point layers from an OGR data source to stdout in
19comma-delimited format.
20
21Initially it is necessary to register all the format drivers that are desired.
22This is normally accomplished by calling :cpp:func:`GDALAllRegister` which registers
23all format drivers built into GDAL/OGR.
24
25In C++ :
26
27.. code-block:: c++
28
29    #include "ogrsf_frmts.h"
30
31    int main()
32
33    {
34        GDALAllRegister();
35
36
37In C :
38
39.. code-block:: c
40
41    #include "gdal.h"
42
43    int main()
44
45    {
46        GDALAllRegister();
47
48Next we need to open the input OGR datasource.  Datasources can be files,
49RDBMSes, directories full of files, or even remote web services depending on
50the driver being used.  However, the datasource name is always a single
51string.  In this case we are hardcoded to open a particular shapefile.
52The second argument (GDAL_OF_VECTOR) tells the :cpp:func:`OGROpen` method
53that we want a vector driver to be use and that don't require update access.
54On failure NULL is returned, and
55we report an error.
56
57In C++ :
58
59.. code-block:: c++
60
61    GDALDataset       *poDS;
62
63    poDS = (GDALDataset*) GDALOpenEx( "point.shp", GDAL_OF_VECTOR, NULL, NULL, NULL );
64    if( poDS == NULL )
65    {
66        printf( "Open failed.\n" );
67        exit( 1 );
68    }
69
70In C :
71
72.. code-block:: c
73
74    GDALDatasetH hDS;
75
76    hDS = GDALOpenEx( "point.shp", GDAL_OF_VECTOR, NULL, NULL, NULL );
77    if( hDS == NULL )
78    {
79        printf( "Open failed.\n" );
80        exit( 1 );
81    }
82
83A GDALDataset can potentially have many layers associated with it.  The
84number of layers available can be queried with :cpp:func:`GDALDataset::GetLayerCount`
85and individual layers fetched by index using :cpp:func:`GDALDataset::GetLayer`.
86However, we will just fetch the layer by name.
87
88In C++ :
89
90.. code-block:: c++
91
92    OGRLayer  *poLayer;
93
94    poLayer = poDS->GetLayerByName( "point" );
95
96In C :
97
98.. code-block:: c
99
100    OGRLayerH hLayer;
101
102    hLayer = GDALDatasetGetLayerByName( hDS, "point" );
103
104
105Now we want to start reading features from the layer.  Before we start we
106could assign an attribute or spatial filter to the layer to restrict the set
107of feature we get back, but for now we are interested in getting all features.
108
109With GDAL 2.3 and C++11:
110
111.. code-block:: c++
112
113    for( auto& poFeature: poLayer )
114    {
115
116With GDAL 2.3 and C:
117
118.. code-block:: c
119
120    OGR_FOR_EACH_FEATURE_BEGIN(hFeature, hLayer)
121    {
122
123If using older GDAL versions, while it isn't strictly necessary in this
124circumstance since we are starting fresh with the layer, it is often wise
125to call :cpp:func:`OGRLayer::ResetReading` to ensure we are starting at the beginning of
126the layer.  We iterate through all the features in the layer using
127OGRLayer::GetNextFeature().  It will return NULL when we run out of features.
128
129With GDAL < 2.3 and C++ :
130
131.. code-block:: c++
132
133    OGRFeature *poFeature;
134
135    poLayer->ResetReading();
136    while( (poFeature = poLayer->GetNextFeature()) != NULL )
137    {
138
139
140With GDAL < 2.3 and C :
141
142.. code-block:: c
143
144    OGRFeatureH hFeature;
145
146    OGR_L_ResetReading(hLayer);
147    while( (hFeature = OGR_L_GetNextFeature(hLayer)) != NULL )
148    {
149
150In order to dump all the attribute fields of the feature, it is helpful
151to get the :cpp:class:`OGRFeatureDefn`.  This is an object, associated with the layer,
152containing the definitions of all the fields.  We loop over all the fields,
153and fetch and report the attributes based on their type.
154
155With GDAL 2.3 and C++11:
156
157.. code-block:: c++
158
159    for( auto&& oField: *poFeature )
160    {
161        switch( oField.GetType() )
162        {
163            case OFTInteger:
164                printf( "%d,", oField.GetInteger() );
165                break;
166            case OFTInteger64:
167                printf( CPL_FRMT_GIB ",", oField.GetInteger64() );
168                break;
169            case OFTReal:
170                printf( "%.3f,", oField.GetDouble() );
171                break;
172            case OFTString:
173                printf( "%s,", oField.GetString() );
174                break;
175            default:
176                printf( "%s,", oField.GetAsString() );
177                break;
178        }
179    }
180
181With GDAL < 2.3 and C++ :
182
183.. code-block:: c
184
185    OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
186    for( int iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
187    {
188        OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField );
189
190        switch( poFieldDefn->GetType() )
191        {
192            case OFTInteger:
193                printf( "%d,", poFeature->GetFieldAsInteger( iField ) );
194                break;
195            case OFTInteger64:
196                printf( CPL_FRMT_GIB ",", poFeature->GetFieldAsInteger64( iField ) );
197                break;
198            case OFTReal:
199                printf( "%.3f,", poFeature->GetFieldAsDouble(iField) );
200                break;
201            case OFTString:
202                printf( "%s,", poFeature->GetFieldAsString(iField) );
203                break;
204            default:
205                printf( "%s,", poFeature->GetFieldAsString(iField) );
206                break;
207        }
208    }
209
210In C :
211
212.. code-block:: c
213
214    OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer);
215    int iField;
216
217    for( iField = 0; iField < OGR_FD_GetFieldCount(hFDefn); iField++ )
218    {
219        OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, iField );
220
221        switch( OGR_Fld_GetType(hFieldDefn) )
222        {
223            case OFTInteger:
224                printf( "%d,", OGR_F_GetFieldAsInteger( hFeature, iField ) );
225                break;
226            case OFTInteger64:
227                printf( CPL_FRMT_GIB ",", OGR_F_GetFieldAsInteger64( hFeature, iField ) );
228                break;
229            case OFTReal:
230                printf( "%.3f,", OGR_F_GetFieldAsDouble( hFeature, iField) );
231                break;
232            case OFTString:
233                printf( "%s,", OGR_F_GetFieldAsString( hFeature, iField) );
234                break;
235            default:
236                printf( "%s,", OGR_F_GetFieldAsString( hFeature, iField) );
237                break;
238        }
239    }
240
241There are a few more field types than those explicitly handled above, but
242a reasonable representation of them can be fetched with the
243:cpp:func:`OGRFeature::GetFieldAsString` method.  In fact we could shorten the above
244by using GetFieldAsString() for all the types.
245
246Next we want to extract the geometry from the feature, and write out the point
247geometry x and y.   Geometries are returned as a generic :cpp:class:`OGRGeometry` pointer.
248We then determine the specific geometry type, and if it is a point, we
249cast it to point and operate on it.  If it is something else we write
250placeholders.
251
252In C++ :
253
254.. code-block:: c++
255
256    OGRGeometry *poGeometry;
257
258    poGeometry = poFeature->GetGeometryRef();
259    if( poGeometry != NULL
260            && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
261    {
262    #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)
263        OGRPoint *poPoint = poGeometry->toPoint();
264    #else
265        OGRPoint *poPoint = (OGRPoint *) poGeometry;
266    #endif
267
268        printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
269    }
270    else
271    {
272        printf( "no point geometry\n" );
273    }
274
275In C :
276
277.. code-block:: c
278
279    OGRGeometryH hGeometry;
280
281    hGeometry = OGR_F_GetGeometryRef(hFeature);
282    if( hGeometry != NULL
283            && wkbFlatten(OGR_G_GetGeometryType(hGeometry)) == wkbPoint )
284    {
285        printf( "%.3f,%3.f\n", OGR_G_GetX(hGeometry, 0), OGR_G_GetY(hGeometry, 0) );
286    }
287    else
288    {
289        printf( "no point geometry\n" );
290    }
291
292The :cpp:func:`wkbFlatten` macro is used above to convert the type for a wkbPoint25D
293(a point with a z coordinate) into the base 2D geometry type code (wkbPoint).
294For each 2D geometry type there is a corresponding 2.5D type code.  The 2D
295and 2.5D geometry cases are handled by the same C++ class, so our code will
296handle 2D or 3D cases properly.
297
298Several geometry fields can be associated to a feature.
299
300In C++ :
301
302.. code-block:: c++
303
304    OGRGeometry *poGeometry;
305    int iGeomField;
306    int nGeomFieldCount;
307
308    nGeomFieldCount = poFeature->GetGeomFieldCount();
309    for(iGeomField = 0; iGeomField < nGeomFieldCount; iGeomField ++ )
310    {
311        poGeometry = poFeature->GetGeomFieldRef(iGeomField);
312        if( poGeometry != NULL
313                && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
314        {
315    #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)
316            OGRPoint *poPoint = poGeometry->toPoint();
317    #else
318            OGRPoint *poPoint = (OGRPoint *) poGeometry;
319    #endif
320
321            printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
322        }
323        else
324        {
325            printf( "no point geometry\n" );
326        }
327    }
328
329
330In C :
331
332.. code-block:: c
333
334    OGRGeometryH hGeometry;
335    int iGeomField;
336    int nGeomFieldCount;
337
338    nGeomFieldCount = OGR_F_GetGeomFieldCount(hFeature);
339    for(iGeomField = 0; iGeomField < nGeomFieldCount; iGeomField ++ )
340    {
341        hGeometry = OGR_F_GetGeomFieldRef(hFeature, iGeomField);
342        if( hGeometry != NULL
343                && wkbFlatten(OGR_G_GetGeometryType(hGeometry)) == wkbPoint )
344        {
345            printf( "%.3f,%3.f\n", OGR_G_GetX(hGeometry, 0),
346                    OGR_G_GetY(hGeometry, 0) );
347        }
348        else
349        {
350            printf( "no point geometry\n" );
351        }
352    }
353
354
355In Python:
356
357.. code-block:: python
358
359    nGeomFieldCount = feat.GetGeomFieldCount()
360    for iGeomField in range(nGeomFieldCount):
361        geom = feat.GetGeomFieldRef(iGeomField)
362        if geom is not None and geom.GetGeometryType() == ogr.wkbPoint:
363            print "%.3f, %.3f" % ( geom.GetX(), geom.GetY() )
364        else:
365            print "no point geometry\n"
366
367Note that :cpp:func:`OGRFeature::GetGeometryRef` and :cpp:func:`OGRFeature::GetGeomFieldRef`
368return a pointer to
369the internal geometry owned by the OGRFeature.  There we don't actually
370delete the return geometry.
371
372
373With GDAL 2.3 and C++11, the looping over features is simply terminated by
374a closing curly bracket.
375
376.. code-block:: c++
377
378    }
379
380With GDAL 2.3 and C, the looping over features is simply terminated by
381the following.
382
383.. code-block:: c
384
385    }
386    OGR_FOR_EACH_FEATURE_END(hFeature)
387
388
389For GDAL < 2.3, as the :cpp:func:`OGRLayer::GetNextFeature` method
390returns a copy of the feature that is now owned by us.  So at the end of
391use we must free the feature.  We could just "delete" it, but this can cause
392problems in windows builds where the GDAL DLL has a different "heap" from the
393main program.  To be on the safe side we use a GDAL function to delete the
394feature.
395
396In C++ :
397
398.. code-block:: c++
399
400        OGRFeature::DestroyFeature( poFeature );
401    }
402
403In C :
404
405.. code-block:: c
406
407        OGR_F_Destroy( hFeature );
408    }
409
410
411The OGRLayer returned by :cpp:func:`GDALDataset::GetLayerByName` is also a reference
412to an internal layer owned by the GDALDataset so we don't need to delete
413it.  But we do need to delete the datasource in order to close the input file.
414Once again we do this with a custom delete method to avoid special win32
415heap issues.
416
417In C/C++ :
418
419.. code-block:: c++
420
421        GDALClose( poDS );
422    }
423
424
425All together our program looks like this.
426
427With GDAL 2.3 and C++11 :
428
429.. code-block:: c++
430
431    #include "ogrsf_frmts.h"
432
433    int main()
434
435    {
436        GDALAllRegister();
437
438        GDALDatasetUniquePtr poDS(GDALDataset::Open( "point.shp", GDAL_OF_VECTOR));
439        if( poDS == nullptr )
440        {
441            printf( "Open failed.\n" );
442            exit( 1 );
443        }
444
445        for( const OGRLayer* poLayer: poDS->GetLayers() )
446        {
447            for( const auto& poFeature: *poLayer )
448            {
449                for( const auto& oField: *poFeature )
450                {
451                    switch( oField.GetType() )
452                    {
453                        case OFTInteger:
454                            printf( "%d,", oField.GetInteger() );
455                            break;
456                        case OFTInteger64:
457                            printf( CPL_FRMT_GIB ",", oField.GetInteger64() );
458                            break;
459                        case OFTReal:
460                            printf( "%.3f,", oField.GetDouble() );
461                            break;
462                        case OFTString:
463                            printf( "%s,", oField.GetString() );
464                            break;
465                        default:
466                            printf( "%s,", oField.GetAsString() );
467                            break;
468                    }
469                }
470
471                const OGRGeometry *poGeometry = poFeature->GetGeometryRef();
472                if( poGeometry != nullptr
473                        && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
474                {
475                    const OGRPoint *poPoint = poGeometry->toPoint();
476
477                    printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
478                }
479                else
480                {
481                    printf( "no point geometry\n" );
482                }
483            }
484        }
485        return 0;
486    }
487
488In C++ :
489
490.. code-block:: c++
491
492    #include "ogrsf_frmts.h"
493
494    int main()
495
496    {
497        GDALAllRegister();
498
499        GDALDataset *poDS = static_cast<GDALDataset*>(
500            GDALOpenEx( "point.shp", GDAL_OF_VECTOR, NULL, NULL, NULL ));
501        if( poDS == NULL )
502        {
503            printf( "Open failed.\n" );
504            exit( 1 );
505        }
506
507        OGRLayer  *poLayer = poDS->GetLayerByName( "point" );
508        OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
509
510        poLayer->ResetReading();
511        OGRFeature *poFeature;
512        while( (poFeature = poLayer->GetNextFeature()) != NULL )
513        {
514            for( int iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
515            {
516                OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField );
517
518                switch( poFieldDefn->GetType() )
519                {
520                    case OFTInteger:
521                        printf( "%d,", poFeature->GetFieldAsInteger( iField ) );
522                        break;
523                    case OFTInteger64:
524                        printf( CPL_FRMT_GIB ",", poFeature->GetFieldAsInteger64( iField ) );
525                        break;
526                    case OFTReal:
527                        printf( "%.3f,", poFeature->GetFieldAsDouble(iField) );
528                        break;
529                    case OFTString:
530                        printf( "%s,", poFeature->GetFieldAsString(iField) );
531                        break;
532                    default:
533                        printf( "%s,", poFeature->GetFieldAsString(iField) );
534                        break;
535                }
536            }
537
538            OGRGeometry *poGeometry = poFeature->GetGeometryRef();
539            if( poGeometry != NULL
540                    && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
541            {
542                OGRPoint *poPoint = (OGRPoint *) poGeometry;
543
544                printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
545            }
546            else
547            {
548                printf( "no point geometry\n" );
549            }
550            OGRFeature::DestroyFeature( poFeature );
551        }
552
553        GDALClose( poDS );
554    }
555
556In C :
557
558.. code-block:: c
559
560    #include "gdal.h"
561
562    int main()
563
564    {
565        GDALAllRegister();
566
567        GDALDatasetH hDS;
568        OGRLayerH hLayer;
569        OGRFeatureH hFeature;
570        OGRFeatureDefnH hFDefn;
571
572        hDS = GDALOpenEx( "point.shp", GDAL_OF_VECTOR, NULL, NULL, NULL );
573        if( hDS == NULL )
574        {
575            printf( "Open failed.\n" );
576            exit( 1 );
577        }
578
579        hLayer = GDALDatasetGetLayerByName( hDS, "point" );
580        hFDefn = OGR_L_GetLayerDefn(hLayer);
581
582        OGR_L_ResetReading(hLayer);
583        while( (hFeature = OGR_L_GetNextFeature(hLayer)) != NULL )
584        {
585            int iField;
586            OGRGeometryH hGeometry;
587
588            for( iField = 0; iField < OGR_FD_GetFieldCount(hFDefn); iField++ )
589            {
590                OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, iField );
591
592                switch( OGR_Fld_GetType(hFieldDefn) )
593                {
594                    case OFTInteger:
595                        printf( "%d,", OGR_F_GetFieldAsInteger( hFeature, iField ) );
596                        break;
597                    case OFTInteger64:
598                        printf( CPL_FRMT_GIB ",", OGR_F_GetFieldAsInteger64( hFeature, iField ) );
599                        break;
600                    case OFTReal:
601                        printf( "%.3f,", OGR_F_GetFieldAsDouble( hFeature, iField) );
602                        break;
603                    case OFTString:
604                        printf( "%s,", OGR_F_GetFieldAsString( hFeature, iField) );
605                        break;
606                    default:
607                        printf( "%s,", OGR_F_GetFieldAsString( hFeature, iField) );
608                        break;
609                }
610            }
611
612            hGeometry = OGR_F_GetGeometryRef(hFeature);
613            if( hGeometry != NULL
614                && wkbFlatten(OGR_G_GetGeometryType(hGeometry)) == wkbPoint )
615            {
616                printf( "%.3f,%3.f\n", OGR_G_GetX(hGeometry, 0), OGR_G_GetY(hGeometry, 0) );
617            }
618            else
619            {
620                printf( "no point geometry\n" );
621            }
622
623            OGR_F_Destroy( hFeature );
624        }
625
626        GDALClose( hDS );
627    }
628
629
630In Python:
631
632.. code-block:: python
633
634    import sys
635    from osgeo import gdal
636
637    ds = gdal.OpenEx( "point.shp", gdal.OF_VECTOR )
638    if ds is None:
639        print "Open failed.\n"
640        sys.exit( 1 )
641
642    lyr = ds.GetLayerByName( "point" )
643
644    lyr.ResetReading()
645
646    for feat in lyr:
647
648        feat_defn = lyr.GetLayerDefn()
649        for i in range(feat_defn.GetFieldCount()):
650            field_defn = feat_defn.GetFieldDefn(i)
651
652            # Tests below can be simplified with just :
653            # print feat.GetField(i)
654            if field_defn.GetType() == ogr.OFTInteger or field_defn.GetType() == ogr.OFTInteger64:
655                print "%d" % feat.GetFieldAsInteger64(i)
656            elif field_defn.GetType() == ogr.OFTReal:
657                print "%.3f" % feat.GetFieldAsDouble(i)
658            elif field_defn.GetType() == ogr.OFTString:
659                print "%s" % feat.GetFieldAsString(i)
660            else:
661                print "%s" % feat.GetFieldAsString(i)
662
663        geom = feat.GetGeometryRef()
664        if geom is not None and geom.GetGeometryType() == ogr.wkbPoint:
665            print "%.3f, %.3f" % ( geom.GetX(), geom.GetY() )
666        else:
667            print "no point geometry\n"
668
669    ds = None
670
671Writing To OGR
672--------------
673
674As an example of writing through OGR, we will do roughly the opposite of the
675above.  A short program that reads comma separated values from input text
676will be written to a point shapefile via OGR.
677
678As usual, we start by registering all the drivers, and then fetch the
679Shapefile driver as we will need it to create our output file.
680
681In C++ :
682
683.. code-block:: c++
684
685    #include "ogrsf_frmts.h"
686
687    int main()
688    {
689        const char *pszDriverName = "ESRI Shapefile";
690        GDALDriver *poDriver;
691
692        GDALAllRegister();
693
694        poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName );
695        if( poDriver == NULL )
696        {
697            printf( "%s driver not available.\n", pszDriverName );
698            exit( 1 );
699        }
700
701In C :
702
703.. code-block:: c
704
705    #include "ogr_api.h"
706
707    int main()
708    {
709        const char *pszDriverName = "ESRI Shapefile";
710        GDALDriver *poDriver;
711
712        GDALAllRegister();
713
714        poDriver = (GDALDriver*) GDALGetDriverByName(pszDriverName );
715        if( poDriver == NULL )
716        {
717            printf( "%s driver not available.\n", pszDriverName );
718            exit( 1 );
719        }
720
721Next we create the datasource.  The ESRI Shapefile driver allows us to create
722a directory full of shapefiles, or a single shapefile as a datasource.  In
723this case we will explicitly create a single file by including the extension
724in the name.  Other drivers behave differently.
725The second, third, fourth and fifth argument are related to raster dimensions
726(in case the driver has raster capabilities). The last argument to
727the call is a list of option values, but we will just be using defaults in
728this case.  Details of the options supported are also format specific.
729
730In C ++ :
731
732.. code-block:: c++
733
734    GDALDataset *poDS;
735
736    poDS = poDriver->Create( "point_out.shp", 0, 0, 0, GDT_Unknown, NULL );
737    if( poDS == NULL )
738    {
739        printf( "Creation of output file failed.\n" );
740        exit( 1 );
741    }
742
743
744In C :
745
746.. code-block:: c
747
748    GDALDatasetH hDS;
749
750    hDS = GDALCreate( hDriver, "point_out.shp", 0, 0, 0, GDT_Unknown, NULL );
751    if( hDS == NULL )
752    {
753        printf( "Creation of output file failed.\n" );
754        exit( 1 );
755    }
756
757Now we create the output layer.  In this case since the datasource is a
758single file, we can only have one layer.  We pass wkbPoint to specify the
759type of geometry supported by this layer.  In this case we aren't passing
760any coordinate system information or other special layer creation options.
761
762In C++ :
763
764.. code-block:: c++
765
766    OGRLayer *poLayer;
767
768    poLayer = poDS->CreateLayer( "point_out", NULL, wkbPoint, NULL );
769    if( poLayer == NULL )
770    {
771        printf( "Layer creation failed.\n" );
772        exit( 1 );
773    }
774
775
776In C :
777
778.. code-block:: c
779
780    OGRLayerH hLayer;
781
782    hLayer = GDALDatasetCreateLayer( hDS, "point_out", NULL, wkbPoint, NULL );
783    if( hLayer == NULL )
784    {
785        printf( "Layer creation failed.\n" );
786        exit( 1 );
787    }
788
789
790Now that the layer exists, we need to create any attribute fields that should
791appear on the layer.  Fields must be added to the layer before any features
792are written.  To create a field we initialize an :cpp:union:`OGRField` object with the
793information about the field.  In the case of Shapefiles, the field width and
794precision is significant in the creation of the output .dbf file, so we
795set it specifically, though generally the defaults are OK.  For this example
796we will just have one attribute, a name string associated with the x,y point.
797
798Note that the template OGRField we pass to :cpp:func:`OGRLayer::CreateField` is copied internally.
799We retain ownership of the object.
800
801In C++:
802
803.. code-block:: c++
804
805    OGRFieldDefn oField( "Name", OFTString );
806
807    oField.SetWidth(32);
808
809    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
810    {
811        printf( "Creating Name field failed.\n" );
812        exit( 1 );
813    }
814
815
816In C:
817
818.. code-block:: c
819
820    OGRFieldDefnH hFieldDefn;
821
822    hFieldDefn = OGR_Fld_Create( "Name", OFTString );
823
824    OGR_Fld_SetWidth( hFieldDefn, 32);
825
826    if( OGR_L_CreateField( hLayer, hFieldDefn, TRUE ) != OGRERR_NONE )
827    {
828        printf( "Creating Name field failed.\n" );
829        exit( 1 );
830    }
831
832    OGR_Fld_Destroy(hFieldDefn);
833
834
835The following snipping loops reading lines of the form "x,y,name" from stdin,
836and parsing them.
837
838In C++ and in C :
839
840.. code-block:: c
841
842    double x, y;
843    char szName[33];
844
845    while( !feof(stdin)
846           && fscanf( stdin, "%lf,%lf,%32s", &x, &y, szName ) == 3 )
847    {
848
849To write a feature to disk, we must create a local OGRFeature, set attributes
850and attach geometry before trying to write it to the layer.  It is
851imperative that this feature be instantiated from the OGRFeatureDefn
852associated with the layer it will be written to.
853
854In C++ :
855
856.. code-block:: c++
857
858        OGRFeature *poFeature;
859
860        poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
861        poFeature->SetField( "Name", szName );
862
863In C :
864
865.. code-block:: c
866
867        OGRFeatureH hFeature;
868
869        hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
870        OGR_F_SetFieldString( hFeature, OGR_F_GetFieldIndex(hFeature, "Name"), szName );
871
872We create a local geometry object, and assign its copy (indirectly) to the feature.
873The :cpp:func:`OGRFeature::SetGeometryDirectly` differs from :cpp:func:`OGRFeature::SetGeometry`
874in that the direct method gives ownership of the geometry to the feature.
875This is generally more efficient as it avoids an extra deep object copy
876of the geometry.
877
878In C++ :
879
880.. code-block:: c++
881
882        OGRPoint pt;
883        pt.setX( x );
884        pt.setY( y );
885
886        poFeature->SetGeometry( &pt );
887
888
889In C :
890
891.. code-block:: c
892
893        OGRGeometryH hPt;
894        hPt = OGR_G_CreateGeometry(wkbPoint);
895        OGR_G_SetPoint_2D(hPt, 0, x, y);
896
897        OGR_F_SetGeometry( hFeature, hPt );
898        OGR_G_DestroyGeometry(hPt);
899
900
901Now we create a feature in the file.  The :cpp:func:`OGRLayer::CreateFeature` does not
902take ownership of our feature so we clean it up when done with it.
903
904In C++ :
905
906.. code-block:: c++
907
908        if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
909        {
910            printf( "Failed to create feature in shapefile.\n" );
911           exit( 1 );
912        }
913
914        OGRFeature::DestroyFeature( poFeature );
915   }
916
917In C :
918
919.. code-block:: c
920
921        if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
922        {
923            printf( "Failed to create feature in shapefile.\n" );
924           exit( 1 );
925        }
926
927        OGR_F_Destroy( hFeature );
928   }
929
930
931Finally we need to close down the datasource in order to ensure headers
932are written out in an orderly way and all resources are recovered.
933
934In C/C++ :
935
936.. code-block:: c
937
938        GDALClose( poDS );
939    }
940
941
942The same program all in one block looks like this:
943
944In C++ :
945
946.. code-block:: c++
947
948    #include "ogrsf_frmts.h"
949
950    int main()
951    {
952        const char *pszDriverName = "ESRI Shapefile";
953        GDALDriver *poDriver;
954
955        GDALAllRegister();
956
957        poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName );
958        if( poDriver == NULL )
959        {
960            printf( "%s driver not available.\n", pszDriverName );
961            exit( 1 );
962        }
963
964        GDALDataset *poDS;
965
966        poDS = poDriver->Create( "point_out.shp", 0, 0, 0, GDT_Unknown, NULL );
967        if( poDS == NULL )
968        {
969            printf( "Creation of output file failed.\n" );
970            exit( 1 );
971        }
972
973        OGRLayer *poLayer;
974
975        poLayer = poDS->CreateLayer( "point_out", NULL, wkbPoint, NULL );
976        if( poLayer == NULL )
977        {
978            printf( "Layer creation failed.\n" );
979            exit( 1 );
980        }
981
982        OGRFieldDefn oField( "Name", OFTString );
983
984        oField.SetWidth(32);
985
986        if( poLayer->CreateField( &oField ) != OGRERR_NONE )
987        {
988            printf( "Creating Name field failed.\n" );
989            exit( 1 );
990        }
991
992        double x, y;
993        char szName[33];
994
995        while( !feof(stdin)
996            && fscanf( stdin, "%lf,%lf,%32s", &x, &y, szName ) == 3 )
997        {
998            OGRFeature *poFeature;
999
1000            poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
1001            poFeature->SetField( "Name", szName );
1002
1003            OGRPoint pt;
1004
1005            pt.setX( x );
1006            pt.setY( y );
1007
1008            poFeature->SetGeometry( &pt );
1009
1010            if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
1011            {
1012                printf( "Failed to create feature in shapefile.\n" );
1013                exit( 1 );
1014            }
1015
1016            OGRFeature::DestroyFeature( poFeature );
1017        }
1018
1019        GDALClose( poDS );
1020    }
1021
1022
1023In C :
1024
1025.. code-block:: c
1026
1027    #include "gdal.h"
1028
1029    int main()
1030    {
1031        const char *pszDriverName = "ESRI Shapefile";
1032        GDALDriverH hDriver;
1033        GDALDatasetH hDS;
1034        OGRLayerH hLayer;
1035        OGRFieldDefnH hFieldDefn;
1036        double x, y;
1037        char szName[33];
1038
1039        GDALAllRegister();
1040
1041        hDriver = GDALGetDriverByName( pszDriverName );
1042        if( hDriver == NULL )
1043        {
1044            printf( "%s driver not available.\n", pszDriverName );
1045            exit( 1 );
1046        }
1047
1048        hDS = GDALCreate( hDriver, "point_out.shp", 0, 0, 0, GDT_Unknown, NULL );
1049        if( hDS == NULL )
1050        {
1051            printf( "Creation of output file failed.\n" );
1052            exit( 1 );
1053        }
1054
1055        hLayer = GDALDatasetCreateLayer( hDS, "point_out", NULL, wkbPoint, NULL );
1056        if( hLayer == NULL )
1057        {
1058            printf( "Layer creation failed.\n" );
1059            exit( 1 );
1060        }
1061
1062        hFieldDefn = OGR_Fld_Create( "Name", OFTString );
1063
1064        OGR_Fld_SetWidth( hFieldDefn, 32);
1065
1066        if( OGR_L_CreateField( hLayer, hFieldDefn, TRUE ) != OGRERR_NONE )
1067        {
1068            printf( "Creating Name field failed.\n" );
1069            exit( 1 );
1070        }
1071
1072        OGR_Fld_Destroy(hFieldDefn);
1073
1074        while( !feof(stdin)
1075            && fscanf( stdin, "%lf,%lf,%32s", &x, &y, szName ) == 3 )
1076        {
1077            OGRFeatureH hFeature;
1078            OGRGeometryH hPt;
1079
1080            hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
1081            OGR_F_SetFieldString( hFeature, OGR_F_GetFieldIndex(hFeature, "Name"), szName );
1082
1083            hPt = OGR_G_CreateGeometry(wkbPoint);
1084            OGR_G_SetPoint_2D(hPt, 0, x, y);
1085
1086            OGR_F_SetGeometry( hFeature, hPt );
1087            OGR_G_DestroyGeometry(hPt);
1088
1089            if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
1090            {
1091            printf( "Failed to create feature in shapefile.\n" );
1092            exit( 1 );
1093            }
1094
1095            OGR_F_Destroy( hFeature );
1096        }
1097
1098        GDALClose( hDS );
1099    }
1100
1101
1102In Python :
1103
1104.. code-block:: python
1105
1106    import sys
1107    from osgeo import gdal
1108    from osgeo import ogr
1109    import string
1110
1111    driverName = "ESRI Shapefile"
1112    drv = gdal.GetDriverByName( driverName )
1113    if drv is None:
1114        print "%s driver not available.\n" % driverName
1115        sys.exit( 1 )
1116
1117    ds = drv.Create( "point_out.shp", 0, 0, 0, gdal.GDT_Unknown )
1118    if ds is None:
1119        print "Creation of output file failed.\n"
1120        sys.exit( 1 )
1121
1122    lyr = ds.CreateLayer( "point_out", None, ogr.wkbPoint )
1123    if lyr is None:
1124        print "Layer creation failed.\n"
1125        sys.exit( 1 )
1126
1127    field_defn = ogr.FieldDefn( "Name", ogr.OFTString )
1128    field_defn.SetWidth( 32 )
1129
1130    if lyr.CreateField ( field_defn ) != 0:
1131        print "Creating Name field failed.\n"
1132        sys.exit( 1 )
1133
1134    # Expected format of user input: x y name
1135    linestring = raw_input()
1136    linelist = string.split(linestring)
1137
1138    while len(linelist) == 3:
1139        x = float(linelist[0])
1140        y = float(linelist[1])
1141        name = linelist[2]
1142
1143        feat = ogr.Feature( lyr.GetLayerDefn())
1144        feat.SetField( "Name", name )
1145
1146        pt = ogr.Geometry(ogr.wkbPoint)
1147        pt.SetPoint_2D(0, x, y)
1148
1149        feat.SetGeometry(pt)
1150
1151        if lyr.CreateFeature(feat) != 0:
1152            print "Failed to create feature in shapefile.\n"
1153            sys.exit( 1 )
1154
1155        feat.Destroy()
1156
1157        linestring = raw_input()
1158        linelist = string.split(linestring)
1159
1160    ds = None
1161
1162
1163Several geometry fields can be associated to a feature. This capability
1164is just available for a few file formats, such as PostGIS.
1165
1166To create such datasources, geometry fields must be first created.
1167Spatial reference system objects can be associated to each geometry field.
1168
1169In C++ :
1170
1171.. code-block:: c++
1172
1173    OGRGeomFieldDefn oPointField( "PointField", wkbPoint );
1174    OGRSpatialReference* poSRS = new OGRSpatialReference();
1175    poSRS->importFromEPSG(4326);
1176    oPointField.SetSpatialRef(poSRS);
1177    poSRS->Release();
1178
1179    if( poLayer->CreateGeomField( &oPointField ) != OGRERR_NONE )
1180    {
1181        printf( "Creating field PointField failed.\n" );
1182        exit( 1 );
1183    }
1184
1185    OGRGeomFieldDefn oFieldPoint2( "PointField2", wkbPoint );
1186    poSRS = new OGRSpatialReference();
1187    poSRS->importFromEPSG(32631);
1188    oPointField2.SetSpatialRef(poSRS);
1189    poSRS->Release();
1190
1191    if( poLayer->CreateGeomField( &oPointField2 ) != OGRERR_NONE )
1192    {
1193        printf( "Creating field PointField2 failed.\n" );
1194        exit( 1 );
1195    }
1196
1197
1198In C :
1199
1200.. code-block:: c
1201
1202    OGRGeomFieldDefnH hPointField;
1203    OGRGeomFieldDefnH hPointField2;
1204    OGRSpatialReferenceH hSRS;
1205
1206    hPointField = OGR_GFld_Create( "PointField", wkbPoint );
1207    hSRS = OSRNewSpatialReference( NULL );
1208    OSRImportFromEPSG(hSRS, 4326);
1209    OGR_GFld_SetSpatialRef(hPointField, hSRS);
1210    OSRRelease(hSRS);
1211
1212    if( OGR_L_CreateGeomField( hLayer, hPointField ) != OGRERR_NONE )
1213    {
1214        printf( "Creating field PointField failed.\n" );
1215        exit( 1 );
1216    }
1217
1218    OGR_GFld_Destroy( hPointField );
1219
1220    hPointField2 = OGR_GFld_Create( "PointField2", wkbPoint );
1221    OSRImportFromEPSG(hSRS, 32631);
1222    OGR_GFld_SetSpatialRef(hPointField2, hSRS);
1223    OSRRelease(hSRS);
1224
1225    if( OGR_L_CreateGeomField( hLayer, hPointField2 ) != OGRERR_NONE )
1226    {
1227        printf( "Creating field PointField2 failed.\n" );
1228        exit( 1 );
1229    }
1230
1231    OGR_GFld_Destroy( hPointField2 );
1232
1233
1234To write a feature to disk, we must create a local OGRFeature, set attributes
1235and attach geometries before trying to write it to the layer.  It is
1236imperative that this feature be instantiated from the OGRFeatureDefn
1237associated with the layer it will be written to.
1238
1239In C++ :
1240
1241.. code-block:: c++
1242
1243        OGRFeature *poFeature;
1244        OGRGeometry *poGeometry;
1245        char* pszWKT;
1246
1247        poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
1248
1249        pszWKT = (char*) "POINT (2 49)";
1250        OGRGeometryFactory::createFromWkt( &pszWKT, NULL, &poGeometry );
1251        poFeature->SetGeomFieldDirectly( "PointField", poGeometry );
1252
1253        pszWKT = (char*) "POINT (500000 4500000)";
1254        OGRGeometryFactory::createFromWkt( &pszWKT, NULL, &poGeometry );
1255        poFeature->SetGeomFieldDirectly( "PointField2", poGeometry );
1256
1257        if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
1258        {
1259            printf( "Failed to create feature.\n" );
1260            exit( 1 );
1261        }
1262
1263        OGRFeature::DestroyFeature( poFeature );
1264
1265In C :
1266
1267.. code-block:: c
1268
1269        OGRFeatureH hFeature;
1270        OGRGeometryH hGeometry;
1271        char* pszWKT;
1272
1273        poFeature = OGR_F_Create( OGR_L_GetLayerDefn(hLayer) );
1274
1275        pszWKT = (char*) "POINT (2 49)";
1276        OGR_G_CreateFromWkt( &pszWKT, NULL, &hGeometry );
1277        OGR_F_SetGeomFieldDirectly( hFeature,
1278            OGR_F_GetGeomFieldIndex(hFeature, "PointField"), hGeometry );
1279
1280        pszWKT = (char*) "POINT (500000 4500000)";
1281        OGR_G_CreateFromWkt( &pszWKT, NULL, &hGeometry );
1282        OGR_F_SetGeomFieldDirectly( hFeature,
1283            OGR_F_GetGeomFieldIndex(hFeature, "PointField2"), hGeometry );
1284
1285        if( OGR_L_CreateFeature( hFeature ) != OGRERR_NONE )
1286        {
1287            printf( "Failed to create feature.\n" );
1288            exit( 1 );
1289        }
1290
1291        OGR_F_Destroy( hFeature );
1292
1293
1294In Python :
1295
1296.. code-block:: python
1297
1298        feat = ogr.Feature( lyr.GetLayerDefn() )
1299
1300        feat.SetGeomFieldDirectly( "PointField",
1301            ogr.CreateGeometryFromWkt( "POINT (2 49)" ) )
1302        feat.SetGeomFieldDirectly( "PointField2",
1303            ogr.CreateGeometryFromWkt( "POINT (500000 4500000)" ) )
1304
1305        if lyr.CreateFeature( feat ) != 0:
1306            print( "Failed to create feature.\n" );
1307            sys.exit( 1 );
1308