/[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 143 by bh, Tue May 7 14:17:20 2002 UTC revision 382 by jonathan, Tue Jan 28 18:37:35 2003 UTC
# Line 7  Line 7 
7    
8  __version__ = "$Revision$"  __version__ = "$Revision$"
9    
10    import os
11    from math import log, ceil
12    
13    from Thuban import _
14    
15  import shapelib, shptree  import shapelib, shptree
16    
17  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
# Line 16  from color import Color Line 21  from color import Color
21  # Some predefined colors for internal use  # Some predefined colors for internal use
22  _black = Color(0, 0, 0)  _black = Color(0, 0, 0)
23    
24    from classification import Classification
25    
26  from table import Table  from table import Table
27    
# Line 81  class BaseLayer(TitledObject, Modifiable Line 87  class BaseLayer(TitledObject, Modifiable
87          """Set the layer's visibility."""          """Set the layer's visibility."""
88          self.visible = visible          self.visible = visible
89          self.issue(LAYER_VISIBILITY_CHANGED, self)          self.issue(LAYER_VISIBILITY_CHANGED, self)
90            
91            
92  class Layer(BaseLayer):  class Layer(BaseLayer):
93    
94      """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 123  class Layer(BaseLayer):
123          colors are expected to be instances of Color class          colors are expected to be instances of Color class
124          """          """
125          BaseLayer.__init__(self, title, visible = visible)          BaseLayer.__init__(self, title, visible = visible)
126          self.filename = filename  
127            # Make the filename absolute. The filename will be
128            # interpreted relative to that anyway, but when saving a
129            # session we need to compare absolute paths and it's usually
130            # safer to always work with absolute paths.
131            self.filename = os.path.abspath(filename)
132    
133          self.projection = projection          self.projection = projection
134          self.fill = fill          self.fill = fill
135          self.stroke = stroke          self.stroke = stroke
# Line 131  class Layer(BaseLayer): Line 143  class Layer(BaseLayer):
143          self.shapetable = Table(filename)          self.shapetable = Table(filename)
144          self.table = self.shapetable          self.table = self.shapetable
145    
146            self.classification = Classification()
147            self.classification.setNull(
148                {'stroke':stroke, 'stroke_width':stroke_width, 'fill':fill})
149    
150      def open_shapefile(self):      def open_shapefile(self):
151          if self.shapefile is None:          if self.shapefile is None:
152              self.shapefile = shapelib.ShapeFile(self.filename)              self.shapefile = shapelib.ShapeFile(self.filename)
153              numshapes, shapetype, mins, maxs = self.shapefile.info()              numshapes, shapetype, mins, maxs = self.shapefile.info()
154              self.numshapes = numshapes              self.numshapes = numshapes
155              self.shapetype = shapelib_shapetypes[shapetype]              self.shapetype = shapelib_shapetypes[shapetype]
156              self.bbox = mins[:2] + maxs[:2]  
157              #print "building tree for", self.filename, "..."              # if there are shapes, set the bbox accordinly. Otherwise
158              self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2, 0)              # set it to None.
159              #print "done"              if self.numshapes:
160                    self.bbox = mins[:2] + maxs[:2]
161                else:
162                    self.bbox = None
163    
164                # estimate a good depth for the quad tree. Each depth
165                # multiplies the number of nodes by four, therefore we
166                # basically take the base 4 logarithm of the number of
167                # shapes.
168                if self.numshapes < 4:
169                    maxdepth = 1
170                else:
171                    maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
172    
173                self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
174                                                 maxdepth)
175    
176        def Destroy(self):
177            BaseLayer.Destroy(self)
178            if self.shapefile is not None:
179                self.shapefile.close()
180                self.shapefile = None
181                self.shapetree = None
182            self.table.Destroy()
183    
184      def BoundingBox(self):      def BoundingBox(self):
185          """Return the bounding box of the layer's shapes in their default          """Return the layer's bounding box in the intrinsic coordinate system.
186          coordinate system"""  
187            If the layer has no shapes, return None.
188            """
189            # The bbox will be set by open_shapefile just as we need it
190            # here.
191          self.open_shapefile()          self.open_shapefile()
192          return self.bbox          return self.bbox
193    
194      def LatLongBoundingBox(self):      def LatLongBoundingBox(self):
195          """Return the layer's bounding box in lat/long coordinates"""          """Return the layer's bounding box in lat/long coordinates.
196          llx, lly, urx, ury = self.BoundingBox()  
197          if self.projection is not None:          Return None, if the layer doesn't contain any shapes.
198              llx, lly = self.projection.Inverse(llx, lly)          """
199              urx, ury = self.projection.Inverse(urx, ury)          bbox = self.BoundingBox()
200          return llx, lly, urx, ury          if bbox is not None:
201                llx, lly, urx, ury = bbox
202                if self.projection is not None:
203                    llx, lly = self.projection.Inverse(llx, lly)
204                    urx, ury = self.projection.Inverse(urx, ury)
205                return llx, lly, urx, ury
206            else:
207                return None
208    
209      def NumShapes(self):      def NumShapes(self):
210          """Return the number of shapes in the layer"""          """Return the number of shapes in the layer"""
# Line 172  class Layer(BaseLayer): Line 222  class Layer(BaseLayer):
222          """Return the shape with index index"""          """Return the shape with index index"""
223          self.open_shapefile()          self.open_shapefile()
224          shape = self.shapefile.read_object(index)          shape = self.shapefile.read_object(index)
225    
226          if self.shapetype == SHAPETYPE_POINT:          if self.shapetype == SHAPETYPE_POINT:
227              points = shape.vertices()              points = shape.vertices()
228          else:          else:
# Line 180  class Layer(BaseLayer): Line 231  class Layer(BaseLayer):
231              points = []              points = []
232              for x, y in poly:              for x, y in poly:
233                  points.append((x, y))                  points.append((x, y))
234    
235          return Shape(points)          return Shape(points)
236    
237      def ShapesInRegion(self, box):      def ShapesInRegion(self, box):
# Line 189  class Layer(BaseLayer): Line 241  class Layer(BaseLayer):
241          system used by the layer's shapefile.          system used by the layer's shapefile.
242          """          """
243          left, bottom, right, top = box          left, bottom, right, top = box
244          import time          return self.shapetree.find_shapes((left, bottom), (right, top))
         start = time.time()  
         ids = self.shapetree.find_shapes((left, bottom), (right, top))  
         print "ShapesInRegion", time.time() - start  
         return ids  
245    
246      def SetProjection(self, projection):      def SetProjection(self, projection):
247          """Set the layer's projection"""          """Set the layer's projection"""
# Line 215  class Layer(BaseLayer): Line 263  class Layer(BaseLayer):
263          """Set the layer's stroke width."""          """Set the layer's stroke width."""
264          self.stroke_width = width          self.stroke_width = width
265          self.changed(LAYER_LEGEND_CHANGED, self)          self.changed(LAYER_LEGEND_CHANGED, self)
266    
267        def TreeInfo(self):
268            items = []
269    
270            if self.Visible():
271                items.append(_("Shown"))
272            else:
273                items.append(_("Hidden"))
274            items.append(_("Shapes: %d") % self.NumShapes())
275    
276            bbox = self.LatLongBoundingBox()
277            if bbox is not None:
278                items.append(_("Extent (lat-lon): (%g, %g, %g, %g)") % bbox)
279            else:
280                items.append(_("Extent (lat-lon):"))
281            items.append(_("Shapetype: %s") % shapetype_names[self.ShapeType()])
282    
283            def color_string(color):
284                if color is None:
285                    return "None"
286                return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
287    
288            # layers will always have a classification with at least a NULL data set
289    
290            #items.append((_("Fill: %s") % color_string(self.fill), self.fill))
291            #items.append((_("Outline: %s") % color_string(self.stroke), self.stroke))
292    
293            items.append(self.classification)
294    
295            return (_("Layer '%s'") % self.Title(), items)
296    

Legend:
Removed from v.143  
changed lines
  Added in v.382

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26