/[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 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 364 by jonathan, Mon Jan 27 11:47:12 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  #  #
# Line 7  Line 7 
7    
8  __version__ = "$Revision$"  __version__ = "$Revision$"
9    
10  import shapelib  import os
11    from math import log, ceil
12    
13    import shapelib, shptree
14    
15  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
16       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED
# Line 16  from color import Color Line 19  from color import Color
19  # Some predefined colors for internal use  # Some predefined colors for internal use
20  _black = Color(0, 0, 0)  _black = Color(0, 0, 0)
21    
22    from classification import Classification
23    
24  from table import Table  from table import Table
25    
# Line 81  class BaseLayer(TitledObject, Modifiable Line 85  class BaseLayer(TitledObject, Modifiable
85          """Set the layer's visibility."""          """Set the layer's visibility."""
86          self.visible = visible          self.visible = visible
87          self.issue(LAYER_VISIBILITY_CHANGED, self)          self.issue(LAYER_VISIBILITY_CHANGED, self)
88            
89            
90  class Layer(BaseLayer):  class Layer(BaseLayer):
91    
92      """Represent the information of one geodata file (currently a shapefile)      """Represent the information of one geodata file (currently a shapefile)
# Line 102  class Layer(BaseLayer): Line 106  class Layer(BaseLayer):
106      """      """
107    
108      def __init__(self, title, filename, projection = None,      def __init__(self, title, filename, projection = None,
109                   fill = None, stroke = _black, visible = 1):                   fill = None, stroke = _black, stroke_width = 1, visible = 1):
110          """Initialize the layer.          """Initialize the layer.
111    
112          title -- the title          title -- the title
# Line 117  class Layer(BaseLayer): Line 121  class Layer(BaseLayer):
121          colors are expected to be instances of Color class          colors are expected to be instances of Color class
122          """          """
123          BaseLayer.__init__(self, title, visible = visible)          BaseLayer.__init__(self, title, visible = visible)
124          self.filename = filename  
125            # Make the filename absolute. The filename will be
126            # interpreted relative to that anyway, but when saving a
127            # session we need to compare absolute paths and it's usually
128            # safer to always work with absolute paths.
129            self.filename = os.path.abspath(filename)
130    
131          self.projection = projection          self.projection = projection
132          self.fill = fill          self.fill = fill
133          self.stroke = stroke          self.stroke = stroke
134            self.stroke_width = stroke_width
135          self.shapefile = None          self.shapefile = None
136            self.shapetree = None
137            self.open_shapefile()
138          # shapetable is the table associated with the shapefile, while          # shapetable is the table associated with the shapefile, while
139          # table is the default table used to look up attributes for          # table is the default table used to look up attributes for
140          # display          # display
141          self.shapetable = Table(filename)          self.shapetable = Table(filename)
142          self.table = self.shapetable          self.table = self.shapetable
143    
144            self.classification = Classification()
145            self.classification.setNull(
146                {'stroke':stroke, 'stroke_width':stroke_width, 'fill':fill})
147    
148      def open_shapefile(self):      def open_shapefile(self):
149          if self.shapefile is None:          if self.shapefile is None:
150              self.shapefile = shapelib.ShapeFile(self.filename)              self.shapefile = shapelib.ShapeFile(self.filename)
151              numshapes, shapetype, mins, maxs = self.shapefile.info()              numshapes, shapetype, mins, maxs = self.shapefile.info()
152              self.numshapes = numshapes              self.numshapes = numshapes
153              self.shapetype = shapelib_shapetypes[shapetype]              self.shapetype = shapelib_shapetypes[shapetype]
154              self.bbox = mins[:2] + maxs[:2]  
155                # if there are shapes, set the bbox accordinly. Otherwise
156                # set it to None.
157                if self.numshapes:
158                    self.bbox = mins[:2] + maxs[:2]
159                else:
160                    self.bbox = None
161    
162                # estimate a good depth for the quad tree. Each depth
163                # multiplies the number of nodes by four, therefore we
164                # basically take the base 4 logarithm of the number of
165                # shapes.
166                if self.numshapes < 4:
167                    maxdepth = 1
168                else:
169                    maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
170    
171                self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
172                                                 maxdepth)
173    
174        def Destroy(self):
175            BaseLayer.Destroy(self)
176            if self.shapefile is not None:
177                self.shapefile.close()
178                self.shapefile = None
179                self.shapetree = None
180            self.table.Destroy()
181    
182      def BoundingBox(self):      def BoundingBox(self):
183          """Return the bounding box of the layer's shapes in their default          """Return the layer's bounding box in the intrinsic coordinate system.
184          coordinate system"""  
185            If the layer has no shapes, return None.
186            """
187            # The bbox will be set by open_shapefile just as we need it
188            # here.
189          self.open_shapefile()          self.open_shapefile()
190          return self.bbox          return self.bbox
191    
192      def LatLongBoundingBox(self):      def LatLongBoundingBox(self):
193          """Return the layer's bounding box in lat/long coordinates"""          """Return the layer's bounding box in lat/long coordinates.
194          llx, lly, urx, ury = self.BoundingBox()  
195          if self.projection is not None:          Return None, if the layer doesn't contain any shapes.
196              llx, lly = self.projection.Inverse(llx, lly)          """
197              urx, ury = self.projection.Inverse(urx, ury)          bbox = self.BoundingBox()
198          return llx, lly, urx, ury          if bbox is not None:
199                llx, lly, urx, ury = bbox
200                if self.projection is not None:
201                    llx, lly = self.projection.Inverse(llx, lly)
202                    urx, ury = self.projection.Inverse(urx, ury)
203                return llx, lly, urx, ury
204            else:
205                return None
206    
207      def NumShapes(self):      def NumShapes(self):
208          """Return the number of shapes in the layer"""          """Return the number of shapes in the layer"""
# Line 166  class Layer(BaseLayer): Line 220  class Layer(BaseLayer):
220          """Return the shape with index index"""          """Return the shape with index index"""
221          self.open_shapefile()          self.open_shapefile()
222          shape = self.shapefile.read_object(index)          shape = self.shapefile.read_object(index)
223    
224          if self.shapetype == SHAPETYPE_POINT:          if self.shapetype == SHAPETYPE_POINT:
225              points = shape.vertices()              points = shape.vertices()
226          else:          else:
# Line 173  class Layer(BaseLayer): Line 228  class Layer(BaseLayer):
228              poly = shape.vertices()[0]              poly = shape.vertices()[0]
229              points = []              points = []
230              for x, y in poly:              for x, y in poly:
231                  points.append(x, y)                  points.append((x, y))
232    
233          return Shape(points)          return Shape(points)
234    
235        def ShapesInRegion(self, box):
236            """Return the ids of the shapes that overlap the box.
237    
238            Box is a tuple (left, bottom, right, top) in the coordinate
239            system used by the layer's shapefile.
240            """
241            left, bottom, right, top = box
242            return self.shapetree.find_shapes((left, bottom), (right, top))
243    
244      def SetProjection(self, projection):      def SetProjection(self, projection):
245          """Set the layer's projection"""          """Set the layer's projection"""
246          self.projection = projection          self.projection = projection
# Line 191  class Layer(BaseLayer): Line 256  class Layer(BaseLayer):
256          stroked."""          stroked."""
257          self.stroke = stroke          self.stroke = stroke
258          self.changed(LAYER_LEGEND_CHANGED, self)          self.changed(LAYER_LEGEND_CHANGED, self)
259    
260        def SetStrokeWidth(self, width):
261            """Set the layer's stroke width."""
262            self.stroke_width = width
263            self.changed(LAYER_LEGEND_CHANGED, self)
264    
265        def TreeInfo(self):
266            items = []
267    
268            if self.Visible():
269                items.append("Shown")
270            else:
271                items.append("Hidden")
272            items.append("Shapes: %d" % self.NumShapes())
273    
274            bbox = self.LatLongBoundingBox()
275            if bbox is not None:
276                items.append("Extent (lat-lon): (%g, %g, %g, %g)" % bbox)
277            else:
278                items.append("Extent (lat-lon):")
279            items.append("Shapetype: %s" % shapetype_names[self.ShapeType()])
280    
281            def color_string(color):
282                if color is None:
283                    return "None"
284                return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
285            items.append("Fill: " + color_string(self.fill))
286            items.append("Outline: " + color_string(self.stroke))
287    
288            return ("Layer '%s'" % self.Title(), items)

Legend:
Removed from v.6  
changed lines
  Added in v.364

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26