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
30 from ctypes
import byref
, c_char_p
, c_int
, c_void_p
32 # Getting the error checking routine and exceptions
33 from django
.contrib
.gis
.gdal
.base
import GDALBase
34 from django
.contrib
.gis
.gdal
.error
import OGRException
, SRSException
35 from django
.contrib
.gis
.gdal
.prototypes
import srs
as capi
37 #### Spatial Reference class. ####
38 class SpatialReference(GDALBase
):
40 A wrapper for the OGRSpatialReference object. According to the GDAL website,
41 the SpatialReference object "provide[s] services to represent coordinate
42 systems (projections and datums) and to transform between them."
45 #### Python 'magic' routines ####
46 def __init__(self
, srs_input
=''):
48 Creates a GDAL OSR Spatial Reference object from the given input.
49 The input may be string of OGC Well Known Text (WKT), an integer
50 EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand
51 string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83').
56 if isinstance(srs_input
, basestring
):
57 # Encoding to ASCII if unicode passed in.
58 if isinstance(srs_input
, unicode):
59 srs_input
= srs_input
.encode('ascii')
61 # If SRID is a string, e.g., '4326', then make acceptable
64 srs_input
= 'EPSG:%d' % srid
67 elif isinstance(srs_input
, (int, long)):
68 # EPSG integer code was input.
70 elif isinstance(srs_input
, self
.ptr_type
):
74 raise TypeError('Invalid SRS type "%s"' % srs_type
)
77 # Input is already an SRS pointer.
80 # Creating a new SRS pointer, using the string buffer.
81 srs
= capi
.new_srs(buf
)
83 # If the pointer is NULL, throw an exception.
85 raise SRSException('Could not create spatial reference from: %s' % srs_input
)
89 # Importing from either the user input string or an integer SRID.
90 if srs_type
== 'user':
91 self
.import_user_input(srs_input
)
92 elif srs_type
== 'epsg':
93 self
.import_epsg(srs_input
)
96 "Destroys this spatial reference."
97 if self
._ptr
: capi
.release_srs(self
._ptr
)
99 def __getitem__(self
, target
):
101 Returns the value of the given string attribute node, None if the node
102 doesn't exist. Can also take a tuple as a parameter, (target, child),
103 where child is the index of the attribute in the WKT. For example:
105 >>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]')
106 >>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
107 >>> print srs['GEOGCS']
109 >>> print srs['DATUM']
111 >>> print srs['AUTHORITY']
113 >>> print srs['AUTHORITY', 1] # The authority value
115 >>> print srs['TOWGS84', 4] # the fourth value in this wkt
117 >>> print srs['UNIT|AUTHORITY'] # For the units authority, have to use the pipe symbole.
119 >>> print srs['UNIT|AUTHORITY', 1] # The authority value for the untis
122 if isinstance(target
, tuple):
123 return self
.attr_value(*target
)
125 return self
.attr_value(target
)
128 "The string representation uses 'pretty' WKT."
129 return self
.pretty_wkt
131 #### SpatialReference Methods ####
132 def attr_value(self
, target
, index
=0):
134 The attribute value for the given target node (e.g. 'PROJCS'). The index
135 keyword specifies an index of the child node to return.
137 if not isinstance(target
, basestring
) or not isinstance(index
, int):
139 return capi
.get_attr_value(self
.ptr
, target
, index
)
141 def auth_name(self
, target
):
142 "Returns the authority name for the given string target node."
143 return capi
.get_auth_name(self
.ptr
, target
)
145 def auth_code(self
, target
):
146 "Returns the authority code for the given string target node."
147 return capi
.get_auth_code(self
.ptr
, target
)
150 "Returns a clone of this SpatialReference object."
151 return SpatialReference(capi
.clone_srs(self
.ptr
))
154 "Morphs this SpatialReference from ESRI's format to EPSG."
155 capi
.morph_from_esri(self
.ptr
)
157 def identify_epsg(self
):
159 This method inspects the WKT of this SpatialReference, and will
160 add EPSG authority nodes where an EPSG identifier is applicable.
162 capi
.identify_epsg(self
.ptr
)
165 "Morphs this SpatialReference to ESRI's format."
166 capi
.morph_to_esri(self
.ptr
)
169 "Checks to see if the given spatial reference is valid."
170 capi
.srs_validate(self
.ptr
)
172 #### Name & SRID properties ####
175 "Returns the name of this Spatial Reference."
176 if self
.projected
: return self
.attr_value('PROJCS')
177 elif self
.geographic
: return self
.attr_value('GEOGCS')
178 elif self
.local
: return self
.attr_value('LOCAL_CS')
183 "Returns the SRID of top-level authority, or None if undefined."
185 return int(self
.attr_value('AUTHORITY', 1))
186 except (TypeError, ValueError):
189 #### Unit Properties ####
191 def linear_name(self
):
192 "Returns the name of the linear units."
193 units
, name
= capi
.linear_units(self
.ptr
, byref(c_char_p()))
197 def linear_units(self
):
198 "Returns the value of the linear units."
199 units
, name
= capi
.linear_units(self
.ptr
, byref(c_char_p()))
203 def angular_name(self
):
204 "Returns the name of the angular units."
205 units
, name
= capi
.angular_units(self
.ptr
, byref(c_char_p()))
209 def angular_units(self
):
210 "Returns the value of the angular units."
211 units
, name
= capi
.angular_units(self
.ptr
, byref(c_char_p()))
217 Returns a 2-tuple of the units value and the units name,
218 and will automatically determines whether to return the linear
221 if self
.projected
or self
.local
:
222 return capi
.linear_units(self
.ptr
, byref(c_char_p()))
223 elif self
.geographic
:
224 return capi
.angular_units(self
.ptr
, byref(c_char_p()))
228 #### Spheroid/Ellipsoid Properties ####
232 Returns a tuple of the ellipsoid parameters:
233 (semimajor axis, semiminor axis, and inverse flattening)
235 return (self
.semi_major
, self
.semi_minor
, self
.inverse_flattening
)
238 def semi_major(self
):
239 "Returns the Semi Major Axis for this Spatial Reference."
240 return capi
.semi_major(self
.ptr
, byref(c_int()))
243 def semi_minor(self
):
244 "Returns the Semi Minor Axis for this Spatial Reference."
245 return capi
.semi_minor(self
.ptr
, byref(c_int()))
248 def inverse_flattening(self
):
249 "Returns the Inverse Flattening for this Spatial Reference."
250 return capi
.invflattening(self
.ptr
, byref(c_int()))
252 #### Boolean Properties ####
254 def geographic(self
):
256 Returns True if this SpatialReference is geographic
257 (root node is GEOGCS).
259 return bool(capi
.isgeographic(self
.ptr
))
263 "Returns True if this SpatialReference is local (root node is LOCAL_CS)."
264 return bool(capi
.islocal(self
.ptr
))
269 Returns True if this SpatialReference is a projected coordinate system
270 (root node is PROJCS).
272 return bool(capi
.isprojected(self
.ptr
))
274 #### Import Routines #####
275 def import_epsg(self
, epsg
):
276 "Imports the Spatial Reference from the EPSG code (an integer)."
277 capi
.from_epsg(self
.ptr
, epsg
)
279 def import_proj(self
, proj
):
280 "Imports the Spatial Reference from a PROJ.4 string."
281 capi
.from_proj(self
.ptr
, proj
)
283 def import_user_input(self
, user_input
):
284 "Imports the Spatial Reference from the given user input string."
285 capi
.from_user_input(self
.ptr
, user_input
)
287 def import_wkt(self
, wkt
):
288 "Imports the Spatial Reference from OGC WKT (string)"
289 capi
.from_wkt(self
.ptr
, byref(c_char_p(wkt
)))
291 def import_xml(self
, xml
):
292 "Imports the Spatial Reference from an XML string."
293 capi
.from_xml(self
.ptr
, xml
)
295 #### Export Properties ####
298 "Returns the WKT representation of this Spatial Reference."
299 return capi
.to_wkt(self
.ptr
, byref(c_char_p()))
302 def pretty_wkt(self
, simplify
=0):
303 "Returns the 'pretty' representation of the WKT."
304 return capi
.to_pretty_wkt(self
.ptr
, byref(c_char_p()), simplify
)
308 "Returns the PROJ.4 representation for this Spatial Reference."
309 return capi
.to_proj(self
.ptr
, byref(c_char_p()))
317 def xml(self
, dialect
=''):
318 "Returns the XML representation of this Spatial Reference."
319 return capi
.to_xml(self
.ptr
, byref(c_char_p()), dialect
)
321 class CoordTransform(GDALBase
):
322 "The coordinate system transformation object."
324 def __init__(self
, source
, target
):
325 "Initializes on a source and target SpatialReference objects."
326 if not isinstance(source
, SpatialReference
) or not isinstance(target
, SpatialReference
):
327 raise TypeError('source and target must be of type SpatialReference')
328 self
.ptr
= capi
.new_ct(source
._ptr
, target
._ptr
)
329 self
._srs
1_name
= source
.name
330 self
._srs
2_name
= target
.name
333 "Deletes this Coordinate Transformation object."
334 if self
._ptr
: capi
.destroy_ct(self
._ptr
)
337 return 'Transform from "%s" to "%s"' % (self
._srs
1_name
, self
._srs
2_name
)