/[thuban]/trunk/thuban/Thuban/Model/layer.py
ViewVC logotype

Diff of /trunk/thuban/Thuban/Model/layer.py

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

revision 217 by bh, Wed Jul 17 10:50:40 2002 UTC revision 701 by bh, Thu Apr 17 16:18:48 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2002 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4    # Jonathan Coles <[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    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11    import os
12  from math import log, ceil  from math import log, ceil
13    
14    from Thuban import _
15    
16  import shapelib, shptree  import shapelib, shptree
17    
18  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_VISIBILITY_CHANGED, \
19       LAYER_VISIBILITY_CHANGED       LAYER_CHANGED
20    
21  from color import Color  from color import Color
 # Some predefined colors for internal use  
 _black = Color(0, 0, 0)  
22    
23    import classification
24    
25  from table import Table  from table import Table
26    
# Line 83  class BaseLayer(TitledObject, Modifiable Line 86  class BaseLayer(TitledObject, Modifiable
86          """Set the layer's visibility."""          """Set the layer's visibility."""
87          self.visible = visible          self.visible = visible
88          self.issue(LAYER_VISIBILITY_CHANGED, self)          self.issue(LAYER_VISIBILITY_CHANGED, self)
89            
90            
91  class Layer(BaseLayer):  class Layer(BaseLayer):
92    
93      """Represent the information of one geodata file (currently a shapefile)      """Represent the information of one geodata file (currently a shapefile)
# Line 99  class Layer(BaseLayer): Line 102  class Layer(BaseLayer):
102    
103          TITLE_CHANGED -- The title has changed.          TITLE_CHANGED -- The title has changed.
104          LAYER_PROJECTION_CHANGED -- the projection has changed.          LAYER_PROJECTION_CHANGED -- the projection has changed.
         LAYER_LEGEND_CHANGED -- the fill or stroke attributes have changed  
   
105      """      """
106    
107      def __init__(self, title, filename, projection = None,      def __init__(self, title, filename, projection = None,
108                   fill = None, stroke = _black, stroke_width = 1, visible = 1):                   fill = Color.Transparent,
109                     stroke = Color.Black,
110                     lineWidth = 1,
111                     visible = 1):
112          """Initialize the layer.          """Initialize the layer.
113    
114          title -- the title          title -- the title
# Line 112  class Layer(BaseLayer): Line 116  class Layer(BaseLayer):
116          projection -- the projection object. Its Inverse method is          projection -- the projection object. Its Inverse method is
117                 assumed to map the layer's coordinates to lat/long                 assumed to map the layer's coordinates to lat/long
118                 coordinates                 coordinates
119          fill -- the fill color or None if the shapes are not filled          fill -- the fill color or Color.Transparent if the shapes are
120          stroke -- the stroke color or None if the shapes are not stroked                  not filled
121            stroke -- the stroke color or Color.Transparent if the shapes
122                    are not stroked
123          visible -- boolean. If true the layer is visible.          visible -- boolean. If true the layer is visible.
124    
125          colors are expected to be instances of Color class          colors are expected to be instances of Color class
126          """          """
127          BaseLayer.__init__(self, title, visible = visible)          BaseLayer.__init__(self, title, visible = visible)
128          self.filename = filename  
129            # Make the filename absolute. The filename will be
130            # interpreted relative to that anyway, but when saving a
131            # session we need to compare absolute paths and it's usually
132            # safer to always work with absolute paths.
133            self.filename = os.path.abspath(filename)
134    
135          self.projection = projection          self.projection = projection
         self.fill = fill  
         self.stroke = stroke  
         self.stroke_width = stroke_width  
136          self.shapefile = None          self.shapefile = None
137          self.shapetree = None          self.shapetree = None
138          self.open_shapefile()          self.open_shapefile()
# Line 133  class Layer(BaseLayer): Line 142  class Layer(BaseLayer):
142          self.shapetable = Table(filename)          self.shapetable = Table(filename)
143          self.table = self.shapetable          self.table = self.shapetable
144    
145            #
146            # this is really important so that when the classification class
147            # tries to set its parent layer the variable will exist
148            #
149            self.__classification = None
150            self.__setClassLock = False
151    
152    
153            self.SetClassification(None)
154    
155            self.__classification.SetDefaultLineColor(stroke)
156            self.__classification.SetDefaultLineWidth(lineWidth)
157            self.__classification.SetDefaultFill(fill)
158            self.__classification.SetLayer(self)
159    
160            self.UnsetModified()
161    
162      def open_shapefile(self):      def open_shapefile(self):
163          if self.shapefile is None:          if self.shapefile is None:
164              self.shapefile = shapelib.ShapeFile(self.filename)              self.shapefile = shapelib.ShapeFile(self.filename)
# Line 159  class Layer(BaseLayer): Line 185  class Layer(BaseLayer):
185              self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,              self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
186                                               maxdepth)                                               maxdepth)
187    
188        def Destroy(self):
189            BaseLayer.Destroy(self)
190            if self.shapefile is not None:
191                self.shapefile.close()
192                self.shapefile = None
193                self.shapetree = None
194            self.SetClassification(None)
195            self.table.Destroy()
196    
197      def BoundingBox(self):      def BoundingBox(self):
198          """Return the layer's bounding box in the intrinsic coordinate system.          """Return the layer's bounding box in the intrinsic coordinate system.
199    
200          If the layer has no shapes, return None.          If the layer has no shapes, return None.
201          """          """
         # The bbox will be set by open_shapefile just as we need it  
         # here.  
         self.open_shapefile()  
202          return self.bbox          return self.bbox
203    
204      def LatLongBoundingBox(self):      def LatLongBoundingBox(self):
# Line 184  class Layer(BaseLayer): Line 216  class Layer(BaseLayer):
216          else:          else:
217              return None              return None
218    
219        def GetFieldType(self, fieldName):
220            info = self.table.field_info_by_name(fieldName)
221            if info is not None:
222                return info[0]
223            else:
224                return None
225    
226      def NumShapes(self):      def NumShapes(self):
227          """Return the number of shapes in the layer"""          """Return the number of shapes in the layer"""
         self.open_shapefile()  
228          return self.numshapes          return self.numshapes
229    
230      def ShapeType(self):      def ShapeType(self):
231          """Return the type of the shapes in the layer.          """Return the type of the shapes in the layer.
232          This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.          This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.
233          """          """
         self.open_shapefile()  
234          return self.shapetype          return self.shapetype
235    
236      def Shape(self, index):      def Shape(self, index):
237          """Return the shape with index index"""          """Return the shape with index index"""
         self.open_shapefile()  
238          shape = self.shapefile.read_object(index)          shape = self.shapefile.read_object(index)
239    
240          if self.shapetype == SHAPETYPE_POINT:          if self.shapetype == SHAPETYPE_POINT:
241              points = shape.vertices()              points = shape.vertices()
242          else:          else:
# Line 208  class Layer(BaseLayer): Line 245  class Layer(BaseLayer):
245              points = []              points = []
246              for x, y in poly:              for x, y in poly:
247                  points.append((x, y))                  points.append((x, y))
248    
249          return Shape(points)          return Shape(points)
250    
251      def ShapesInRegion(self, box):      def ShapesInRegion(self, box):
# Line 224  class Layer(BaseLayer): Line 262  class Layer(BaseLayer):
262          self.projection = projection          self.projection = projection
263          self.changed(LAYER_PROJECTION_CHANGED, self)          self.changed(LAYER_PROJECTION_CHANGED, self)
264    
265      def SetFill(self, fill):      def GetClassification(self):
266          """Set the layer's fill color. None means the shapes are not filled"""          return self.__classification
267          self.fill = fill  
268          self.changed(LAYER_LEGEND_CHANGED, self)      def SetClassification(self, clazz):
269            """Set the classification to 'clazz'
     def SetStroke(self, stroke):  
         """Set the layer's stroke color. None means the shapes are not  
         stroked."""  
         self.stroke = stroke  
         self.changed(LAYER_LEGEND_CHANGED, self)  
   
     def SetStrokeWidth(self, width):  
         """Set the layer's stroke width."""  
         self.stroke_width = width  
         self.changed(LAYER_LEGEND_CHANGED, self)  
270    
271            If 'clazz' is None a default classification is created
272            """
273    
274            # prevent infinite recursion when calling SetLayer()
275            if self.__setClassLock: return
276    
277            self.__setClassLock = True
278    
279            if clazz is None:
280                if self.__classification is not None:
281                    self.__classification.SetLayer(None)
282                self.__classification = classification.Classification()
283            else:
284                self.__classification = clazz
285                try:
286                    self.__classification.SetLayer(self)
287                except ValueError:
288                    self.__setClassLock = False
289                    raise ValueError
290    
291            self.changed(LAYER_CHANGED, self)
292    
293            self.__setClassLock = False
294    
295        def ClassChanged(self):
296            """Called from the classification object when it has changed."""
297            self.changed(LAYER_CHANGED, self)
298    
299      def TreeInfo(self):      def TreeInfo(self):
300          items = []          items = []
301    
302          if self.Visible():          if self.Visible():
303              items.append("Shown")              items.append(_("Shown"))
304          else:          else:
305              items.append("Hidden")              items.append(_("Hidden"))
306          items.append("Shapes: %d" % self.NumShapes())          items.append(_("Shapes: %d") % self.NumShapes())
307    
308          bbox = self.LatLongBoundingBox()          bbox = self.LatLongBoundingBox()
309          if bbox is not None:          if bbox is not None:
310              items.append("Extent (lat-lon): (%g, %g, %g, %g)" % bbox)              items.append(_("Extent (lat-lon): (%g, %g, %g, %g)") % bbox)
311          else:          else:
312              items.append("Extent (lat-lon):")              items.append(_("Extent (lat-lon):"))
313          items.append("Shapetype: %s" % shapetype_names[self.ShapeType()])          items.append(_("Shapetype: %s") % shapetype_names[self.ShapeType()])
314    
315            items.append(self.__classification)
316    
317          def color_string(color):          return (_("Layer '%s'") % self.Title(), items)
             if color is None:  
                 return "None"  
             return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)  
         items.append("Fill: " + color_string(self.fill))  
         items.append("Outline: " + color_string(self.stroke))  
318    
         return ("Layer '%s'" % self.Title(), items)  

Legend:
Removed from v.217  
changed lines
  Added in v.701

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26