1 from ctypes
import byref
, c_int
2 from datetime
import date
, datetime
, time
3 from django
.contrib
.gis
.gdal
.base
import GDALBase
4 from django
.contrib
.gis
.gdal
.error
import OGRException
5 from django
.contrib
.gis
.gdal
.prototypes
import ds
as capi
7 # For more information, see the OGR C API source code:
8 # http://www.gdal.org/ogr/ogr__api_8h.html
10 # The OGR_Fld_* routines are relevant here.
11 class Field(GDALBase
):
12 "A class that wraps an OGR Field, needs to be instantiated from a Feature object."
14 #### Python 'magic' routines ####
15 def __init__(self
, feat
, index
):
17 Initializes on the feature pointer and the integer index of
18 the field within the feature.
20 # Setting the feature pointer and index.
24 # Getting the pointer for this field.
25 fld_ptr
= capi
.get_feat_field_defn(feat
, index
)
27 raise OGRException('Cannot create OGR Field, invalid pointer given.')
30 # Setting the class depending upon the OGR Field Type (OFT)
31 self
.__class
__ = OGRFieldTypes
[self
.type]
33 # OFTReal with no precision should be an OFTInteger.
34 if isinstance(self
, OFTReal
) and self
.precision
== 0:
35 self
.__class
__ = OFTInteger
39 "Returns the string representation of the Field."
40 return str(self
.value
).strip()
42 #### Field Methods ####
44 "Retrieves the Field's value as a double (float)."
45 return capi
.get_field_as_double(self
._feat
, self
._index
)
48 "Retrieves the Field's value as an integer."
49 return capi
.get_field_as_integer(self
._feat
, self
._index
)
52 "Retrieves the Field's value as a string."
53 return capi
.get_field_as_string(self
._feat
, self
._index
)
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
))
61 return (yy
, mm
, dd
, hh
, mn
, ss
, tz
)
63 raise OGRException('Unable to retrieve date & time information from the field.')
65 #### Field Properties ####
68 "Returns the name of this Field."
69 return capi
.get_field_name(self
.ptr
)
73 "Returns the precision of this Field."
74 return capi
.get_field_precision(self
.ptr
)
78 "Returns the OGR type of this Field."
79 return capi
.get_field_type(self
.ptr
)
83 "Return the OGR field type name for this Field."
84 return capi
.get_field_type_name(self
.type)
88 "Returns the value of this Field."
89 # Default is to get the field as a string.
90 return self
.as_string()
94 "Returns the width of this Field."
95 return capi
.get_field_width(self
.ptr
)
97 ### The Field sub-classes for each OGR Field type. ###
98 class OFTInteger(Field
):
103 "Returns an integer contained in this field."
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())
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.
120 class OFTReal(Field
):
123 "Returns a float contained in this field."
124 return self
.as_double()
126 # String & Binary fields, just subclasses
127 class OFTString(Field
): pass
128 class OFTWideString(Field
): pass
129 class OFTBinary(Field
): pass
131 # OFTDate, OFTTime, OFTDateTime fields.
132 class OFTDate(Field
):
135 "Returns a Python `date` object for the OFTDate field."
137 yy
, mm
, dd
, hh
, mn
, ss
, tz
= self
.as_datetime()
138 return date(yy
.value
, mm
.value
, dd
.value
)
139 except (ValueError, OGRException
):
142 class OFTDateTime(Field
):
145 "Returns a Python `datetime` object for this OFTDateTime field."
146 # TODO: Adapt timezone information.
147 # See http://lists.osgeo.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.
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
):
156 class OFTTime(Field
):
159 "Returns a Python `time` object for this OFTTime field."
161 yy
, mm
, dd
, hh
, mn
, ss
, tz
= self
.as_datetime()
162 return time(hh
.value
, mn
.value
, ss
.value
)
163 except (ValueError, OGRException
):
166 # List fields are also just subclasses
167 class OFTIntegerList(Field
): pass
168 class OFTRealList(Field
): pass
169 class OFTStringList(Field
): pass
170 class OFTWideStringList(Field
): pass
172 # Class mapping dictionary for OFT Types and reverse mapping.
173 OGRFieldTypes
= { 0 : OFTInteger
,
180 7 : OFTWideStringList
,
186 ROGRFieldTypes
= dict([(cls
, num
) for num
, cls
in OGRFieldTypes
.items()])