/[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 2699 - (show annotations)
Mon Sep 18 13:59:40 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: 6487 byte(s)
Improved documentation.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26