/[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 462 by jonathan, Wed Mar 5 18:17:17 2003 UTC revision 491 by jonathan, Mon Mar 10 10:44:42 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    import copy
27    
28  from types import *  from types import *
29    
30  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
# Line 33  from Thuban.Model.color import Color Line 35  from Thuban.Model.color import Color
35    
36  import Thuban.Model.layer  import Thuban.Model.layer
37    
   
38  # constants  # constants
39  RANGE_MIN  = 0  RANGE_MIN  = 0
40  RANGE_MAX  = 1  RANGE_MAX  = 1
# Line 58  class Classification: Line 59  class Classification:
59          self.field = None          self.field = None
60          self.fieldType = None          self.fieldType = None
61          self.groups = []          self.groups = []
         self.__sendMessages = False  
62    
         self.__ToggleMessages(False)  
63          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
64    
65          self.SetLayer(layer)          self.SetLayer(layer)
66          self.SetField(field)          self.SetField(field)
67    
         self.__ToggleMessages(True)  
   
68      def __iter__(self):      def __iter__(self):
69          return ClassIterator(self.groups)          return ClassIterator(self.groups)
70    
71      def __ToggleMessages(self, on):      def __SendNotification(self):
72          self.__sendMessages = on          """Notify the layer that this class has changed."""
73            if self.layer is not None:
74      def __SendMessage(self, message):              self.layer.ClassChanged()
         """Send the message 'message' to the parent layer."""  
         if self.__sendMessages and self.layer is not None:  
             self.layer.changed(message, self.layer)  
75            
76      def SetField(self, field = None):      def SetField(self, field):
77          """Set the name of the data table field to use.          """Set the name of the data table field to use.
78                    
79               If there is no layer then the field type is set to None,
80               otherwise the layer is queried to find the type of the
81               field data
82    
83             field -- if None then all values map to the default data             field -- if None then all values map to the default data
84          """          """
85    
86          if field == "":          if field == "":
87              field = None              field = None
88    
         self.field = field  
89    
90          if self.layer is not None:          if field is None:
91              fieldType = self.layer.GetFieldType(field)              if self.layer is not None:
92                    self.fieldType = None
93          else:          else:
94              fieldType = None              if self.layer is not None:
95                    fieldType = self.layer.GetFieldType(field)
96                    if fieldType is None:
97                        raise ValueError("'%s' was not found in the layer's table."
98                                         % self.field)
99    
100                    #
101                    # unfortunately we cannot call SetFieldType() because it
102                    # requires the layer to be None
103                    #
104                    self.fieldType = fieldType
105                    #self.SetFieldType(fieldType)
106    
107          self.SetFieldType(fieldType)          self.field = field
   
         # XXX: if fieldType comes back None then field isn't in the table!  
108    
109          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
110    
111      def GetField(self):      def GetField(self):
112          """Return the name of the field."""          """Return the name of the field."""
# Line 109  class Classification: Line 117  class Classification:
117          return self.fieldType          return self.fieldType
118    
119      def SetFieldType(self, type):      def SetFieldType(self, type):
120          self.fieldType = type          """Set the type of the field used by this classification.
121    
122      def SetLayer(self, layer):          A ValueError is raised if the owning layer is not None and
123          """Set the owning Layer of this classification."""          'type' is different from the current field type.
124            """
125    
126          if __debug__:          if type != self.fieldType:
127              if layer is not None:              if self.layer is not None:
128                  assert(isinstance(layer, Thuban.Model.layer.Layer))                  raise ValueError()
129                else:
130                    self.fieldType = type
131                    self.__SendNotification()
132    
133          self.layer = layer      def SetLayer(self, layer):
134          self.SetField(self.GetField()) # XXX: this sync's the fieldType          """Set the owning Layer of this classification.
135    
136               A ValueError exception will be thrown either the field or
137               field type mismatch the information in the layer's table.
138            """
139    
140          self.__SendMessage(LAYER_LEGEND_CHANGED)          if layer is None:
141                if self.layer is not None:
142                    l = self.layer
143                    self.layer = None
144                    l.SetClassification(None)
145            else:
146                assert(isinstance(layer, Thuban.Model.layer.Layer))
147    
148                # prevent infinite recursion when calling SetClassification()
149                if layer == self.layer:
150                    return
151                
152                old_layer = self.layer
153    
154                self.layer = layer
155    
156                try:
157                    self.SetField(self.GetField()) # this sync's the fieldType
158                except ValueError:
159                    self.layer = old_layer
160                    raise ValueError
161                else:
162                    self.layer.SetClassification(self)
163    
164      def GetLayer(self):      def GetLayer(self):
165          """Return the parent layer."""          """Return the parent layer."""
# Line 153  class Classification: Line 191  class Classification:
191          """          """
192          assert(isinstance(fill, Color))          assert(isinstance(fill, Color))
193          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
194          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
195                    
196      def GetDefaultFill(self):      def GetDefaultFill(self):
197          """Return the default fill color."""          """Return the default fill color."""
# Line 166  class Classification: Line 204  class Classification:
204          """          """
205          assert(isinstance(color, Color))          assert(isinstance(color, Color))
206          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
207          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
208                    
209      def GetDefaultLineColor(self):      def GetDefaultLineColor(self):
210          """Return the default line color."""          """Return the default line color."""
# Line 179  class Classification: Line 217  class Classification:
217          """          """
218          assert(isinstance(lineWidth, IntType))          assert(isinstance(lineWidth, IntType))
219          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
220          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
221                    
222      def GetDefaultLineWidth(self):      def GetDefaultLineWidth(self):
223          """Return the default line width."""          """Return the default line width."""
# Line 195  class Classification: Line 233  class Classification:
233    
234          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):
235              self.groups[0] = item              self.groups[0] = item
             #self.SetDefaultGroup(item)  
236          else:          else:
237              self.groups.append(item)              self.groups.append(item)
238    
239          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
240    
241      def GetGroup(self, value):      def GetGroup(self, value):
242          """Return the associated group, or the default group.          """Return the associated group, or the default group.
# Line 208  class Classification: Line 245  class Classification:
245             Classification.             Classification.
246    
247             value -- the value to classify. If there is no mapping,             value -- the value to classify. If there is no mapping,
248                      or value is None, return the default properties                      the field is None or value is None,
249                        return the default properties
250          """          """
251    
252          if self.field is not None and value is not None:          if self.GetField() is not None and value is not None:
253    
254              for i in range(1, len(self.groups)):              for i in range(1, len(self.groups)):
255                  group = self.groups[i]                  group = self.groups[i]
# Line 328  class ClassGroupProperties: Line 366  class ClassGroupProperties:
366    
367          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
368                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
369                   is created.                   is created such that: line color = Color.Black, line width = 1,
370                     and fill color = Color.None
371          """          """
372    
373          self.stroke = None          self.stroke = None
# Line 338  class ClassGroupProperties: Line 377  class ClassGroupProperties:
377          if props is not None:          if props is not None:
378              self.SetProperties(props)              self.SetProperties(props)
379          else:          else:
380              self.SetLineColor(Color.None)              self.SetLineColor(Color.Black)
381              self.SetLineWidth(1)              self.SetLineWidth(1)
382              self.SetFill(Color.None)              self.SetFill(Color.None)
383    
# Line 391  class ClassGroupProperties: Line 430  class ClassGroupProperties:
430          assert(isinstance(fill, Color))          assert(isinstance(fill, Color))
431          self.fill = fill          self.fill = fill
432    
433        def __eq__(self, other):
434            """Return true if 'props' has the same attributes as this class"""
435    
436            return isinstance(other, ClassGroupProperties)   \
437                and self.stroke      == other.GetLineColor() \
438                and self.strokeWidth == other.GetLineWidth() \
439                and self.fill        == other.GetFill()
440    
441        def __ne__(self, other):
442            return not self.__eq__(other)
443    
444        def __copy__(self):
445            return ClassGroupProperties(self)
446    
447  class ClassGroup:  class ClassGroup:
448      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
# Line 421  class ClassGroup: Line 473  class ClassGroup:
473      def Matches(self, value):      def Matches(self, value):
474          """Determines if this Group is associated with the given value.          """Determines if this Group is associated with the given value.
475    
476          Returns True or False. This needs to be implemented by all subclasses.          Returns False. This needs to be overridden by all subclasses.
477          """          """
478          pass          return False
479    
480      def GetProperties(self):      def GetProperties(self):
481          """Return the properties associated with the given value.          """Return the properties associated with the given value.
482    
483          This needs to be implemented by all subclasses.          Returns None. This needs to be overridden by all subclasses.
484          """          """
485          pass          return None
486    
487            
488  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
# Line 455  class ClassGroupSingleton(ClassGroup): Line 507  class ClassGroupSingleton(ClassGroup):
507          self.SetProperties(prop)          self.SetProperties(prop)
508    
509      def __copy__(self):      def __copy__(self):
510          return ClassGroupSingleton(self.value, self.prop, self.label)          return ClassGroupSingleton(self.GetValue(),
511                                       self.GetProperties(),
512                                       self.GetLabel())
513    
514        def __deepcopy__(self, memo):
515            return ClassGroupSingleton(copy.copy(self.GetValue()),
516                                       copy.copy(self.GetProperties()),
517                                       copy.copy(self.GetLabel()))
518    
519      def GetValue(self):      def GetValue(self):
520          """Return the associated value."""          """Return the associated value."""
# Line 488  class ClassGroupSingleton(ClassGroup): Line 547  class ClassGroupSingleton(ClassGroup):
547          assert(isinstance(prop, ClassGroupProperties))          assert(isinstance(prop, ClassGroupProperties))
548          self.prop = prop          self.prop = prop
549    
550        def __eq__(self, other):
551            return isinstance(other, ClassGroupSingleton) \
552                and self.GetProperties() == other.GetProperties() \
553                and self.GetValue() == other.GetValue()
554    
555        def __ne__(self, other):
556            return not self.__eq__(other)
557    
558  class ClassGroupDefault(ClassGroupSingleton):  class ClassGroupDefault(ClassGroup):
559      """The default Group. When values do not match any other      """The default Group. When values do not match any other
560         Group within a Classification, the properties from this         Group within a Classification, the properties from this
561         class are used."""         class are used."""
# Line 503  class ClassGroupDefault(ClassGroupSingle Line 569  class ClassGroupDefault(ClassGroupSingle
569          label -- a label for this group.          label -- a label for this group.
570          """          """
571    
572          ClassGroupSingleton.__init__(self, 0, prop, label)          ClassGroup.__init__(self, label)
573            self.SetProperties(prop)
574    
575      def __copy__(self):      def __copy__(self):
576          return ClassGroupDefault(self.prop, self.label)          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
577    
578        def __deepcopy__(self, memo):
579            return ClassGroupDefault(copy.copy(self.GetProperties()),
580                                     copy.copy(self.GetLabel()))
581    
582        def Matches(self, value):
583            return True
584    
585      def GetProperties(self):      def GetProperties(self):
586          """Return the Properties associated with this Group."""          """Return the Properties associated with this Group."""
587          return self.prop          return self.prop
588    
589        def SetProperties(self, prop):
590            """Set the properties associated with this Group.
591    
592            prop -- a ClassGroupProperties object. if prop is None,
593                    a default set of properties is created.
594            """
595    
596            if prop is None: prop = ClassGroupProperties()
597            assert(isinstance(prop, ClassGroupProperties))
598            self.prop = prop
599    
600        def __eq__(self, other):
601            return isinstance(other, ClassGroupDefault) \
602                and self.GetProperties() == other.GetProperties()
603    
604        def __ne__(self, other):
605            return not self.__eq__(other)
606    
607  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
608      """A Group that represents a range of values that map to the same      """A Group that represents a range of values that map to the same
609         set of properties."""         set of properties."""
# Line 540  class ClassGroupRange(ClassGroup): Line 632  class ClassGroupRange(ClassGroup):
632          self.SetProperties(prop)          self.SetProperties(prop)
633    
634      def __copy__(self):      def __copy__(self):
635          return ClassGroupRange(self.min, self.max, self.prop, self.label)          return ClassGroupRange(self.GetMin(),
636                                   self.GetMax(),
637                                   self.GetProperties(),
638                                   self.GetLabel())
639    
640        def __deepcopy__(self, memo):
641            return ClassGroupRange(copy.copy(self.GetMin()),
642                                   copy.copy(self.GetMax()),
643                                   copy.copy(self.GetProperties()),
644                                   copy.copy(self.GetLabel()))
645    
646      def GetMin(self):      def GetMin(self):
647          """Return the range's minimum value."""          """Return the range's minimum value."""
# Line 608  class ClassGroupRange(ClassGroup): Line 709  class ClassGroupRange(ClassGroup):
709          assert(isinstance(prop, ClassGroupProperties))          assert(isinstance(prop, ClassGroupProperties))
710          self.prop = prop          self.prop = prop
711    
712        def __eq__(self, other):
713            return isinstance(other, ClassGroupRange) \
714                and self.GetProperties() == other.GetProperties() \
715                and self.GetRange() == other.GetRange()
716    
717        def __ne__(self, other):
718            return not self.__eq__(other)
719    
720  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
721      """Currently, this class is not used."""      """Currently, this class is not used."""
722    

Legend:
Removed from v.462  
changed lines
  Added in v.491

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26