/[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

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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26