PageRenderTime 52ms CodeModel.GetById 30ms app.highlight 8ms RepoModel.GetById 12ms app.codeStats 0ms

/django/contrib/gis/gdal/datasource.py

https://code.google.com/p/mango-py/
Python | 128 lines | 115 code | 0 blank | 13 comment | 1 complexity | c739981dc53340c46959989ca87aa484 MD5 | raw file
  1"""
  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).
  5
  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.
  9
 10 The ds_driver keyword is used internally when a ctypes pointer
 11 is passed in directly.
 12
 13 Example:
 14  ds = DataSource('/home/foo/bar.shp')
 15  for layer in ds:
 16      for feature in layer:
 17          # Getting the geometry for the feature.
 18          g = feature.geom
 19
 20          # Getting the 'description' field for the feature.
 21          desc = feature['description']
 22
 23          # We can also increment through all of the fields
 24          #  attached to this feature.
 25          for field in feature:
 26              # Get the name of the field (e.g. 'description')
 27              nm = field.name
 28
 29              # Get the type (integer) of the field, e.g. 0 => OFTInteger
 30              t = field.type
 31
 32              # Returns the value the field; OFTIntegers return ints,
 33              #  OFTReal returns floats, all else returns string.
 34              val = field.value
 35"""
 36# ctypes prerequisites.
 37from ctypes import byref, c_void_p
 38
 39# The GDAL C library, OGR exceptions, and the Layer object.
 40from django.contrib.gis.gdal.base import GDALBase
 41from django.contrib.gis.gdal.driver import Driver
 42from django.contrib.gis.gdal.error import OGRException, OGRIndexError
 43from django.contrib.gis.gdal.layer import Layer
 44
 45# Getting the ctypes prototypes for the DataSource.
 46from django.contrib.gis.gdal.prototypes import ds as capi
 47
 48# For more information, see the OGR C API source code:
 49#  http://www.gdal.org/ogr/ogr__api_8h.html
 50#
 51# The OGR_DS_* routines are relevant here.
 52class DataSource(GDALBase):
 53    "Wraps an OGR Data Source object."
 54
 55    #### Python 'magic' routines ####
 56    def __init__(self, ds_input, ds_driver=False, write=False):
 57        # The write flag.
 58        if write:
 59            self._write = 1
 60        else:
 61            self._write = 0
 62
 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():
 66            capi.register_all()
 67
 68        if isinstance(ds_input, basestring):
 69            # The data source driver is a void pointer.
 70            ds_driver = Driver.ptr_type()
 71            try:
 72                # OGROpen will auto-detect the data source type.
 73                ds = capi.open_ds(ds_input, self._write, byref(ds_driver))
 74            except OGRException:
 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):
 79            ds = ds_input
 80        else:
 81            raise OGRException('Invalid data source input type: %s' % type(ds_input))
 82
 83        if bool(ds):
 84            self.ptr = ds
 85            self.driver = Driver(ds_driver)
 86        else:
 87            # Raise an exception if the returned pointer is NULL 
 88            raise OGRException('Invalid data source file "%s"' % ds_input)
 89
 90    def __del__(self):
 91        "Destroys this DataStructure object."
 92        if self._ptr: capi.destroy_ds(self._ptr)
 93
 94    def __iter__(self):
 95        "Allows for iteration over the layers in a data source."
 96        for i in xrange(self.layer_count):
 97            yield self[i]
 98
 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)
108        else:
109            raise TypeError('Invalid index type: %s' % type(index))
110        return Layer(l, self)
111        
112    def __len__(self):
113        "Returns the number of layers within the data source."
114        return self.layer_count
115
116    def __str__(self):
117        "Returns OGR GetName and Driver for the Data Source."
118        return '%s (%s)' % (self.name, str(self.driver))
119
120    @property
121    def layer_count(self):
122        "Returns the number of layers in the data source."
123        return capi.get_layer_count(self._ptr)
124
125    @property
126    def name(self):
127        "Returns the name of the data source."
128        return capi.get_ds_name(self._ptr)