/[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 73 by bh, Mon Feb 4 19:19:25 2002 UTC revision 276 by bh, Fri Aug 23 15:25:07 2002 UTC
# 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 81  class BaseLayer(TitledObject, Modifiable Line 84  class BaseLayer(TitledObject, Modifiable
84          """Set the layer's visibility."""          """Set the layer's visibility."""
85          self.visible = visible          self.visible = visible
86          self.issue(LAYER_VISIBILITY_CHANGED, self)          self.issue(LAYER_VISIBILITY_CHANGED, self)
87            
88            
89  class Layer(BaseLayer):  class Layer(BaseLayer):
90    
91      """Represent the information of one geodata file (currently a shapefile)      """Represent the information of one geodata file (currently a shapefile)
# Line 117  class Layer(BaseLayer): Line 120  class Layer(BaseLayer):
120          colors are expected to be instances of Color class          colors are expected to be instances of Color class
121          """          """
122          BaseLayer.__init__(self, title, visible = visible)          BaseLayer.__init__(self, title, visible = visible)
123          self.filename = filename  
124            # Make the filename absolute. The filename will be
125            # interpreted relative to that anyway, but when saving a
126            # session we need to compare absolute paths and it's usually
127            # safer to always work with absolute paths.
128            self.filename = os.path.abspath(filename)
129    
130          self.projection = projection          self.projection = projection
131          self.fill = fill          self.fill = fill
132          self.stroke = stroke          self.stroke = stroke
133          self.stroke_width = stroke_width          self.stroke_width = stroke_width
134          self.shapefile = None          self.shapefile = None
135            self.shapetree = None
136          self.open_shapefile()          self.open_shapefile()
137          # shapetable is the table associated with the shapefile, while          # shapetable is the table associated with the shapefile, while
138          # table is the default table used to look up attributes for          # table is the default table used to look up attributes for
# Line 136  class Layer(BaseLayer): Line 146  class Layer(BaseLayer):
146              numshapes, shapetype, mins, maxs = self.shapefile.info()              numshapes, shapetype, mins, maxs = self.shapefile.info()
147              self.numshapes = numshapes              self.numshapes = numshapes
148              self.shapetype = shapelib_shapetypes[shapetype]              self.shapetype = shapelib_shapetypes[shapetype]
149              self.bbox = mins[:2] + maxs[:2]  
150                # if there are shapes, set the bbox accordinly. Otherwise
151                # set it to None.
152                if self.numshapes:
153                    self.bbox = mins[:2] + maxs[:2]
154                else:
155                    self.bbox = None
156    
157                # estimate a good depth for the quad tree. Each depth
158                # multiplies the number of nodes by four, therefore we
159                # basically take the base 4 logarithm of the number of
160                # shapes.
161                if self.numshapes < 4:
162                    maxdepth = 1
163                else:
164                    maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
165    
166                self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
167                                                 maxdepth)
168    
169        def Destroy(self):
170            BaseLayer.Destroy(self)
171            if self.shapefile is not None:
172                self.shapefile.close()
173                self.shapefile = None
174                self.shapetree = None
175            self.table.Destroy()
176    
177      def BoundingBox(self):      def BoundingBox(self):
178          """Return the bounding box of the layer's shapes in their default          """Return the layer's bounding box in the intrinsic coordinate system.
179          coordinate system"""  
180            If the layer has no shapes, return None.
181            """
182            # The bbox will be set by open_shapefile just as we need it
183            # here.
184          self.open_shapefile()          self.open_shapefile()
185          return self.bbox          return self.bbox
186    
187      def LatLongBoundingBox(self):      def LatLongBoundingBox(self):
188          """Return the layer's bounding box in lat/long coordinates"""          """Return the layer's bounding box in lat/long coordinates.
189          llx, lly, urx, ury = self.BoundingBox()  
190          if self.projection is not None:          Return None, if the layer doesn't contain any shapes.
191              llx, lly = self.projection.Inverse(llx, lly)          """
192              urx, ury = self.projection.Inverse(urx, ury)          bbox = self.BoundingBox()
193          return llx, lly, urx, ury          if bbox is not None:
194                llx, lly, urx, ury = bbox
195                if self.projection is not None:
196                    llx, lly = self.projection.Inverse(llx, lly)
197                    urx, ury = self.projection.Inverse(urx, ury)
198                return llx, lly, urx, ury
199            else:
200                return None
201    
202      def NumShapes(self):      def NumShapes(self):
203          """Return the number of shapes in the layer"""          """Return the number of shapes in the layer"""
# Line 175  class Layer(BaseLayer): Line 222  class Layer(BaseLayer):
222              poly = shape.vertices()[0]              poly = shape.vertices()[0]
223              points = []              points = []
224              for x, y in poly:              for x, y in poly:
225                  points.append(x, y)                  points.append((x, y))
226          return Shape(points)          return Shape(points)
227    
228        def ShapesInRegion(self, box):
229            """Return the ids of the shapes that overlap the box.
230    
231            Box is a tuple (left, bottom, right, top) in the coordinate
232            system used by the layer's shapefile.
233            """
234            left, bottom, right, top = box
235            return self.shapetree.find_shapes((left, bottom), (right, top))
236    
237      def SetProjection(self, projection):      def SetProjection(self, projection):
238          """Set the layer's projection"""          """Set the layer's projection"""
239          self.projection = projection          self.projection = projection
# Line 198  class Layer(BaseLayer): Line 254  class Layer(BaseLayer):
254          """Set the layer's stroke width."""          """Set the layer's stroke width."""
255          self.stroke_width = width          self.stroke_width = width
256          self.changed(LAYER_LEGEND_CHANGED, self)          self.changed(LAYER_LEGEND_CHANGED, self)
257    
258        def TreeInfo(self):
259            items = []
260    
261            if self.Visible():
262                items.append("Shown")
263            else:
264                items.append("Hidden")
265            items.append("Shapes: %d" % self.NumShapes())
266    
267            bbox = self.LatLongBoundingBox()
268            if bbox is not None:
269                items.append("Extent (lat-lon): (%g, %g, %g, %g)" % bbox)
270            else:
271                items.append("Extent (lat-lon):")
272            items.append("Shapetype: %s" % shapetype_names[self.ShapeType()])
273    
274            def color_string(color):
275                if color is None:
276                    return "None"
277                return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
278            items.append("Fill: " + color_string(self.fill))
279            items.append("Outline: " + color_string(self.stroke))
280    
281            return ("Layer '%s'" % self.Title(), items)

Legend:
Removed from v.73  
changed lines
  Added in v.276

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26