/[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 2698 - (show annotations)
Mon Sep 18 00:56:26 2006 UTC (18 years, 5 months ago) by bernhard
Original Path: trunk/thuban/Thuban/Model/proj.py
File MIME type: text/x-python
File size: 6336 byte(s)
Fixed behaviour with the proj bug and python >=2.4 
when decimal_point != '.'. So de_DE locales will work fine again.

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 locale.setlocale(locale.LC_NUMERIC, savedlocale)
39 if result1 != result2:
40 return True
41 return False
42
43 class Projection(BaseProjection):
44 """A proj4 projection object that remembers the parameters.
45
46 Note: it seems that calling
47 self.assuregoodlocale()
48 self.assureinitlocale()
49 before BaseProjection.__init__() is enough to work around the bug.
50
51 We assuming that the locale stays the same after a projection
52 has been initialised
53 and thus we can return to it in self.assureinitlocale().
54 """
55
56 def __init__(self, params, name = None, epsg = None):
57 """Initialize the Projection
58
59 Parameters:
60
61 params -- a list of 'parameter=value' strings
62
63 name -- (optional) The name of the projection. If None or omitted
64 it defaults to 'Unknown' in the local language.
65
66 epsg -- (optional) The EPSG code as a string.
67 """
68 self.initlocale = locale.getlocale(locale.LC_NUMERIC)
69 self.work_around_broken_proj = _do_we_have_to_work_around_broken_proj()
70
71 self.assuregoodlocale()
72 BaseProjection.__init__(self, params)
73 self.assureinitlocale()
74
75 if name is None:
76 self.name = _("Unknown")
77 elif isinstance(name, StringTypes):
78 self.name = name
79
80 self.epsg = epsg
81 self.params = params
82
83 def assuregoodlocale(self):
84 if self.work_around_broken_proj:
85 locale.setlocale(locale.LC_NUMERIC, "C")
86
87 def assureinitlocale(self):
88 if self.work_around_broken_proj:
89 locale.setlocale(locale.LC_NUMERIC, self.initlocale)
90
91 def _transform_bbox(self, trafo, bbox):
92 # This is not really the correct way to determine the bbox of a
93 # projected bbox, but for now it works well enough
94 llx, lly, urx, ury = bbox
95 xs = []; ys = []
96 for x, y in ((llx, lly), (llx, ury), (urx, lly), (urx, ury)):
97 x, y = trafo(x, y)
98 xs.append(x); ys.append(y)
99 return min(xs), min(ys), max(xs), max(ys)
100
101 def ForwardBBox(self, bbox):
102 """Return the bounding box of the corners of the bounding box bbox
103 """
104 return self._transform_bbox(self.Forward, bbox)
105
106 def InverseBBox(self, bbox):
107 return self._transform_bbox(self.Inverse, bbox)
108
109 def GetName(self):
110 """Return the name of the projection."""
111 return self.name
112
113 def Label(self):
114 if self.epsg:
115 return "EPSG % 5s %s" % (self.epsg, self.name)
116 return self.name
117
118 def EPSGCode(self):
119 """Return the EPSG code as a string or None if there is none"""
120 return self.epsg
121
122 def GetParameter(self, param):
123 """Return the projection value for the given parameter.
124
125 If 'param' exists as a valid parameter return the associated
126 value as a string. If the parameter does not have a value (like
127 e.g. the 'south' parameter for utm) then the value is the
128 parameter name itself.
129
130 If the parameter doesn't exist return an empty string.
131 """
132
133 for pair in self.params:
134 if "=" in pair:
135 p, v = pair.split("=")
136 else:
137 p = v = pair
138 if p == param:
139 return v
140
141 return ""
142
143 def GetAllParameters(self):
144 """Return list of 'parameter=value' strings"""
145 return self.params
146
147 def GetProjectedUnits(self):
148 if self.GetParameter("proj") in [ 'latlong', 'longlat' ]:
149 return PROJ_UNITS_DEGREES
150 else:
151 return PROJ_UNITS_METERS
152
153 def __repr__(self):
154 return self.name + ": " + repr(self.params)
155
156
157 class ProjFile(Publisher):
158
159 def __init__(self, filename):
160 """Intialize the ProjFile.
161
162 filename -- name of the file that this ProjFile represents.
163 """
164
165 self.__projs = []
166
167 self.SetFilename(filename)
168
169 def Add(self, proj):
170 """Add the projection to the end of the file."""
171 self.__projs.append(proj)
172 self.issue(PROJECTION_ADDED, proj)
173
174 def Remove(self, proj):
175 """Remove the object proj from the projection file.
176
177 Raises a ValueError is proj is not found.
178 """
179 self.__projs.remove(proj)
180 self.issue(PROJECTION_REMOVED, proj)
181
182 def Replace(self, oldproj, newproj):
183 """Replace the object 'oldproj' with 'newproj'.
184
185 Raises ValueError if oldproj is not in the file.
186 """
187 self.__projs[self.__projs.index(oldproj)] = newproj
188 self.issue(PROJECTION_REPLACED, oldproj, newproj)
189
190 def GetFilename(self):
191 """Return the filename where the ProjFile was read or will be
192 written to.
193 """
194
195 return self.__filename
196
197 def SetFilename(self, filename):
198 """Set the filename where the ProjFile will be written to."""
199 self.__filename = filename
200
201 def GetProjections(self):
202 """Return a list of the projections in the order they were read
203 from the file or will be written.
204
205 This is not a deep copy list, so any modifications made to the
206 Projection objects will be written to the file.
207 """
208
209 return self.__projs
210

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26