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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2698 - (hide 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 bernhard 2698 # Copyright (c) 2001, 2003, 2006 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4 bernhard 2698 # Bernhard Reiter <[email protected]>
5 bh 6 #
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 bh 1824 from types import StringTypes
11 bernhard 2698 import locale
12 bh 1824
13 jonathan 745 from Thuban import _
14 bh 1824 from Thuban.Lib.connector import Publisher
15 jonathan 745
16 bh 6 import Projection
17     BaseProjection = Projection.Projection
18     del Projection
19    
20 bh 1824 from messages import PROJECTION_ADDED, PROJECTION_REPLACED, PROJECTION_REMOVED
21    
22 jonathan 1250 PROJ_UNITS_METERS = 1
23     PROJ_UNITS_DEGREES = 2
24    
25 bernhard 2698 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 bh 6 class Projection(BaseProjection):
44 bernhard 2698 """A proj4 projection object that remembers the parameters.
45 bh 6
46 bernhard 2698 Note: it seems that calling
47     self.assuregoodlocale()
48     self.assureinitlocale()
49     before BaseProjection.__init__() is enough to work around the bug.
50 bh 6
51 bernhard 2698 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 bh 1815 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 bernhard 2698 name -- (optional) The name of the projection. If None or omitted
64 bh 1815 it defaults to 'Unknown' in the local language.
65    
66     epsg -- (optional) The EPSG code as a string.
67 jonathan 745 """
68 bernhard 2698 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 bh 6 BaseProjection.__init__(self, params)
73 bernhard 2698 self.assureinitlocale()
74 jonathan 745
75 jonathan 758 if name is None:
76     self.name = _("Unknown")
77     elif isinstance(name, StringTypes):
78     self.name = name
79 jonathan 745
80 bh 1815 self.epsg = epsg
81 jonathan 758 self.params = params
82    
83 bernhard 2698 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 bh 1982 def _transform_bbox(self, trafo, bbox):
92 bh 6 # This is not really the correct way to determine the bbox of a
93 bh 1982 # projected bbox, but for now it works well enough
94 bh 6 llx, lly, urx, ury = bbox
95     xs = []; ys = []
96 bh 1982 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 bh 6 return min(xs), min(ys), max(xs), max(ys)
100 jonathan 695
101 bh 1982 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 jonathan 695 def GetName(self):
110 jonathan 738 """Return the name of the projection."""
111 jonathan 695 return self.name
112    
113 bh 1815 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 jonathan 708 def GetParameter(self, param):
123 jonathan 738 """Return the projection value for the given parameter.
124 jonathan 708
125 bh 1797 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 jonathan 738 """
132    
133 jonathan 708 for pair in self.params:
134 bh 1797 if "=" in pair:
135     p, v = pair.split("=")
136     else:
137     p = v = pair
138 jonathan 708 if p == param:
139     return v
140    
141     return ""
142    
143     def GetAllParameters(self):
144 jonathan 738 """Return list of 'parameter=value' strings"""
145 jonathan 695 return self.params
146    
147 jonathan 1250 def GetProjectedUnits(self):
148 jan 1860 if self.GetParameter("proj") in [ 'latlong', 'longlat' ]:
149 jonathan 1250 return PROJ_UNITS_DEGREES
150     else:
151     return PROJ_UNITS_METERS
152    
153 jonathan 695 def __repr__(self):
154 jonathan 726 return self.name + ": " + repr(self.params)
155 jonathan 695
156 bh 1815
157 bh 1824 class ProjFile(Publisher):
158 jonathan 695
159     def __init__(self, filename):
160 jonathan 738 """Intialize the ProjFile.
161 jonathan 695
162 jonathan 738 filename -- name of the file that this ProjFile represents.
163     """
164    
165     self.__projs = []
166    
167     self.SetFilename(filename)
168 bh 1824
169 jonathan 695 def Add(self, proj):
170 bh 1802 """Add the projection to the end of the file."""
171     self.__projs.append(proj)
172 bh 1824 self.issue(PROJECTION_ADDED, proj)
173 jonathan 695
174 jonathan 726 def Remove(self, proj):
175 jonathan 758 """Remove the object proj from the projection file.
176 jonathan 726
177 jonathan 738 Raises a ValueError is proj is not found.
178     """
179     self.__projs.remove(proj)
180 bh 1824 self.issue(PROJECTION_REMOVED, proj)
181 jonathan 695
182 jonathan 758 def Replace(self, oldproj, newproj):
183     """Replace the object 'oldproj' with 'newproj'.
184 bh 1824
185 jonathan 758 Raises ValueError if oldproj is not in the file.
186     """
187     self.__projs[self.__projs.index(oldproj)] = newproj
188 bh 1824 self.issue(PROJECTION_REPLACED, oldproj, newproj)
189 jonathan 758
190 jonathan 738 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 jonathan 695 def GetProjections(self):
202 jonathan 738 """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