/[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 1815 by bh, Mon Oct 13 15:53:39 2003 UTC revision 2698 by bernhard, Mon Sep 18 00:56:26 2006 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2003 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    
 from Thuban import _  
   
10  from types import StringTypes  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  PROJ_UNITS_METERS  = 1
23  PROJ_UNITS_DEGREES = 2  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      """A proj4 projection object that remembers the parameters"""      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):      def __init__(self, params, name = None, epsg = None):
57          """Initialize the Projection          """Initialize the Projection
# Line 29  class Projection(BaseProjection): Line 60  class Projection(BaseProjection):
60    
61          params -- a list of 'parameter=value' strings          params -- a list of 'parameter=value' strings
62    
63          name -- (optional) The name of the projectin. If None or omitted          name -- (optional) The name of the projection. If None or omitted
64                  it defaults to 'Unknown' in the local language.                  it defaults to 'Unknown' in the local language.
65    
66          epsg -- (optional) The EPSG code as a string.          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)          BaseProjection.__init__(self, params)
73            self.assureinitlocale()
74    
75          if name is None:          if name is None:
76              self.name = _("Unknown")              self.name = _("Unknown")
# Line 44  class Projection(BaseProjection): Line 80  class Projection(BaseProjection):
80          self.epsg = epsg          self.epsg = epsg
81          self.params = params          self.params = params
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."""          """Return the name of the projection."""
111          return self.name          return self.name
# Line 101  class Projection(BaseProjection): Line 145  class Projection(BaseProjection):
145          return self.params          return self.params
146    
147      def GetProjectedUnits(self):      def GetProjectedUnits(self):
148          if self.GetParameter("proj") == "latlong":          if self.GetParameter("proj") in [ 'latlong', 'longlat' ]:
149              return PROJ_UNITS_DEGREES              return PROJ_UNITS_DEGREES
150          else:          else:
151              return PROJ_UNITS_METERS              return PROJ_UNITS_METERS
# Line 110  class Projection(BaseProjection): Line 154  class Projection(BaseProjection):
154          return self.name + ": " + 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          """Intialize the ProjFile.          """Intialize the ProjFile.
# Line 121  class ProjFile: Line 165  class ProjFile:
165          self.__projs = []          self.__projs = []
166    
167          self.SetFilename(filename)          self.SetFilename(filename)
168        
169      def Add(self, proj):      def Add(self, proj):
170          """Add the projection to the end of the file."""          """Add the projection to the end of the file."""
171          self.__projs.append(proj)          self.__projs.append(proj)
172            self.issue(PROJECTION_ADDED, proj)
173    
174      def Remove(self, proj):      def Remove(self, proj):
175          """Remove the object proj from the projection file.          """Remove the object proj from the projection file.
176    
177          Raises a ValueError is proj is not found.          Raises a ValueError is proj is not found.
178          """          """
   
179          self.__projs.remove(proj)          self.__projs.remove(proj)
180            self.issue(PROJECTION_REMOVED, proj)
181    
182      def Replace(self, oldproj, newproj):      def Replace(self, oldproj, newproj):
183          """Replace the object 'oldproj' with 'newproj'.          """Replace the object 'oldproj' with 'newproj'.
184            
185          Raises ValueError if oldproj is not in the file.          Raises ValueError if oldproj is not in the file.
186          """          """
   
         #  
         # see if the projection already exists.  
         # this only works if Projection doesn't override __eq__  
         #  
187          self.__projs[self.__projs.index(oldproj)] = newproj          self.__projs[self.__projs.index(oldproj)] = newproj
188            self.issue(PROJECTION_REPLACED, oldproj, newproj)
189    
190      def GetFilename(self):      def GetFilename(self):
191          """Return the filename where the ProjFile was read or will be          """Return the filename where the ProjFile was read or will be

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26