/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py

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

revision 428 by jonathan, Mon Feb 24 18:46:35 2003 UTC revision 436 by jonathan, Thu Feb 27 15:53:03 2003 UTC
# Line 23  on the mapping algorithm. Line 23  on the mapping algorithm.
23  # fix for people using python2.1  # fix for people using python2.1
24  from __future__ import nested_scopes  from __future__ import nested_scopes
25    
26    from types import *
27    
28  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
29       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED
30    
31  from Thuban import _  from Thuban import _
32  from Thuban.Model.color import Color  from Thuban.Model.color import Color
33    
34    import Thuban.Model.layer
35    
36  from wxPython.wx import *  from wxPython.wx import *
37    
38  # constants  # constants
# Line 47  class Classification: Line 51  class Classification:
51                      is to be used to classify layer properties                      is to be used to classify layer properties
52          """          """
53    
54            self.layer = None # stop message sending
55    
56            self.SetDefaultGroup(ClassGroupDefault())
57            self.SetField(field)
58    
59          self.layer = layer          self.layer = layer
60          self.points = {}          self.points = []
61          self.ranges = []          self.ranges = []
62          self.maps   = []          self.maps   = []
         self.DefaultData = ClassDataDefault()  
         self.field = field  
         #self.SetField(field)  
63    
64      def __iter__(self):      def __iter__(self):
65          return ClassIterator(self.DefaultData,          return ClassIterator(self.DefaultGroup,
66                               self.points.values(),                               self.points,
67                               self.ranges,                               self.ranges,
68                               self.maps)                               self.maps)
69    
# Line 71  class Classification: Line 77  class Classification:
77             field -- if None then all values map to the default data             field -- if None then all values map to the default data
78          """          """
79    
80            if field == "":
81                field = None
82    
83          self.field = field          self.field = field
84          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
85    
# Line 78  class Classification: Line 87  class Classification:
87          return self.field          return self.field
88    
89      def SetLayer(self, layer):      def SetLayer(self, layer):
90            assert(isinstance(layer, Thuban.Model.layer.Layer))
91          self.layer = layer          self.layer = layer
92          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
93    
94      def GetLayer(self):      def GetLayer(self):
95          return layer.self          return layer.self
96    
97      def SetDefaultData(self, data):      def SetDefaultGroup(self, group):
98          """Set the data to be used when a value can't be classified.          """Set the group to be used when a value can't be classified.
99    
100             data -- data that the value maps to. See class description.             group -- group that the value maps to. See class description.
101          """          """
102    
103          assert(data.GetType() == ClassData.DEFAULT)          assert(isinstance(group, ClassGroupDefault))
104          self.DefaultData = data          self.DefaultGroup = group
105    
106      def GetDefaultData(self):      def GetDefaultGroup(self):
107          return self.DefaultData          return self.DefaultGroup
108    
109      #      #
110      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
# Line 103  class Classification: Line 113  class Classification:
113      #      #
114    
115      def SetDefaultFill(self, fill):      def SetDefaultFill(self, fill):
116          self.DefaultData.SetFill(fill)          assert(isinstance(fill, Color))
117            self.DefaultGroup.GetProperties().SetFill(fill)
118          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
119                    
120      def GetDefaultFill(self):      def GetDefaultFill(self):
121          return self.DefaultData.GetFill()          return self.DefaultGroup.GetProperties().GetFill()
122                    
123      def SetDefaultStroke(self, stroke):      def SetDefaultStroke(self, stroke):
124          self.DefaultData.SetStroke(stroke)          assert(isinstance(stroke, Color))
125            self.DefaultGroup.GetProperties().SetStroke(stroke)
126          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
127                    
128      def GetDefaultStroke(self):      def GetDefaultStroke(self):
129          return self.DefaultData.GetStroke()          return self.DefaultGroup.GetProperties().GetStroke()
130                    
131      def SetDefaultStrokeWidth(self, strokeWidth):      def SetDefaultStrokeWidth(self, strokeWidth):
132          self.DefaultData.SetStrokeWidth(strokeWidth)          assert(isinstance(strokeWidth, IntType))
133            self.DefaultGroup.GetProperties().SetStrokeWidth(strokeWidth)
134          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
135                    
136      def GetDefaultStrokeWidth(self):      def GetDefaultStrokeWidth(self):
137          return self.DefaultData.GetStrokeWidth()          return self.DefaultGroup.GetProperties().GetStrokeWidth()
138                    
139      def AddClassData(self, item):      def AddGroup(self, item):
140          type = item.GetType()          assert(isinstance(item, ClassGroup))
141    
142          if type == ClassData.POINT:          if isinstance(item, ClassGroupDefault):
143              self.points[item.GetValue()] = item              self.SetDefaultGroup(item)
144          elif type == ClassData.RANGE:          elif isinstance(item, ClassGroupSingleton):
145                self.points.append(item)
146            elif isinstance(item, ClassGroupRange):
147              self.ranges.append(item)              self.ranges.append(item)
148          elif type == ClassData.MAP:          elif isinstance(item, ClassGroupMap):
149              self.maps.append(item)              self.maps.append(item)
         elif type == ClassData.DEFAULT:  
             self.DefaultData = item  
150          else:          else:
151              raise ValueError(_("Unrecognized ClassData type %s") % type)              raise ValueError(_("Unrecognized ClassGroup"))
152    
153          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendMessage(LAYER_LEGEND_CHANGED)
154    
155      def GetClassData(self, value):      def GetGroup(self, value):
156          """Return the associated data, or the default data.          """Return the associated data, or the default data.
157    
158             The following search technique is used:             The following search technique is used:
# Line 154  class Classification: Line 167  class Classification:
167          """          """
168    
169          if self.field is not None and value is not None:          if self.field is not None and value is not None:
170              #  
171              # check the discrete values              for p in self:
172              #                  if p.Matches(value):
             if self.points.has_key(value):  
                 return self.points[value]  
   
             #  
             # check the ranges  
             #  
             for p in self.ranges:  
                 if p.InRange(value):  
173                      return p                      return p
174    #           #
175    #           # check the discrete values
176    #           #
177    #           if self.points.has_key(value):
178    #               return self.points[value]
179    #           #for p in self.points:
180    #               #if p.Value
181    
182    #           #
183    #           # check the ranges
184    #           #
185    #           for p in self.ranges:
186    #               if p.InRange(value):
187    #                   return p
188    
189    #           #
190    #           # check the maps
191    #           #
192    #           for p in self.maps:
193    #               try:
194    #                   return p.Map(value)
195    #               except: pass
196    
197              #          return self.DefaultGroup
             # check the maps  
             #  
             for p in self.maps:  
                 try:  
                     return p.Map(value)  
                 except: pass  
198    
199          return self.DefaultData      def GetProperties(self, value):
200            return self.GetGroup(value).GetProperties()
201    
202      def TreeInfo(self):      def TreeInfo(self):
203          items = []          items = []
# Line 188  class Classification: Line 210  class Classification:
210                      (text, color.red, color.green, color.blue),                      (text, color.red, color.green, color.blue),
211                      color)                      color)
212    
213          def build_item(data, string):          def build_item(group, string):
214              label = data.GetLabel()              label = group.GetLabel()
215              if label == "":              if label == "":
216                  label = string                  label = string
217              else:              else:
218                  label += " (%s)" % string                  label += " (%s)" % string
219    
220                props = group.GetProperties()
221              i = []              i = []
222              v = data.GetStroke()              v = props.GetStroke()
223              i.append(build_color_item(_("Stroke"), v))              i.append(build_color_item(_("Stroke"), v))
224              v = data.GetStrokeWidth()              v = props.GetStrokeWidth()
225              i.append(_("Stroke Width: %s") % v)              i.append(_("Stroke Width: %s") % v)
226              v = data.GetFill()              v = props.GetFill()
227              i.append(build_color_item(_("Fill"), v))              i.append(build_color_item(_("Fill"), v))
228              return (label, i)              return (label, i)
229    
230          for p in self:          for p in self:
231              type = p.GetType()              if isinstance(p, ClassGroupDefault):
232              if type == ClassData.DEFAULT:                  items.append(build_item(self.DefaultGroup, _("'DEFAULT'")))
233                  items.append(build_item(self.DefaultData, _("'DEFAULT'")))              elif isinstance(p, ClassGroupSingleton):
             elif type == ClassData.POINT:  
234                  items.append(build_item(p, str(p.GetValue())))                  items.append(build_item(p, str(p.GetValue())))
235              elif type == ClassData.RANGE:              elif isinstance(p, ClassGroupRange):
236                  items.append(build_item(p, "%s - %s" %                  items.append(build_item(p, "%s - %s" %
237                                             (p.GetMin(), p.GetMax())))                                             (p.GetMin(), p.GetMax())))
238    
# Line 220  class Classification: Line 242  class Classification:
242  #       for p in self.ranges:  #       for p in self.ranges:
243  #           items.append(build_item(p, "%s - %s" % (p.GetMin(), p.GetMax())))  #           items.append(build_item(p, "%s - %s" % (p.GetMin(), p.GetMax())))
244    
245          return (_("Classifications"), items)          return (_("Classification"), items)
246    
247  class ClassIterator:  class ClassIterator:
248    
# Line 246  class ClassIterator: Line 268  class ClassIterator:
268              self.iter = None              self.iter = None
269              return self.next()              return self.next()
270                
271  class ClassData:  class ClassGroupProperties:
272    
273        def __init__(self, prop = None):
274    
275      INVALID = -1          if prop is not None:
276      DEFAULT = 0              self.SetStroke(prop.GetStroke())
277      POINT = 1              self.SetStrokeWidth(prop.GetStrokeWidth())
278      RANGE = 2              self.SetFill(prop.GetFill())
     MAP   = 3  
   
     def __init__(self, classData = None, type = INVALID):  
   
         if classData is not None:  
             self.SetStroke(classData.GetStroke())  
             self.SetStrokeWidth(classData.GetStrokeWidth())  
             self.SetFill(classData.GetFill())  
279          else:          else:
280              self.SetStroke(Color.None)              self.SetStroke(Color.None)
281              self.SetStrokeWidth(1)              self.SetStrokeWidth(1)
282              self.SetFill(Color.None)              self.SetFill(Color.None)
283    
         self.type = type  
         self.label = ""  
       
     def GetType(self):  
         return self.type  
   
284      def GetStroke(self):      def GetStroke(self):
285          return self.stroke          return self.stroke
286    
# Line 282  class ClassData: Line 292  class ClassData:
292          return self.stroke_width          return self.stroke_width
293    
294      def SetStrokeWidth(self, stroke_width):      def SetStrokeWidth(self, stroke_width):
295            assert(isinstance(stroke_width, IntType))
296          if (stroke_width < 1):          if (stroke_width < 1):
297              raise ValueError(_("stroke_width < 1"))              raise ValueError(_("stroke_width < 1"))
298    
# Line 294  class ClassData: Line 305  class ClassData:
305          assert(isinstance(fill, Color))          assert(isinstance(fill, Color))
306          self.fill = fill          self.fill = fill
307    
308    
309    class ClassGroup:
310    
311        def __init__(self, label = ""):
312            self.label = label
313    
314      def GetLabel(self):      def GetLabel(self):
315          return self.label          return self.label
316    
317      def SetLabel(self, label):      def SetLabel(self, label):
318          self.label = label          self.label = label
319    
320  class ClassDataDefault(ClassData):      def Matches(self, value):
321      def __init__(self, classData = None):          """This needs to be implemented by all subclasses."""
322          ClassData.__init__(self, classData, ClassData.DEFAULT)          pass
323    
324        def GetProperties(self, value):
325            """This needs to be implemented by all subclasses."""
326            pass
327    
328            
329  class ClassDataPoint(ClassData):  class ClassGroupSingleton(ClassGroup):
330    
331      def __init__(self, value = 0, classData = None):      def __init__(self, value = 0, prop = None, label = ""):
332          ClassData.__init__(self, classData, ClassData.POINT)          ClassGroup.__init__(self, label)
333    
334          self.value = value          self.SetValue(value)
335            self.SetProperties(prop)
336    
337        def __copy__(self):
338            return ClassGroupSingleton(self.value, self.prop, self.label)
339    
340      def GetValue(self):      def GetValue(self):
341          return self.value          return self.value
# Line 317  class ClassDataPoint(ClassData): Line 343  class ClassDataPoint(ClassData):
343      def SetValue(self, value):      def SetValue(self, value):
344          self.value = value          self.value = value
345    
346  class ClassDataRange(ClassData):      def Matches(self, value):
347            return self.value == value
348    
349      def __init__(self, min = 0, max = 1, classData = None):      def GetProperties(self, value = None):
350          ClassData.__init__(self, classData, ClassData.RANGE)          if value is None: return self.prop
351    
352          if min >= max:          if self.Matches(value):
353              raise ValueError(_("ClassDataRange: %i(min) >= %i(max)!") %              return self.prop
354                               (min, max))          else:
355                return None
356    
357        def SetProperties(self, prop):
358            if prop is None: prop = ClassGroupProperties()
359            assert(isinstance(prop, ClassGroupProperties))
360            self.prop = prop
361    
362    
363    class ClassGroupDefault(ClassGroupSingleton):
364        def __init__(self, prop = None, label = ""):
365            ClassGroupSingleton.__init__(self, 0, prop, label)
366    
367        def __copy__(self):
368            return ClassGroupDefault(self.prop, self.label)
369    
370        def GetProperties(self, value = None):
371            return self.prop
372    
373    class ClassGroupRange(ClassGroup):
374    
375        def __init__(self, min = 0, max = 1, prop = None, label = ""):
376            ClassGroup.__init__(self, label)
377    
378          self.SetRange(min, max)          self.SetRange(min, max)
379            self.SetProperties(prop)
380    
381        def __copy__(self):
382            return ClassGroupRange(self.min, self.max, self.prop, self.label)
383    
384      def GetMin(self):      def GetMin(self):
385          return self.min          return self.min
# Line 341  class ClassDataRange(ClassData): Line 394  class ClassDataRange(ClassData):
394          self.SetRange(self.min, max)          self.SetRange(self.min, max)
395    
396      def SetRange(self, min, max):      def SetRange(self, min, max):
         self.min = min  
         self.max = max  
397          if min >= max:          if min >= max:
398              raise ValueError(_("ClassDataRange: %i(min) >= %i(max)!") %              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %
399                               (min, max))                               (min, max))
400            self.min = min
401            self.max = max
402    
403      def GetRange(self):      def GetRange(self):
404          return (self.min, self.max)          return (self.min, self.max)
405    
406      def InRange(self, value):      def Matches(self, value):
407          return self.min <= value < self.max          return self.min <= value < self.max
408    
409  class ClassDataMap(ClassData):      def GetProperties(self, value):
410            if value is None: return self.prop
411    
412            if self.Matches(value):
413                return self.prop
414            else:
415                return None
416    
417        def SetProperties(self, prop):
418            if prop is None: prop = ClassGroupProperties()
419            assert(isinstance(prop, ClassGroupProperties))
420            self.prop = prop
421    
422    class ClassGroupMap(ClassGroup):
423    
424      FUNC_ID = "id"      FUNC_ID = "id"
425    
426      def __init__(self, map_type = FUNC_ID, func = None, classData = None):      def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
427          ClassData.__init__(self, classData, ClassData.MAP)          ClassGroup.__init__(self, prop)
428    
429          self.map_type = map_type          self.map_type = map_type
430          self.func = func          self.func = func

Legend:
Removed from v.428  
changed lines
  Added in v.436

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26