/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/proj.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/Model/proj.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 6761 byte(s)
made a copy
1 # Copyright (c) 2001, 2003, 2006 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 # Bernhard Reiter <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with Thuban for details.
8 __version__ = "$Revision$"
9
10 from types import StringTypes
11 import locale
12
13 from Thuban import _
14 from Thuban.Lib.connector import Publisher
15
16 import Projection
17 BaseProjection = Projection.Projection
18 del Projection
19
20 from messages import PROJECTION_ADDED, PROJECTION_REPLACED, PROJECTION_REMOVED
21
22 PROJ_UNITS_METERS = 1
23 PROJ_UNITS_DEGREES = 2
24
25 def _do_we_have_to_work_around_broken_proj():
26 """ If we have a problematic locale, check if proj results are good. """
27 if locale.localeconv()['decimal_point'] != '.':
28 params = ["proj=latlong", "to_meter=0.01745", "ellps=clrk66"]
29 proj = BaseProjection(params)
30 result1 = proj.Forward(1,1)
31
32 savedlocale = locale.getlocale(locale.LC_NUMERIC)
33 locale.setlocale(locale.LC_NUMERIC, "C")
34
35 proj = BaseProjection(params)
36 result2 = proj.Forward(1,1)
37
38 try:
39 locale.setlocale(locale.LC_NUMERIC, savedlocale)
40 except:
41 # python under some circumstances (observed 2.3.5-2 Debian Sarge)
42 # does not accept savedlocale directly
43 # deviating from the documentation
44 locale.setlocale(locale.LC_NUMERIC, savedlocale[0])
45 if result1 != result2:
46 return True
47 return False
48
49 class Projection(BaseProjection):
50 """A proj4 projection object that remembers the parameters.
51
52 The proj library is not robust against decimal_point != '.' locales.
53 Since python 2.4 calls C extensions with the set locale, it can create
54 a problem. It seems that calling
55 self.assuregoodlocale()
56 self.assureinitlocale()
57 before BaseProjection.__init__() is enough to work around this.
58
59 We assuming that the locale stays the same after a projection
60 has been initialised
61 and thus we can return to it in self.assureinitlocale().
62 """
63
64 def __init__(self, params, name = None, epsg = None):
65 """Initialize the Projection
66
67 Parameters:
68
69 params -- a list of 'parameter=value' strings
70
71 name -- (optional) The name of the projection. If None or omitted
72 it defaults to 'Unknown' in the local language.
73
74 epsg -- (optional) The EPSG code as a string.
75 """
76 self.initlocale = locale.getlocale(locale.LC_NUMERIC)
77 self.work_around_broken_proj = _do_we_have_to_work_around_broken_proj()
78
79 self.assuregoodlocale()
80 BaseProjection.__init__(self, params)
81 self.assureinitlocale()
82
83 if name is None:
84 self.name = _("Unknown")
85 elif isinstance(name, StringTypes):
86 self.name = name
87
88 self.epsg = epsg
89 self.params = params
90
91 def assuregoodlocale(self):
92 if self.work_around_broken_proj:
93 locale.setlocale(locale.LC_NUMERIC, "C")
94
95 def assureinitlocale(self):
96 if self.work_around_broken_proj:
97 locale.setlocale(locale.LC_NUMERIC, self.initlocale)
98
99 def _transform_bbox(self, trafo, bbox):
100 # This is not really the correct way to determine the bbox of a
101 # projected bbox, but for now it works well enough
102 llx, lly, urx, ury = bbox
103 xs = []; ys = []
104 for x, y in ((llx, lly), (llx, ury), (urx, lly), (urx, ury)):
105 x, y = trafo(x, y)
106 xs.append(x); ys.append(y)
107 return min(xs), min(ys), max(xs), max(ys)
108
109 def ForwardBBox(self, bbox):
110 """Return the bounding box of the corners of the bounding box bbox
111 """
112 return self._transform_bbox(self.Forward, bbox)
113
114 def InverseBBox(self, bbox):
115 return self._transform_bbox(self.Inverse, bbox)
116
117 def GetName(self):
118 """Return the name of the projection."""
119 return self.name
120
121 def Label(self):
122 if self.epsg:
123 return "EPSG % 5s %s" % (self.epsg, self.name)
124 return self.name
125
126 def EPSGCode(self):
127 """Return the EPSG code as a string or None if there is none"""
128 return self.epsg
129
130 def GetParameter(self, param):
131 """Return the projection value for the given parameter.
132
133 If 'param' exists as a valid parameter return the associated
134 value as a string. If the parameter does not have a value (like
135 e.g. the 'south' parameter for utm) then the value is the
136 parameter name itself.
137
138 If the parameter doesn't exist return an empty string.
139 """
140
141 for pair in self.params:
142 if "=" in pair:
143 p, v = pair.split("=")
144 else:
145 p = v = pair
146 if p == param:
147 return v
148
149 return ""
150
151 def GetAllParameters(self):
152 """Return list of 'parameter=value' strings"""
153 return self.params
154
155 def GetProjectedUnits(self):
156 if self.GetParameter("proj") in [ 'latlong', 'longlat' ]:
157 return PROJ_UNITS_DEGREES
158 else:
159 return PROJ_UNITS_METERS
160
161 def __repr__(self):
162 return self.name + ": " + repr(self.params)
163
164
165 class ProjFile(Publisher):
166
167 def __init__(self, filename):
168 """Intialize the ProjFile.
169
170 filename -- name of the file that this ProjFile represents.
171 """
172
173 self.__projs = []
174
175 self.SetFilename(filename)
176
177 def Add(self, proj):
178 """Add the projection to the end of the file."""
179 self.__projs.append(proj)
180 self.issue(PROJECTION_ADDED, proj)
181
182 def Remove(self, proj):
183 """Remove the object proj from the projection file.
184
185 Raises a ValueError is proj is not found.
186 """
187 self.__projs.remove(proj)
188 self.issue(PROJECTION_REMOVED, proj)
189
190 def Replace(self, oldproj, newproj):
191 """Replace the object 'oldproj' with 'newproj'.
192
193 Raises ValueError if oldproj is not in the file.
194 """
195 self.__projs[self.__projs.index(oldproj)] = newproj
196 self.issue(PROJECTION_REPLACED, oldproj, newproj)
197
198 def GetFilename(self):
199 """Return the filename where the ProjFile was read or will be
200 written to.
201 """
202
203 return self.__filename
204
205 def SetFilename(self, filename):
206 """Set the filename where the ProjFile will be written to."""
207 self.__filename = filename
208
209 def GetProjections(self):
210 """Return a list of the projections in the order they were read
211 from the file or will be written.
212
213 This is not a deep copy list, so any modifications made to the
214 Projection objects will be written to the file.
215 """
216
217 return self.__projs
218

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26