App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / django / contrib / gis / gdal / srs.py
blobe211bace91ddd42f1d5ca1ac369e0a488118aa45
1 """
2 The Spatial Reference class, represensents OGR Spatial Reference objects.
4 Example:
5 >>> from django.contrib.gis.gdal import SpatialReference
6 >>> srs = SpatialReference('WGS84')
7 >>> print srs
8 GEOGCS["WGS 84",
9 DATUM["WGS_1984",
10 SPHEROID["WGS 84",6378137,298.257223563,
11 AUTHORITY["EPSG","7030"]],
12 TOWGS84[0,0,0,0,0,0,0],
13 AUTHORITY["EPSG","6326"]],
14 PRIMEM["Greenwich",0,
15 AUTHORITY["EPSG","8901"]],
16 UNIT["degree",0.01745329251994328,
17 AUTHORITY["EPSG","9122"]],
18 AUTHORITY["EPSG","4326"]]
19 >>> print srs.proj
20 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs
21 >>> print srs.ellipsoid
22 (6378137.0, 6356752.3142451793, 298.25722356300003)
23 >>> print srs.projected, srs.geographic
24 False True
25 >>> srs.import_epsg(32140)
26 >>> print srs.name
27 NAD83 / Texas South Central
28 """
29 from ctypes import byref, c_char_p, c_int
31 # Getting the error checking routine and exceptions
32 from django.contrib.gis.gdal.base import GDALBase
33 from django.contrib.gis.gdal.error import SRSException
34 from django.contrib.gis.gdal.prototypes import srs as capi
36 #### Spatial Reference class. ####
37 class SpatialReference(GDALBase):
38 """
39 A wrapper for the OGRSpatialReference object. According to the GDAL Web site,
40 the SpatialReference object "provide[s] services to represent coordinate
41 systems (projections and datums) and to transform between them."
42 """
44 #### Python 'magic' routines ####
45 def __init__(self, srs_input=''):
46 """
47 Creates a GDAL OSR Spatial Reference object from the given input.
48 The input may be string of OGC Well Known Text (WKT), an integer
49 EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand
50 string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83').
51 """
52 buf = c_char_p('')
53 srs_type = 'user'
55 if isinstance(srs_input, basestring):
56 # Encoding to ASCII if unicode passed in.
57 if isinstance(srs_input, unicode):
58 srs_input = srs_input.encode('ascii')
59 try:
60 # If SRID is a string, e.g., '4326', then make acceptable
61 # as user input.
62 srid = int(srs_input)
63 srs_input = 'EPSG:%d' % srid
64 except ValueError:
65 pass
66 elif isinstance(srs_input, (int, long)):
67 # EPSG integer code was input.
68 srs_type = 'epsg'
69 elif isinstance(srs_input, self.ptr_type):
70 srs = srs_input
71 srs_type = 'ogr'
72 else:
73 raise TypeError('Invalid SRS type "%s"' % srs_type)
75 if srs_type == 'ogr':
76 # Input is already an SRS pointer.
77 srs = srs_input
78 else:
79 # Creating a new SRS pointer, using the string buffer.
80 srs = capi.new_srs(buf)
82 # If the pointer is NULL, throw an exception.
83 if not srs:
84 raise SRSException('Could not create spatial reference from: %s' % srs_input)
85 else:
86 self.ptr = srs
88 # Importing from either the user input string or an integer SRID.
89 if srs_type == 'user':
90 self.import_user_input(srs_input)
91 elif srs_type == 'epsg':
92 self.import_epsg(srs_input)
94 def __del__(self):
95 "Destroys this spatial reference."
96 if self._ptr: capi.release_srs(self._ptr)
98 def __getitem__(self, target):
99 """
100 Returns the value of the given string attribute node, None if the node
101 doesn't exist. Can also take a tuple as a parameter, (target, child),
102 where child is the index of the attribute in the WKT. For example:
104 >>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]')
105 >>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
106 >>> print srs['GEOGCS']
107 WGS 84
108 >>> print srs['DATUM']
109 WGS_1984
110 >>> print srs['AUTHORITY']
111 EPSG
112 >>> print srs['AUTHORITY', 1] # The authority value
113 4326
114 >>> print srs['TOWGS84', 4] # the fourth value in this wkt
116 >>> print srs['UNIT|AUTHORITY'] # For the units authority, have to use the pipe symbole.
117 EPSG
118 >>> print srs['UNIT|AUTHORITY', 1] # The authority value for the untis
119 9122
121 if isinstance(target, tuple):
122 return self.attr_value(*target)
123 else:
124 return self.attr_value(target)
126 def __str__(self):
127 "The string representation uses 'pretty' WKT."
128 return self.pretty_wkt
130 #### SpatialReference Methods ####
131 def attr_value(self, target, index=0):
133 The attribute value for the given target node (e.g. 'PROJCS'). The index
134 keyword specifies an index of the child node to return.
136 if not isinstance(target, basestring) or not isinstance(index, int):
137 raise TypeError
138 return capi.get_attr_value(self.ptr, target, index)
140 def auth_name(self, target):
141 "Returns the authority name for the given string target node."
142 return capi.get_auth_name(self.ptr, target)
144 def auth_code(self, target):
145 "Returns the authority code for the given string target node."
146 return capi.get_auth_code(self.ptr, target)
148 def clone(self):
149 "Returns a clone of this SpatialReference object."
150 return SpatialReference(capi.clone_srs(self.ptr))
152 def from_esri(self):
153 "Morphs this SpatialReference from ESRI's format to EPSG."
154 capi.morph_from_esri(self.ptr)
156 def identify_epsg(self):
158 This method inspects the WKT of this SpatialReference, and will
159 add EPSG authority nodes where an EPSG identifier is applicable.
161 capi.identify_epsg(self.ptr)
163 def to_esri(self):
164 "Morphs this SpatialReference to ESRI's format."
165 capi.morph_to_esri(self.ptr)
167 def validate(self):
168 "Checks to see if the given spatial reference is valid."
169 capi.srs_validate(self.ptr)
171 #### Name & SRID properties ####
172 @property
173 def name(self):
174 "Returns the name of this Spatial Reference."
175 if self.projected: return self.attr_value('PROJCS')
176 elif self.geographic: return self.attr_value('GEOGCS')
177 elif self.local: return self.attr_value('LOCAL_CS')
178 else: return None
180 @property
181 def srid(self):
182 "Returns the SRID of top-level authority, or None if undefined."
183 try:
184 return int(self.attr_value('AUTHORITY', 1))
185 except (TypeError, ValueError):
186 return None
188 #### Unit Properties ####
189 @property
190 def linear_name(self):
191 "Returns the name of the linear units."
192 units, name = capi.linear_units(self.ptr, byref(c_char_p()))
193 return name
195 @property
196 def linear_units(self):
197 "Returns the value of the linear units."
198 units, name = capi.linear_units(self.ptr, byref(c_char_p()))
199 return units
201 @property
202 def angular_name(self):
203 "Returns the name of the angular units."
204 units, name = capi.angular_units(self.ptr, byref(c_char_p()))
205 return name
207 @property
208 def angular_units(self):
209 "Returns the value of the angular units."
210 units, name = capi.angular_units(self.ptr, byref(c_char_p()))
211 return units
213 @property
214 def units(self):
216 Returns a 2-tuple of the units value and the units name,
217 and will automatically determines whether to return the linear
218 or angular units.
220 if self.projected or self.local:
221 return capi.linear_units(self.ptr, byref(c_char_p()))
222 elif self.geographic:
223 return capi.angular_units(self.ptr, byref(c_char_p()))
224 else:
225 return (None, None)
227 #### Spheroid/Ellipsoid Properties ####
228 @property
229 def ellipsoid(self):
231 Returns a tuple of the ellipsoid parameters:
232 (semimajor axis, semiminor axis, and inverse flattening)
234 return (self.semi_major, self.semi_minor, self.inverse_flattening)
236 @property
237 def semi_major(self):
238 "Returns the Semi Major Axis for this Spatial Reference."
239 return capi.semi_major(self.ptr, byref(c_int()))
241 @property
242 def semi_minor(self):
243 "Returns the Semi Minor Axis for this Spatial Reference."
244 return capi.semi_minor(self.ptr, byref(c_int()))
246 @property
247 def inverse_flattening(self):
248 "Returns the Inverse Flattening for this Spatial Reference."
249 return capi.invflattening(self.ptr, byref(c_int()))
251 #### Boolean Properties ####
252 @property
253 def geographic(self):
255 Returns True if this SpatialReference is geographic
256 (root node is GEOGCS).
258 return bool(capi.isgeographic(self.ptr))
260 @property
261 def local(self):
262 "Returns True if this SpatialReference is local (root node is LOCAL_CS)."
263 return bool(capi.islocal(self.ptr))
265 @property
266 def projected(self):
268 Returns True if this SpatialReference is a projected coordinate system
269 (root node is PROJCS).
271 return bool(capi.isprojected(self.ptr))
273 #### Import Routines #####
274 def import_epsg(self, epsg):
275 "Imports the Spatial Reference from the EPSG code (an integer)."
276 capi.from_epsg(self.ptr, epsg)
278 def import_proj(self, proj):
279 "Imports the Spatial Reference from a PROJ.4 string."
280 capi.from_proj(self.ptr, proj)
282 def import_user_input(self, user_input):
283 "Imports the Spatial Reference from the given user input string."
284 capi.from_user_input(self.ptr, user_input)
286 def import_wkt(self, wkt):
287 "Imports the Spatial Reference from OGC WKT (string)"
288 capi.from_wkt(self.ptr, byref(c_char_p(wkt)))
290 def import_xml(self, xml):
291 "Imports the Spatial Reference from an XML string."
292 capi.from_xml(self.ptr, xml)
294 #### Export Properties ####
295 @property
296 def wkt(self):
297 "Returns the WKT representation of this Spatial Reference."
298 return capi.to_wkt(self.ptr, byref(c_char_p()))
300 @property
301 def pretty_wkt(self, simplify=0):
302 "Returns the 'pretty' representation of the WKT."
303 return capi.to_pretty_wkt(self.ptr, byref(c_char_p()), simplify)
305 @property
306 def proj(self):
307 "Returns the PROJ.4 representation for this Spatial Reference."
308 return capi.to_proj(self.ptr, byref(c_char_p()))
310 @property
311 def proj4(self):
312 "Alias for proj()."
313 return self.proj
315 @property
316 def xml(self, dialect=''):
317 "Returns the XML representation of this Spatial Reference."
318 return capi.to_xml(self.ptr, byref(c_char_p()), dialect)
320 class CoordTransform(GDALBase):
321 "The coordinate system transformation object."
323 def __init__(self, source, target):
324 "Initializes on a source and target SpatialReference objects."
325 if not isinstance(source, SpatialReference) or not isinstance(target, SpatialReference):
326 raise TypeError('source and target must be of type SpatialReference')
327 self.ptr = capi.new_ct(source._ptr, target._ptr)
328 self._srs1_name = source.name
329 self._srs2_name = target.name
331 def __del__(self):
332 "Deletes this Coordinate Transformation object."
333 if self._ptr: capi.destroy_ct(self._ptr)
335 def __str__(self):
336 return 'Transform from "%s" to "%s"' % (self._srs1_name, self._srs2_name)