/[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 723 by bh, Thu Apr 24 15:31:53 2003 UTC revision 929 by jonathan, Tue May 20 15:22:42 2003 UTC
# Line 14  from Thuban import _ Line 14  from Thuban import _
14    
15  import shapelib, shptree  import shapelib, shptree
16    
17    import gdal
18    from gdalconst import GA_ReadOnly
19    
20  from messages import LAYER_PROJECTION_CHANGED, LAYER_VISIBILITY_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_VISIBILITY_CHANGED, \
21       LAYER_CHANGED       LAYER_CHANGED
22    
# Line 31  class Shape: Line 34  class Shape:
34      def __init__(self, points):      def __init__(self, points):
35          self.points = points          self.points = points
36          #self.compute_bbox()          #self.compute_bbox()
37            self.bbox = None
38    
39      def compute_bbox(self):      def compute_bbox(self):
40            if self.bbox is not None:
41                return self.bbox
42    
43          xs = []          xs = []
44          ys = []          ys = []
45          for x, y in self.points:          for x, y in self.points:
# Line 43  class Shape: Line 50  class Shape:
50          self.urx = max(xs)          self.urx = max(xs)
51          self.ury = max(ys)          self.ury = max(ys)
52    
53            self.bbox = (self.llx, self.lly, self.urx, self.ury)
54    
55            return self.bbox
56    
57      def Points(self):      def Points(self):
58          return self.points          return self.points
59    
# Line 66  class BaseLayer(TitledObject, Modifiable Line 77  class BaseLayer(TitledObject, Modifiable
77    
78      """Base class for the layers."""      """Base class for the layers."""
79    
80      def __init__(self, title, visible = 1):      def __init__(self, title, visible = True, projection = None):
81          """Initialize the layer.          """Initialize the layer.
82    
83          title -- the title          title -- the title
# Line 75  class BaseLayer(TitledObject, Modifiable Line 86  class BaseLayer(TitledObject, Modifiable
86          TitledObject.__init__(self, title)          TitledObject.__init__(self, title)
87          Modifiable.__init__(self)          Modifiable.__init__(self)
88          self.visible = visible          self.visible = visible
89            self.projection = projection
90    
91      def Visible(self):      def Visible(self):
92          """Return true if layer is visible"""          """Return true if layer is visible"""
# Line 85  class BaseLayer(TitledObject, Modifiable Line 97  class BaseLayer(TitledObject, Modifiable
97          self.visible = visible          self.visible = visible
98          self.issue(LAYER_VISIBILITY_CHANGED, self)          self.issue(LAYER_VISIBILITY_CHANGED, self)
99    
100        def HasClassification(self):
101            """Determine if this layer support classifications."""
102            return False
103    
104        def GetProjection(self):
105            """Return the layer's projection."""
106            return self.projection
107    
108        def SetProjection(self, projection):
109            """Set the layer's projection"""
110            self.projection = projection
111            self.changed(LAYER_PROJECTION_CHANGED, self)
112    
113  class Layer(BaseLayer):  class Layer(BaseLayer):
114    
# Line 106  class Layer(BaseLayer): Line 130  class Layer(BaseLayer):
130                   fill = Color.Transparent,                   fill = Color.Transparent,
131                   stroke = Color.Black,                   stroke = Color.Black,
132                   lineWidth = 1,                   lineWidth = 1,
133                   visible = 1):                   visible = True):
134          """Initialize the layer.          """Initialize the layer.
135    
136          title -- the title          title -- the title
# Line 122  class Layer(BaseLayer): Line 146  class Layer(BaseLayer):
146    
147          colors are expected to be instances of Color class          colors are expected to be instances of Color class
148          """          """
149          BaseLayer.__init__(self, title, visible = visible)          BaseLayer.__init__(self, title,
150                                     visible = visible,
151          self.projection = projection                                   projection = projection)
152    
153          #          #
154          # this is really important so that when the classification class          # this is really important so that when the classification class
# Line 176  class Layer(BaseLayer): Line 200  class Layer(BaseLayer):
200                                           maxdepth)                                           maxdepth)
201          if self.__classification is not None:          if self.__classification is not None:
202              fieldname = self.__classification.GetField()              fieldname = self.__classification.GetField()
203              if not self.store.Table().field_info_by_name(fieldname):              if fieldname is not None and \
204                   not self.store.Table().HasColumn(fieldname):
205                  self.SetClassification(None)                  self.SetClassification(None)
206          self.changed(LAYER_CHANGED, self)          self.changed(LAYER_CHANGED, self)
207    
# Line 209  class Layer(BaseLayer): Line 234  class Layer(BaseLayer):
234          else:          else:
235              return None              return None
236    
237      def GetFieldType(self, fieldName):      def ShapesBoundingBox(self, shapes):
238          info = self.table.field_info_by_name(fieldName)          """Return a bounding box in lat/long coordinates for the given
239          if info is not None:          list of shape ids.
240              return info[0]  
241            If shapes is None or empty, return None.
242            """
243    
244            if shapes is None or len(shapes) == 0: return None
245    
246            llx = []
247            lly = []
248            urx = []
249            ury = []
250    
251            if self.projection is not None:
252                inverse = lambda x, y: self.projection.Inverse(x, y)
253          else:          else:
254              return None              inverse = lambda x, y: (x, y)
255    
256            for id in shapes:
257                left, bottom, right, top = self.Shape(id).compute_bbox()
258    
259                left, bottom = inverse(left, bottom)
260                right, top   = inverse(right, top)
261    
262                llx.append(left)
263                lly.append(bottom)
264                urx.append(right)
265                ury.append(top)
266    
267            return (min(llx), min(lly), max(urx), max(ury))
268    
269        def GetFieldType(self, fieldName):
270            if self.table.HasColumn(fieldName):
271                return self.table.Column(fieldName).type
272            return None
273    
274      def NumShapes(self):      def NumShapes(self):
275          """Return the number of shapes in the layer"""          """Return the number of shapes in the layer"""
# Line 244  class Layer(BaseLayer): Line 299  class Layer(BaseLayer):
299      def ShapesInRegion(self, box):      def ShapesInRegion(self, box):
300          """Return the ids of the shapes that overlap the box.          """Return the ids of the shapes that overlap the box.
301    
302          Box is a tuple (left, bottom, right, top) in the coordinate          Box is a tuple (left, bottom, right, top) in unprojected coordinates.
         system used by the layer's shapefile.  
303          """          """
304          left, bottom, right, top = box          left, bottom, right, top = box
305    
306            if self.projection is not None:
307                left,  bottom = self.projection.Forward(left, bottom)
308                right, top    = self.projection.Forward(right, top)
309    
310          return self.shapetree.find_shapes((left, bottom), (right, top))          return self.shapetree.find_shapes((left, bottom), (right, top))
311    
312      def SetProjection(self, projection):      def HasClassification(self):
313          """Set the layer's projection"""          return True
         self.projection = projection  
         self.changed(LAYER_PROJECTION_CHANGED, self)  
314    
315      def GetClassification(self):      def GetClassification(self):
316          return self.__classification          return self.__classification
# Line 305  class Layer(BaseLayer): Line 362  class Layer(BaseLayer):
362              items.append(_("Extent (lat-lon):"))              items.append(_("Extent (lat-lon):"))
363          items.append(_("Shapetype: %s") % shapetype_names[self.ShapeType()])          items.append(_("Shapetype: %s") % shapetype_names[self.ShapeType()])
364    
365            if self.projection and len(self.projection.params) > 0:
366                items.append((_("Projection"),
367                            [str(param) for param in self.projection.params]))
368    
369          items.append(self.__classification)          items.append(self.__classification)
370    
371          return (_("Layer '%s'") % self.Title(), items)          return (_("Layer '%s'") % self.Title(), items)
372    
373    
374    class RasterLayer(BaseLayer):
375    
376        def __init__(self, title, filename, projection = None, visible = True):
377            """Initialize the Raster Layer.
378    
379            title -- title for the layer.
380    
381            filename -- file name of the source image.
382    
383            projection -- Projection object describing the projection which
384                          the source image is in.
385    
386            visible -- True is the layer should initially be visible.
387            """
388    
389            BaseLayer.__init__(self, title, visible = visible)
390    
391            self.projection = projection
392            self.filename = filename
393    
394            self.bbox = -1
395    
396            self.UnsetModified()
397    
398    
399        def BoundingBox(self):
400            """Return the layer's bounding box in the intrinsic coordinate system.
401    
402            If the layer has no shapes, return None.
403            """
404            if self.bbox == -1:
405                dataset = gdal.Open(self.filename, GA_ReadOnly)
406                if dataset is None:
407                    self.bbox = None
408                else:
409                    left, bottom = self.__CalcCorner(dataset,
410                                                     0, dataset.RasterYSize)
411                    right, top   = self.__CalcCorner(dataset,
412                                                     dataset.RasterXSize, 0)
413                    self.bbox = (left, bottom, right, top)
414    
415            return self.bbox
416    
417        def __CalcCorner(self, dataset, x, y):
418            geotransform = dataset.GetGeoTransform()
419            return geotransform[0] + geotransform[1] * x + geotransform[2] * y, \
420                   geotransform[3] + geotransform[4] * x + geotransform[5] * y
421    
422        def LatLongBoundingBox(self):
423            bbox = self.BoundingBox()
424            if bbox is not None:
425                llx, lly, urx, ury = bbox
426                if self.projection is not None:
427                    llx, lly = self.projection.Inverse(llx, lly)
428                    urx, ury = self.projection.Inverse(urx, ury)
429                return llx, lly, urx, ury
430            else:
431                return None
432    
433        def GetImageFilename(self):
434            return self.filename
435    
436        def TreeInfo(self):
437            items = []
438    
439            if self.Visible():
440                items.append(_("Shown"))
441            else:
442                items.append(_("Hidden"))
443            items.append(_("Shapes: %d") % self.NumShapes())
444    
445            bbox = self.LatLongBoundingBox()
446            if bbox is not None:
447                items.append(_("Extent (lat-lon): (%g, %g, %g, %g)") % bbox)
448            else:
449                items.append(_("Extent (lat-lon):"))
450    
451            if self.projection and len(self.projection.params) > 0:
452                items.append((_("Projection"),
453                            [str(param) for param in self.projection.params]))
454    
455            return (_("Layer '%s'") % self.Title(), items)
456    

Legend:
Removed from v.723  
changed lines
  Added in v.929

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26