/[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 1802 by bh, Thu Oct 9 15:18:35 2003 UTC revision 2699 by bernhard, Mon Sep 18 13:59:40 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        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      """A proj4 projection object that remembers the parameters"""      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):      def __init__(self, params, name = None, epsg = None):
59          """Initialize the Projection with a list of          """Initialize the Projection
60          'parameter=value' strings and an optional name. If 'name' is  
61          None, the name will be set to 'Unknown' in the local language.          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)          BaseProjection.__init__(self, params)
75            self.assureinitlocale()
76    
77          if name is None:          if name is None:
78              self.name = _("Unknown")              self.name = _("Unknown")
79          elif isinstance(name, StringTypes):          elif isinstance(name, StringTypes):
80              self.name = name              self.name = name
81    
82            self.epsg = epsg
83          self.params = params          self.params = params
84    
85      def ForwardBBox(self, bbox):      def assuregoodlocale(self):
86          """Return the bounding box of the corners of the bounding box bbox          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          # This is not really the correct way to determine the bbox of a
95          # projected shape, but for now it works well enough          # projected bbox, but for now it works well enough
96          llx, lly, urx, ury = bbox          llx, lly, urx, ury = bbox
97          xs = []; ys = []          xs = []; ys = []
98          x, y = self.Forward(llx, lly)          for x, y in ((llx, lly), (llx, ury), (urx, lly), (urx, ury)):
99          xs.append(x); ys.append(y)              x, y = trafo(x, y)
100          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)  
           
101          return min(xs), min(ys), max(xs), max(ys)          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):      def GetName(self):
112          """Return the name of the projection."""          """Return the name of the projection."""
113          return self.name          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):      def GetParameter(self, param):
125          """Return the projection value for the given parameter.          """Return the projection value for the given parameter.
126    
# Line 85  class Projection(BaseProjection): Line 147  class Projection(BaseProjection):
147          return self.params          return self.params
148    
149      def GetProjectedUnits(self):      def GetProjectedUnits(self):
150          if self.GetParameter("proj") == "latlong":          if self.GetParameter("proj") in [ 'latlong', 'longlat' ]:
151              return PROJ_UNITS_DEGREES              return PROJ_UNITS_DEGREES
152          else:          else:
153              return PROJ_UNITS_METERS              return PROJ_UNITS_METERS
# Line 93  class Projection(BaseProjection): Line 155  class Projection(BaseProjection):
155      def __repr__(self):      def __repr__(self):
156          return self.name + ": " + repr(self.params)          return self.name + ": " + repr(self.params)
157    
158  class ProjFile:  
159    class ProjFile(Publisher):
160    
161      def __init__(self, filename):      def __init__(self, filename):
162          """Intialize the ProjFile.          """Intialize the ProjFile.
# Line 104  class ProjFile: Line 167  class ProjFile:
167          self.__projs = []          self.__projs = []
168    
169          self.SetFilename(filename)          self.SetFilename(filename)
170        
171      def Add(self, proj):      def Add(self, proj):
172          """Add the projection to the end of the file."""          """Add the projection to the end of the file."""
173          self.__projs.append(proj)          self.__projs.append(proj)
174            self.issue(PROJECTION_ADDED, proj)
175    
176      def Remove(self, proj):      def Remove(self, proj):
177          """Remove the object proj from the projection file.          """Remove the object proj from the projection file.
178    
179          Raises a ValueError is proj is not found.          Raises a ValueError is proj is not found.
180          """          """
   
181          self.__projs.remove(proj)          self.__projs.remove(proj)
182            self.issue(PROJECTION_REMOVED, proj)
183    
184      def Replace(self, oldproj, newproj):      def Replace(self, oldproj, newproj):
185          """Replace the object 'oldproj' with 'newproj'.          """Replace the object 'oldproj' with 'newproj'.
186            
187          Raises ValueError if oldproj is not in the file.          Raises ValueError if oldproj is not in the file.
188          """          """
   
         #  
         # see if the projection already exists.  
         # this only works if Projection doesn't override __eq__  
         #  
189          self.__projs[self.__projs.index(oldproj)] = newproj          self.__projs[self.__projs.index(oldproj)] = newproj
190            self.issue(PROJECTION_REPLACED, oldproj, newproj)
191    
192      def GetFilename(self):      def GetFilename(self):
193          """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.1802  
changed lines
  Added in v.2699

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26