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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 695 by jonathan, Wed Apr 16 16:39:36 2003 UTC revision 2698 by bernhard, Mon Sep 18 00:56:26 2006 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2003, 2006 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4    # Bernhard Reiter <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
   
8  __version__ = "$Revision$"  __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  import Projection
17  BaseProjection = Projection.Projection  BaseProjection = Projection.Projection
18  del Projection  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):  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      """A proj4 projection object that remembers the parameters"""      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      def __init__(self, params, name = "Unknown"):          self.assuregoodlocale()
72          BaseProjection.__init__(self, params)          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          self.params = params
         self.name = name  
82    
83      def ForwardBBox(self, bbox):      def assuregoodlocale(self):
84          """Return the bounding box of the corners of the bounding box bbox          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          # This is not really the correct way to determine the bbox of a
93          # projected shape, but for now it works well enough          # projected bbox, but for now it works well enough
94          llx, lly, urx, ury = bbox          llx, lly, urx, ury = bbox
95          xs = []; ys = []          xs = []; ys = []
96          x, y = self.Forward(llx, lly)          for x, y in ((llx, lly), (llx, ury), (urx, lly), (urx, ury)):
97          xs.append(x); ys.append(y)              x, y = trafo(x, y)
98          x, y = self.Forward(llx, ury)              xs.append(x); ys.append(y)
         xs.append(x); ys.append(y)  
         x, y = self.Forward(urx, ury)  
         xs.append(x); ys.append(y)  
         x, y = self.Forward(urx, lly)  
         xs.append(x); ys.append(y)  
99          return min(xs), min(ys), max(xs), max(ys)          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):      def GetName(self):
110            """Return the name of the projection."""
111          return self.name          return self.name
112    
113      def GetParameters(self):      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          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):      def __repr__(self):
154          return repr(self.params)          return self.name + ": " + repr(self.params)
155    
156    
157  class ProjFile:  class ProjFile(Publisher):
158    
159      def __init__(self, filename):      def __init__(self, filename):
160          self.projs = []          """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    
         self.SetFileName(filename)  
       
169      def Add(self, proj):      def Add(self, proj):
170          self.projs.append(proj)          """Add the projection to the end of the file."""
171            self.__projs.append(proj)
172            self.issue(PROJECTION_ADDED, proj)
173    
174      def GetFileName(self):      def Remove(self, proj):
175          return self.filename          """Remove the object proj from the projection file.
176    
177      def SetFileName(self, filename):          Raises a ValueError is proj is not found.
178          self.filename = filename          """
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):      def GetProjections(self):
202          return self.projs          """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    

Legend:
Removed from v.695  
changed lines
  Added in v.2698

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26