/[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 689 by jonathan, Wed Apr 16 13:47:07 2003 UTC revision 1351 by jonathan, Tue Jul 1 16:17:02 2003 UTC
# Line 20  See the description of FindGroup() for m Line 20  See the description of FindGroup() for m
20  on the mapping algorithm.  on the mapping algorithm.
21  """  """
22        
23  # fix for people using python2.1  import copy, operator, types
 from __future__ import nested_scopes  
   
 import copy  
24    
25  from Thuban import _  from Thuban import _
26    
 from types import *  
   
27  from messages import \  from messages import \
28      LAYER_PROJECTION_CHANGED, \      LAYER_PROJECTION_CHANGED, \
29      LAYER_LEGEND_CHANGED, \      LAYER_LEGEND_CHANGED, \
30      LAYER_VISIBILITY_CHANGED      LAYER_VISIBILITY_CHANGED
31    
32  from Thuban.Model.color import Color  from Thuban.Model.color import Color, Transparent, Black
33    from Thuban.Model.range import Range
34    
35  import Thuban.Model.layer  import Thuban.Model.layer
36    
# Line 60  class Classification: Line 56  class Classification:
56          self.fieldType = None          self.fieldType = None
57          self.__groups = []          self.__groups = []
58    
         self.__setLayerLock = False  
   
59          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
60    
61          self.SetLayer(layer)          self.SetFieldInfo(field, None)
62          self.SetField(field)  
63            self._set_layer(layer)
64    
65      def __iter__(self):      def __iter__(self):
66          return ClassIterator(self.__groups)          return ClassIterator(self.__groups)
# Line 88  class Classification: Line 83  class Classification:
83          if self.layer is not None:          if self.layer is not None:
84              self.layer.ClassChanged()              self.layer.ClassChanged()
85            
     def SetField(self, field):  
         """Set the name of the data table field to use.  
           
         If there is no layer then the field type is set to None,  
         otherwise the layer is queried to find the type of the  
         field data  
   
         field -- if None then all values map to the default data  
         """  
   
         if field == "":  
             field = None  
   
   
         if field is None:  
             if self.layer is not None:  
                 self.fieldType = None  
         else:  
             if self.layer is not None:  
                 fieldType = self.layer.GetFieldType(field)  
                 if fieldType is None:  
                     raise ValueError("'%s' was not found in the layer's table."  
                                      % self.field)  
   
                 #  
                 # unfortunately we cannot call SetFieldType() because it  
                 # requires the layer to be None  
                 #  
                 self.fieldType = fieldType  
                 #self.SetFieldType(fieldType)  
   
         self.field = field  
   
         self.__SendNotification()  
   
86      def GetField(self):      def GetField(self):
87          """Return the name of the field."""          """Return the name of the field."""
88          return self.field          return self.field
# Line 131  class Classification: Line 91  class Classification:
91          """Return the field type."""          """Return the field type."""
92          return self.fieldType          return self.fieldType
93    
94      def SetFieldType(self, type):      def SetFieldInfo(self, name, type):
95          """Set the type of the field used by this classification.          """Set the classified field name to 'name' and it's field
96            type to 'type'
97    
98            If this classification has an owning layer a ValueError
99            exception will be thrown either the field or field type
100            mismatch the information in the layer's table.
101    
102            If the field info is successful set and the class has
103            an owning layer, the layer will be informed that the
104            classification has changed.
105            """
106    
107            if name == "":
108                name = None
109    
110            if self.layer is None:
111                self.field = name
112                self.fieldType = type
113            elif name is None:
114                self.field = None
115                self.fieldType = None
116            else:
117                #
118                # verify that the field exists in the layer and that
119                # the type is correct.
120                #
121                fieldType = self.layer.GetFieldType(name)
122                if fieldType is None:
123                    raise ValueError("'%s' was not found in the layer's table."
124                                     % self.field)
125                elif type is not None and fieldType != type:
126                    raise ValueError("type doesn't match layer's field type for %s"
127                                     % self.field)
128    
129          A ValueError is raised if the owning layer is not None and              self.field = name
130          'type' is different from the current field type.              self.fieldType = fieldType
         """  
131    
132          if type != self.fieldType:          self.__SendNotification()
             if self.layer is not None:  
                 raise ValueError()  
             else:  
                 self.fieldType = type  
                 self.__SendNotification()  
133    
134      def SetLayer(self, layer):      def _set_layer(self, layer):
135          """Set the owning Layer of this classification.          """Internal: Set the owning Layer of this classification.
136    
137          A ValueError exception will be thrown either the field or          A ValueError exception will be thrown either the field or
138          field type mismatch the information in the layer's table.          field type mismatch the information in the layer's table.
         """  
   
         # prevent infinite recursion when calling SetClassification()  
         if self.__setLayerLock: return  
139    
140          self.__setLayerLock = True          If the layer is successful set, the layer will be informed
141            that the classification has changed.
142            """
143    
144          if layer is None:          if layer is None:
145              if self.layer is not None:              self.layer = None
                 l = self.layer  
                 self.layer = None  
                 l.SetClassification(None)  
146          else:          else:
             assert isinstance(layer, Thuban.Model.layer.Layer)  
   
147              old_layer = self.layer              old_layer = self.layer
   
148              self.layer = layer              self.layer = layer
149    
150              try:              try:
151                  self.SetField(self.GetField()) # this sync's the fieldType                  # this sync's the fieldType
152                    # and sends a notification to the layer
153                    self.SetFieldInfo(self.GetField(), None)
154              except ValueError:              except ValueError:
155                  self.layer = old_layer                  self.layer = old_layer
                 self.__setLayerLock = False  
156                  raise ValueError                  raise ValueError
             else:  
                 self.layer.SetClassification(self)  
   
         self.__setLayerLock = False  
157    
158      def GetLayer(self):      def GetLayer(self):
159          """Return the parent layer."""          """Return the parent layer."""
160          return self.layer          return self.layer
161    
   
162      #      #
163      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
164      # some backward compatibility. they should be considered      # some backward compatibility. they should be considered
# Line 196  class Classification: Line 170  class Classification:
170    
171          fill -- a Color object.          fill -- a Color object.
172          """          """
         assert isinstance(fill, Color)  
173          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
174          self.__SendNotification()          self.__SendNotification()
175                    
# Line 209  class Classification: Line 182  class Classification:
182    
183          color -- a Color object.          color -- a Color object.
184          """          """
         assert isinstance(color, Color)  
185          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
186          self.__SendNotification()          self.__SendNotification()
187                    
# Line 222  class Classification: Line 194  class Classification:
194    
195          lineWidth -- an integer > 0.          lineWidth -- an integer > 0.
196          """          """
197          assert isinstance(lineWidth, IntType)          assert isinstance(lineWidth, types.IntType)
198          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
199          self.__SendNotification()          self.__SendNotification()
200                    
# Line 327  class Classification: Line 299  class Classification:
299          items = []          items = []
300    
301          def build_color_item(text, color):          def build_color_item(text, color):
302              if color is Color.Transparent:              if color is Transparent:
303                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
304    
305              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 424  class ClassGroupProperties: Line 396  class ClassGroupProperties:
396    
397          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
398                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
399                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Black, line width = 1,
400                   and fill color = Color.Transparent                   and fill color = Transparent
401          """          """
402    
403          #self.stroke = None          #self.stroke = None
# Line 435  class ClassGroupProperties: Line 407  class ClassGroupProperties:
407          if props is not None:          if props is not None:
408              self.SetProperties(props)              self.SetProperties(props)
409          else:          else:
410              self.SetLineColor(Color.Black)              self.SetLineColor(Black)
411              self.SetLineWidth(1)              self.SetLineWidth(1)
412              self.SetFill(Color.Transparent)              self.SetFill(Transparent)
413    
414      def SetProperties(self, props):      def SetProperties(self, props):
415          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
# Line 457  class ClassGroupProperties: Line 429  class ClassGroupProperties:
429          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
430          """          """
431    
         assert isinstance(color, Color)  
432          self.__stroke = color          self.__stroke = color
433    
434      def GetLineWidth(self):      def GetLineWidth(self):
# Line 469  class ClassGroupProperties: Line 440  class ClassGroupProperties:
440    
441          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
442          """          """
443          assert isinstance(lineWidth, IntType)          assert isinstance(lineWidth, types.IntType)
444          if (lineWidth < 1):          if (lineWidth < 1):
445              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
446    
# Line 485  class ClassGroupProperties: Line 456  class ClassGroupProperties:
456          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
457          """          """
458    
         assert isinstance(fill, Color)  
459          self.__fill = fill          self.__fill = fill
460    
461      def __eq__(self, other):      def __eq__(self, other):
# Line 542  class ClassGroup: Line 512  class ClassGroup:
512          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
513                   not be None.                   not be None.
514          """          """
515          assert isinstance(label, StringTypes)          assert isinstance(label, types.StringTypes)
516          self.label = label          self.label = label
517    
518      def GetDisplayText(self):      def GetDisplayText(self):
# Line 706  class ClassGroupRange(ClassGroup): Line 676  class ClassGroupRange(ClassGroup):
676    
677          ClassGroup.__init__(self, label, props, group)          ClassGroup.__init__(self, label, props, group)
678    
679          self.__min = self.__max = 0          #self.__min = self.__max = 0
680            #self.__range = Range("[" + repr(float(min)) + ";" +
681                                       #repr(float(max)) + "[")
682          self.SetRange(min, max)          self.SetRange(min, max)
683    
684      def __copy__(self):      def __copy__(self):
685          return ClassGroupRange(self.GetMin(),          return ClassGroupRange(min = self.__range,
686                                 self.GetMax(),                                 max = None,
687                                 self.GetProperties(),                                 props = self.GetProperties(),
688                                 self.GetLabel())                                 label = self.GetLabel())
689    
690      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
691          return ClassGroupRange(copy.copy(self.GetMin()),          return ClassGroupRange(min = copy.copy(self.__range),
692                                 copy.copy(self.GetMax()),                                 max = copy.copy(self.GetMax()),
693                                 group = self)                                 group = self)
694    
695      def GetMin(self):      def GetMin(self):
696          """Return the range's minimum value."""          """Return the range's minimum value."""
697          return self.__min          return self.__range.GetRange()[1]
698    
699      def SetMin(self, min):      def SetMin(self, min):
700          """Set the range's minimum value.          """Set the range's minimum value.
# Line 732  class ClassGroupRange(ClassGroup): Line 703  class ClassGroupRange(ClassGroup):
703                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
704          """          """
705            
706          self.SetRange(min, self.__max)          self.SetRange(min, self.__range.GetRange()[2])
707    
708      def GetMax(self):      def GetMax(self):
709          """Return the range's maximum value."""          """Return the range's maximum value."""
710          return self.__max          return self.__range.GetRange()[2]
711    
712      def SetMax(self, max):      def SetMax(self, max):
713          """Set the range's maximum value.          """Set the range's maximum value.
# Line 744  class ClassGroupRange(ClassGroup): Line 715  class ClassGroupRange(ClassGroup):
715          max -- the new maximum. Note that this must be greater than the current          max -- the new maximum. Note that this must be greater than the current
716                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
717          """          """
718          self.SetRange(self.__min, max)          self.SetRange(self.__range.GetRange()[1], max)
719    
720      def SetRange(self, min, max):      def SetRange(self, min, max = None):
721          """Set a new range.          """Set a new range.
722    
723          Note that min must be strictly less than max.          Note that min must be strictly less than max.
# Line 755  class ClassGroupRange(ClassGroup): Line 726  class ClassGroupRange(ClassGroup):
726          min -- the new maximum value          min -- the new maximum value
727          """          """
728    
729          if min >= max:          if isinstance(min, Range):
730              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = min
731                               (min, max))          else:
732          self.__min = min              if max is None:
733          self.__max = max                  raise ValueError()
734    
735                self.__range = Range(("[", min, max, "["))
736    
737      def GetRange(self):      def GetRange(self):
738          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
739          return (self.__min, self.__max)          #return (self.__min, self.__max)
740            return self.__range.string(self.__range.GetRange())
741    
742      def Matches(self, value):      def Matches(self, value):
743          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
# Line 771  class ClassGroupRange(ClassGroup): Line 745  class ClassGroupRange(ClassGroup):
745          The following check is used: min <= value < max.          The following check is used: min <= value < max.
746          """          """
747    
748          return self.__min <= value < self.__max          return operator.contains(self.__range, value)
749            #return self.__min <= value < self.__max
750    
751      def GetDisplayText(self):      def GetDisplayText(self):
752          label = self.GetLabel()          label = self.GetLabel()
753    
754          if label != "": return label          if label != "": return label
755    
756          return _("%s - %s") % (self.GetMin(), self.GetMax())          #return _("%s - %s") % (self.GetMin(), self.GetMax())
757            #return repr(self.__range)
758            return self.__range.string(self.__range.GetRange())
759    
760      def __eq__(self, other):      def __eq__(self, other):
761          return ClassGroup.__eq__(self, other) \          return ClassGroup.__eq__(self, other) \
762              and isinstance(other, ClassGroupRange) \              and isinstance(other, ClassGroupRange) \
763              and self.__min == other.__min \              and self.__range == other.__range
764              and self.__max == other.__max              #and self.__min == other.__min \
765                #and self.__max == other.__max
766    
767      def __repr__(self):      def __repr__(self):
768          return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \          return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
769                 ClassGroup.__repr__(self) + ")"          #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
770                   #ClassGroup.__repr__(self) + ")"
771    
772  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
773      """Currently, this class is not used."""      """Currently, this class is not used."""

Legend:
Removed from v.689  
changed lines
  Added in v.1351

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26