2 DataSource is a wrapper for the OGR Data Source object, which provides
3 an interface for reading vector geometry data from many different file
4 formats (including ESRI shapefiles).
6 When instantiating a DataSource object, use the filename of a
7 GDAL-supported data source. For example, a SHP file or a
8 TIGER/Line file from the government.
10 The ds_driver keyword is used internally when a ctypes pointer
11 is passed in directly.
14 ds = DataSource('/home/foo/bar.shp')
17 # Getting the geometry for the feature.
20 # Getting the 'description' field for the feature.
21 desc = feature['description']
23 # We can also increment through all of the fields
24 # attached to this feature.
26 # Get the name of the field (e.g. 'description')
29 # Get the type (integer) of the field, e.g. 0 => OFTInteger
32 # Returns the value the field; OFTIntegers return ints,
33 # OFTReal returns floats, all else returns string.
36 # ctypes prerequisites.
37 from ctypes
import byref
, c_void_p
39 # The GDAL C library, OGR exceptions, and the Layer object.
40 from django
.contrib
.gis
.gdal
.base
import GDALBase
41 from django
.contrib
.gis
.gdal
.driver
import Driver
42 from django
.contrib
.gis
.gdal
.error
import OGRException
, OGRIndexError
43 from django
.contrib
.gis
.gdal
.layer
import Layer
45 # Getting the ctypes prototypes for the DataSource.
46 from django
.contrib
.gis
.gdal
.prototypes
import ds
as capi
48 # For more information, see the OGR C API source code:
49 # http://www.gdal.org/ogr/ogr__api_8h.html
51 # The OGR_DS_* routines are relevant here.
52 class DataSource(GDALBase
):
53 "Wraps an OGR Data Source object."
55 #### Python 'magic' routines ####
56 def __init__(self
, ds_input
, ds_driver
=False, write
=False):
63 # Registering all the drivers, this needs to be done
64 # _before_ we try to open up a data source.
65 if not capi
.get_driver_count():
68 if isinstance(ds_input
, basestring
):
69 # The data source driver is a void pointer.
70 ds_driver
= Driver
.ptr_type()
72 # OGROpen will auto-detect the data source type.
73 ds
= capi
.open_ds(ds_input
, self
._write
, byref(ds_driver
))
75 # Making the error message more clear rather than something
76 # like "Invalid pointer returned from OGROpen".
77 raise OGRException('Could not open the datasource at "%s"' % ds_input
)
78 elif isinstance(ds_input
, self
.ptr_type
) and isinstance(ds_driver
, Driver
.ptr_type
):
81 raise OGRException('Invalid data source input type: %s' % type(ds_input
))
85 self
.driver
= Driver(ds_driver
)
87 # Raise an exception if the returned pointer is NULL
88 raise OGRException('Invalid data source file "%s"' % ds_input
)
91 "Destroys this DataStructure object."
92 if self
._ptr
: capi
.destroy_ds(self
._ptr
)
95 "Allows for iteration over the layers in a data source."
96 for i
in xrange(self
.layer_count
):
99 def __getitem__(self
, index
):
100 "Allows use of the index [] operator to get a layer at the index."
101 if isinstance(index
, basestring
):
102 l
= capi
.get_layer_by_name(self
.ptr
, index
)
103 if not l
: raise OGRIndexError('invalid OGR Layer name given: "%s"' % index
)
104 elif isinstance(index
, int):
105 if index
< 0 or index
>= self
.layer_count
:
106 raise OGRIndexError('index out of range')
107 l
= capi
.get_layer(self
._ptr
, index
)
109 raise TypeError('Invalid index type: %s' % type(index
))
110 return Layer(l
, self
)
113 "Returns the number of layers within the data source."
114 return self
.layer_count
117 "Returns OGR GetName and Driver for the Data Source."
118 return '%s (%s)' % (self
.name
, str(self
.driver
))
121 def layer_count(self
):
122 "Returns the number of layers in the data source."
123 return capi
.get_layer_count(self
._ptr
)
127 "Returns the name of the data source."
128 return capi
.get_ds_name(self
._ptr
)