2 The Spatial Reference class, represensents OGR Spatial Reference objects.
5 >>> from django.contrib.gis.gdal import SpatialReference
6 >>> srs = SpatialReference('WGS84')
10 SPHEROID["WGS 84",6378137,298.257223563,
11 AUTHORITY["EPSG","7030"]],
12 TOWGS84[0,0,0,0,0,0,0],
13 AUTHORITY["EPSG","6326"]],
15 AUTHORITY["EPSG","8901"]],
16 UNIT["degree",0.01745329251994328,
17 AUTHORITY["EPSG","9122"]],
18 AUTHORITY["EPSG","4326"]]
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
25 >>> srs.import_epsg(32140)
27 NAD83 / Texas South Central
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
):
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."
44 #### Python 'magic' routines ####
45 def __init__(self
, srs_input
=''):
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').
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')
60 # If SRID is a string, e.g., '4326', then make acceptable
63 srs_input
= 'EPSG:%d' % srid
66 elif isinstance(srs_input
, (int, long)):
67 # EPSG integer code was input.
69 elif isinstance(srs_input
, self
.ptr_type
):
73 raise TypeError('Invalid SRS type "%s"' % srs_type
)
76 # Input is already an SRS pointer.
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.
84 raise SRSException('Could not create spatial reference from: %s' % srs_input
)
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
)
95 "Destroys this spatial reference."
96 if self
._ptr
: capi
.release_srs(self
._ptr
)
98 def __getitem__(self
, target
):
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']
108 >>> print srs['DATUM']
110 >>> print srs['AUTHORITY']
112 >>> print srs['AUTHORITY', 1] # The authority value
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.
118 >>> print srs['UNIT|AUTHORITY', 1] # The authority value for the untis
121 if isinstance(target
, tuple):
122 return self
.attr_value(*target
)
124 return self
.attr_value(target
)
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):
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
)
149 "Returns a clone of this SpatialReference object."
150 return SpatialReference(capi
.clone_srs(self
.ptr
))
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
)
164 "Morphs this SpatialReference to ESRI's format."
165 capi
.morph_to_esri(self
.ptr
)
168 "Checks to see if the given spatial reference is valid."
169 capi
.srs_validate(self
.ptr
)
171 #### Name & SRID properties ####
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')
182 "Returns the SRID of top-level authority, or None if undefined."
184 return int(self
.attr_value('AUTHORITY', 1))
185 except (TypeError, ValueError):
188 #### Unit Properties ####
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()))
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()))
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()))
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()))
216 Returns a 2-tuple of the units value and the units name,
217 and will automatically determines whether to return the linear
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()))
227 #### Spheroid/Ellipsoid Properties ####
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
)
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()))
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()))
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 ####
253 def geographic(self
):
255 Returns True if this SpatialReference is geographic
256 (root node is GEOGCS).
258 return bool(capi
.isgeographic(self
.ptr
))
262 "Returns True if this SpatialReference is local (root node is LOCAL_CS)."
263 return bool(capi
.islocal(self
.ptr
))
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 ####
297 "Returns the WKT representation of this Spatial Reference."
298 return capi
.to_wkt(self
.ptr
, byref(c_char_p()))
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
)
307 "Returns the PROJ.4 representation for this Spatial Reference."
308 return capi
.to_proj(self
.ptr
, byref(c_char_p()))
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
._srs
1_name
= source
.name
329 self
._srs
2_name
= target
.name
332 "Deletes this Coordinate Transformation object."
333 if self
._ptr
: capi
.destroy_ct(self
._ptr
)
336 return 'Transform from "%s" to "%s"' % (self
._srs
1_name
, self
._srs
2_name
)