PageRenderTime 67ms CodeModel.GetById 58ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/django/contrib/gis/gdal/field.py

https://code.google.com/p/mango-py/
Python | 186 lines | 128 code | 26 blank | 32 comment | 10 complexity | 1c97e6b9e0cd031036ba9cf75e5e4eea MD5 | raw file
  1from ctypes import byref, c_int
  2from datetime import date, datetime, time
  3from django.contrib.gis.gdal.base import GDALBase
  4from django.contrib.gis.gdal.error import OGRException
  5from django.contrib.gis.gdal.prototypes import ds as capi
  6
  7# For more information, see the OGR C API source code:
  8#  http://www.gdal.org/ogr/ogr__api_8h.html
  9#
 10# The OGR_Fld_* routines are relevant here.
 11class Field(GDALBase):
 12    "A class that wraps an OGR Field, needs to be instantiated from a Feature object."
 13
 14    #### Python 'magic' routines ####
 15    def __init__(self, feat, index):
 16        """
 17        Initializes on the feature pointer and the integer index of
 18        the field within the feature.
 19        """
 20        # Setting the feature pointer and index.
 21        self._feat = feat
 22        self._index = index
 23
 24        # Getting the pointer for this field.
 25        fld_ptr = capi.get_feat_field_defn(feat, index)
 26        if not fld_ptr:
 27            raise OGRException('Cannot create OGR Field, invalid pointer given.')
 28        self.ptr = fld_ptr
 29
 30        # Setting the class depending upon the OGR Field Type (OFT)
 31        self.__class__ = OGRFieldTypes[self.type]
 32
 33        # OFTReal with no precision should be an OFTInteger.
 34        if isinstance(self, OFTReal) and self.precision == 0:
 35            self.__class__ = OFTInteger
 36            self._double = True
 37
 38    def __str__(self):
 39        "Returns the string representation of the Field."
 40        return str(self.value).strip()
 41
 42    #### Field Methods ####
 43    def as_double(self):
 44        "Retrieves the Field's value as a double (float)."
 45        return capi.get_field_as_double(self._feat, self._index)
 46
 47    def as_int(self):
 48        "Retrieves the Field's value as an integer."
 49        return capi.get_field_as_integer(self._feat, self._index)
 50
 51    def as_string(self):
 52        "Retrieves the Field's value as a string."
 53        return capi.get_field_as_string(self._feat, self._index)
 54
 55    def as_datetime(self):
 56        "Retrieves the Field's value as a tuple of date & time components."
 57        yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
 58        status = capi.get_field_as_datetime(self._feat, self._index, byref(yy), byref(mm), byref(dd),
 59                                            byref(hh), byref(mn), byref(ss), byref(tz))
 60        if status:
 61            return (yy, mm, dd, hh, mn, ss, tz)
 62        else:
 63            raise OGRException('Unable to retrieve date & time information from the field.')
 64
 65    #### Field Properties ####
 66    @property
 67    def name(self):
 68        "Returns the name of this Field."
 69        return capi.get_field_name(self.ptr)
 70
 71    @property
 72    def precision(self):
 73        "Returns the precision of this Field."
 74        return capi.get_field_precision(self.ptr)
 75
 76    @property
 77    def type(self):
 78        "Returns the OGR type of this Field."
 79        return capi.get_field_type(self.ptr)
 80
 81    @property
 82    def type_name(self):
 83        "Return the OGR field type name for this Field."
 84        return capi.get_field_type_name(self.type)
 85
 86    @property
 87    def value(self):
 88        "Returns the value of this Field."
 89        # Default is to get the field as a string.
 90        return self.as_string()
 91
 92    @property
 93    def width(self):
 94        "Returns the width of this Field."
 95        return capi.get_field_width(self.ptr)
 96
 97### The Field sub-classes for each OGR Field type. ###
 98class OFTInteger(Field):
 99    _double = False
100
101    @property
102    def value(self):
103        "Returns an integer contained in this field."
104        if self._double:
105            # If this is really from an OFTReal field with no precision,
106            # read as a double and cast as Python int (to prevent overflow).
107            return int(self.as_double())
108        else:
109            return self.as_int()
110
111    @property
112    def type(self):
113        """
114        GDAL uses OFTReals to represent OFTIntegers in created
115        shapefiles -- forcing the type here since the underlying field
116        type may actually be OFTReal.
117        """
118        return 0
119
120class OFTReal(Field):
121    @property
122    def value(self):
123        "Returns a float contained in this field."
124        return self.as_double()
125
126# String & Binary fields, just subclasses
127class OFTString(Field): pass
128class OFTWideString(Field): pass
129class OFTBinary(Field): pass
130
131# OFTDate, OFTTime, OFTDateTime fields.
132class OFTDate(Field):
133    @property
134    def value(self):
135        "Returns a Python `date` object for the OFTDate field."
136        try:
137            yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
138            return date(yy.value, mm.value, dd.value)
139        except (ValueError, OGRException):
140            return None
141
142class OFTDateTime(Field):
143    @property
144    def value(self):
145        "Returns a Python `datetime` object for this OFTDateTime field."
146        # TODO: Adapt timezone information.
147        #  See http://lists.maptools.org/pipermail/gdal-dev/2006-February/007990.html
148        #  The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
149        #  100=GMT, 104=GMT+1, 80=GMT-5, etc.
150        try:
151            yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
152            return datetime(yy.value, mm.value, dd.value, hh.value, mn.value, ss.value)
153        except (ValueError, OGRException):
154            return None
155
156class OFTTime(Field):
157    @property
158    def value(self):
159        "Returns a Python `time` object for this OFTTime field."
160        try:
161            yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
162            return time(hh.value, mn.value, ss.value)
163        except (ValueError, OGRException):
164            return None
165
166# List fields are also just subclasses
167class OFTIntegerList(Field): pass
168class OFTRealList(Field): pass
169class OFTStringList(Field): pass
170class OFTWideStringList(Field): pass
171
172# Class mapping dictionary for OFT Types and reverse mapping.
173OGRFieldTypes = { 0 : OFTInteger,
174                  1 : OFTIntegerList,
175                  2 : OFTReal,
176                  3 : OFTRealList,
177                  4 : OFTString,
178                  5 : OFTStringList,
179                  6 : OFTWideString,
180                  7 : OFTWideStringList,
181                  8 : OFTBinary,
182                  9 : OFTDate,
183                 10 : OFTTime,
184                 11 : OFTDateTime,
185                  }
186ROGRFieldTypes = dict([(cls, num) for num, cls in OGRFieldTypes.items()])