/[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 371 by jonathan, Mon Jan 27 13:49:39 2003 UTC revision 1176 by jonathan, Thu Jun 12 15:46:22 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4  #  #
# Line 13  to data. This mapping can be specified i Line 13  to data. This mapping can be specified i
13  First, specific values can be associated with data.  First, specific values can be associated with data.
14  Second, ranges can be associated with data such that if  Second, ranges can be associated with data such that if
15  an input value falls with a range that data is returned.  an input value falls with a range that data is returned.
16  If no mapping can be found then a NullData data will  If no mapping can be found then default data will
17  be returned. Input values must be hashable objects  be returned. Input values must be hashable objects
18    
19  See the description of getProperties() for more information  See the description of FindGroup() for more information
20  on the mapping algorithm.  on the mapping algorithm.
21  """  """
22        
23  # constants  # fix for people using python2.1
24  RANGE_MIN  = 0  from __future__ import nested_scopes
 RANGE_MAX  = 1  
 RANGE_DATA = 2  
25    
26  class Classification:  import copy, operator
27    
28    from Thuban import _
29    
30    import types
31    
32    from messages import \
33        LAYER_PROJECTION_CHANGED, \
34        LAYER_LEGEND_CHANGED, \
35        LAYER_VISIBILITY_CHANGED
36    
37    from Thuban.Model.color import Color
38    from Thuban.Model.range import Range
39    
40    import Thuban.Model.layer
41    
42    class Classification:
43        """Encapsulates the classification of layer.
44        
45        The Classification divides some kind of data into Groups which
46        are associated with properties. Later the properties can be
47        retrieved by matching data values to the appropriate group.
48        """
49    
50      def __init__(self, field = None):      def __init__(self, layer = None, field = None):
51          """Initialize a classification.          """Initialize a classification.
52    
53             field -- the name of the data table field that          layer -- the Layer object who owns this classification
54                      is to be used to classify layer properties  
55            field -- the name of the data table field that
56                     is to be used to classify layer properties
57          """          """
58    
59          self.__points = {}          self.layer = None
60          self.__ranges = []          self.field = None
61          self.setField(field)          self.fieldType = None
62          self.setNull(None)          self.__groups = []
63            
64      def setField(self, field):          self.__setLayerLock = False
65    
66            self.SetDefaultGroup(ClassGroupDefault())
67    
68            self.SetLayer(layer)
69            self.SetField(field)
70    
71        def __iter__(self):
72            return ClassIterator(self.__groups)
73    
74        def __deepcopy__(self, memo):
75            clazz = Classification()
76    
77            # note: the only thing that isn't copied is the layer reference
78            clazz.field = self.field
79            clazz.fieldType = self.fieldType
80            clazz.__groups[0] = copy.deepcopy(self.__groups[0])
81    
82            for i in range(1, len(self.__groups)):
83                clazz.__groups.append(copy.deepcopy(self.__groups[i]))
84    
85            return clazz
86    
87        def __SendNotification(self):
88            """Notify the layer that this class has changed."""
89            if self.layer is not None:
90                self.layer.ClassChanged()
91        
92        def SetField(self, field):
93          """Set the name of the data table field to use.          """Set the name of the data table field to use.
94                    
95             field -- if None then all values map to NullData          If there is no layer then the field type is set to None,
96            otherwise the layer is queried to find the type of the
97            field data
98    
99            field -- if None then all values map to the default data
100          """          """
101    
102            if field == "":
103                field = None
104    
105    
106            if field is None:
107                if self.layer is not None:
108                    self.fieldType = None
109            else:
110                if self.layer is not None:
111                    fieldType = self.layer.GetFieldType(field)
112                    if fieldType is None:
113                        raise ValueError("'%s' was not found in the layer's table."
114                                         % self.field)
115    
116                    #
117                    # unfortunately we cannot call SetFieldType() because it
118                    # requires the layer to be None
119                    #
120                    self.fieldType = fieldType
121                    #self.SetFieldType(fieldType)
122    
123          self.field = field          self.field = field
124    
125      def setNull(self, data):          self.__SendNotification()
126          """Set the data to be used when a value can't be classified.  
127        def GetField(self):
128            """Return the name of the field."""
129            return self.field
130    
131        def GetFieldType(self):
132            """Return the field type."""
133            return self.fieldType
134    
135             data -- data that the value maps to. See class description.      def SetFieldType(self, type):
136            """Set the type of the field used by this classification.
137    
138            A ValueError is raised if the owning layer is not None and
139            'type' is different from the current field type.
140            """
141    
142            if type != self.fieldType:
143                if self.layer is not None:
144                    raise ValueError()
145                else:
146                    self.fieldType = type
147                    self.__SendNotification()
148    
149        def SetLayer(self, layer):
150            """Set the owning Layer of this classification.
151    
152            A ValueError exception will be thrown either the field or
153            field type mismatch the information in the layer's table.
154          """          """
155    
156          self.NullData = data          # prevent infinite recursion when calling SetClassification()
157            if self.__setLayerLock: return
158    
159      def addRange(self, min, max, data):          self.__setLayerLock = True
         """Add a new range to the classification.  
160    
161             A range allows a value to be classified if it falls between          if layer is None:
162             min and max. Specifically, min <= value < max              if self.layer is not None:
163                            l = self.layer
164             min -- the lower bound.                  self.layer = None
165                    l.SetClassification(None)
166            else:
167                assert isinstance(layer, Thuban.Model.layer.Layer)
168    
169                old_layer = self.layer
170    
171                self.layer = layer
172    
173                try:
174                    self.SetField(self.GetField()) # this sync's the fieldType
175                except ValueError:
176                    self.layer = old_layer
177                    self.__setLayerLock = False
178                    raise ValueError
179                else:
180                    self.layer.SetClassification(self)
181    
182            self.__setLayerLock = False
183    
184        def GetLayer(self):
185            """Return the parent layer."""
186            return self.layer
187    
188    
189        #
190        # these SetDefault* methods are really only provided for
191        # some backward compatibility. they should be considered
192        # for removal once all the classification code is finished.
193        #
194    
195        def SetDefaultFill(self, fill):
196            """Set the default fill color.
197    
198            fill -- a Color object.
199            """
200            self.GetDefaultGroup().GetProperties().SetFill(fill)
201            self.__SendNotification()
202            
203        def GetDefaultFill(self):
204            """Return the default fill color."""
205            return self.GetDefaultGroup().GetProperties().GetFill()
206            
207        def SetDefaultLineColor(self, color):
208            """Set the default line color.
209    
210            color -- a Color object.
211            """
212            self.GetDefaultGroup().GetProperties().SetLineColor(color)
213            self.__SendNotification()
214            
215        def GetDefaultLineColor(self):
216            """Return the default line color."""
217            return self.GetDefaultGroup().GetProperties().GetLineColor()
218            
219        def SetDefaultLineWidth(self, lineWidth):
220            """Set the default line width.
221    
222            lineWidth -- an integer > 0.
223            """
224            assert isinstance(lineWidth, types.IntType)
225            self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
226            self.__SendNotification()
227            
228        def GetDefaultLineWidth(self):
229            """Return the default line width."""
230            return self.GetDefaultGroup().GetProperties().GetLineWidth()
231            
232    
233        #
234        # The methods that manipulate self.__groups have to be kept in
235        # sync. We store the default group in index 0 to make it
236        # convienent to iterate over the classification's groups, but
237        # from the user's perspective the first (non-default) group is
238        # at index 0 and the DefaultGroup is a special entity.
239        #
240    
241        def SetDefaultGroup(self, group):
242            """Set the group to be used when a value can't be classified.
243    
244            group -- group that the value maps to.
245            """
246    
247            assert isinstance(group, ClassGroupDefault)
248            if len(self.__groups) > 0:
249                self.__groups[0] = group
250            else:
251                self.__groups.append(group)
252    
253        def GetDefaultGroup(self):
254            """Return the default group."""
255            return self.__groups[0]
256    
257             max -- the upper bound.      def AppendGroup(self, item):
258            """Append a new ClassGroup item to the classification.
259    
260             data -- data that the value maps to. See class description.          item -- this must be a valid ClassGroup object
261          """          """
262    
263          if min >= max:          self.InsertGroup(self.GetNumGroups(), item)
264              raise ValueError("Range minimum >= maximum!")  
265          self.__ranges.append([min, max, data])      def InsertGroup(self, index, group):
266            
267            assert isinstance(group, ClassGroup)
268    
269            self.__groups.insert(index + 1, group)
270    
271            self.__SendNotification()
272    
273      def addPoint(self, value, data):      def RemoveGroup(self, index):
274          """Associate a single value with data.          return self.__groups.pop(index + 1)
275    
276             When this value is to be classified data will be returned.      def ReplaceGroup(self, index, group):
277            assert isinstance(group, ClassGroup)
278    
279             value -- classification value.          self.__groups[index + 1] = group
280    
281             data  -- data that the value maps to. See class description.          self.__SendNotification()
282    
283        def GetGroup(self, index):
284            return self.__groups[index + 1]
285    
286        def GetNumGroups(self):
287            """Return the number of non-default groups in the classification."""
288            return len(self.__groups) - 1
289    
290    
291        def FindGroup(self, value):
292            """Return the associated group, or the default group.
293    
294            Groups are checked in the order the were added to the
295            Classification.
296    
297            value -- the value to classify. If there is no mapping,
298                     the field is None or value is None,
299                     return the default properties
300          """          """
301    
302          self.__points[value] = data          if self.GetField() is not None and value is not None:
303    
304      def getProperties(self, value):              for i in range(1, len(self.__groups)):
305          """Return the associated data, or the NullData.                  group = self.__groups[i]
306                    if group.Matches(value):
307                        return group
308    
309            return self.GetDefaultGroup()
310    
311        def GetProperties(self, value):
312            """Return the properties associated with the given value.
313          
314            Use this function rather than Classification.FindGroup().GetProperties()
315            since the returned group may be a ClassGroupMap which doesn't support
316            a call to GetProperties().
317            """
318    
319            group = self.FindGroup(value)
320            if isinstance(group, ClassGroupMap):
321                return group.GetPropertiesFromValue(value)
322            else:
323                return group.GetProperties()
324    
325        def TreeInfo(self):
326            items = []
327    
328            def build_color_item(text, color):
329                if color is Color.Transparent:
330                    return ("%s: %s" % (text, _("None")), None)
331    
332                return ("%s: (%.3f, %.3f, %.3f)" %
333                        (text, color.red, color.green, color.blue),
334                        color)
335    
336            def build_item(group, string):
337                label = group.GetLabel()
338                if label == "":
339                    label = string
340                else:
341                    label += " (%s)" % string
342    
343                props = group.GetProperties()
344                i = []
345                v = props.GetLineColor()
346                i.append(build_color_item(_("Line Color"), v))
347                v = props.GetLineWidth()
348                i.append(_("Line Width: %s") % v)
349                v = props.GetFill()
350                i.append(build_color_item(_("Fill"), v))
351                return (label, i)
352    
353            for p in self:
354                items.append(build_item(p, p.GetDisplayText()))
355    
356    #           if isinstance(p, ClassGroupDefault):
357    #               items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
358    #           elif isinstance(p, ClassGroupSingleton):
359    #               items.append(build_item(p, str(p.GetValue())))
360    #           elif isinstance(p, ClassGroupRange):
361    #               items.append(build_item(p, "%s - %s" %
362    #                                          (p.GetMin(), p.GetMax())))
363    
364            return (_("Classification"), items)
365    
366    class ClassIterator:
367        """Allows the Groups in a Classifcation to be interated over.
368    
369        The items are returned in the following order:
370            default data, singletons, ranges, maps
371        """
372    
373             The following search technique is used:      def __init__(self, data): #default, points, ranges, maps):
374                 (1) if the field is None, return NullData          """Constructor.
                (2) check if the value exists as a single value  
                (3) check if the value falls within a range. Ranges  
                    are checked in the order they were added to  
                    the classification.  
375    
376             value -- the value to classify. If there is no mapping          default -- the default group
377                      return the NullData (which may be None)  
378            points -- a list of singleton groups
379    
380            ranges -- a list of range groups
381    
382            maps -- a list of map groups
383            """
384    
385            self.data = data #[default, points, ranges, maps]
386            self.data_index = 0
387            #self.data_iter = iter(self.data)
388            #self.iter = None
389    
390        def __iter__(self):
391            return self
392    
393        def next(self):
394            """Return the next item."""
395    
396            if self.data_index >= len(self.data):
397                raise StopIteration
398            else:
399                d = self.data[self.data_index]
400                self.data_index += 1
401                return d
402            
403    #       if self.iter is None:
404    #           try:
405    #               self.data_item = self.data_iter.next()
406    #               self.iter = iter(self.data_item)
407    #           except TypeError:
408    #               return self.data_item
409    
410    #       try:
411    #           return self.iter.next()
412    #       except StopIteration:
413    #           self.iter = None
414    #           return self.next()
415          
416    class ClassGroupProperties:
417        """Represents the properties of a single Classification Group.
418      
419        These are used when rendering a layer."""
420    
421        def __init__(self, props = None):
422            """Constructor.
423    
424            props -- a ClassGroupProperties object. The class is copied if
425                     prop is not None. Otherwise, a default set of properties
426                     is created such that: line color = Color.Black, line width = 1,
427                     and fill color = Color.Transparent
428          """          """
429    
430          if self.field is not None:          #self.stroke = None
431              #          #self.strokeWidth = 0
432              # first check the discrete values          #self.fill = None
433              #  
434              if self.__points.has_key(value):          if props is not None:
435                  return self.__points[value]              self.SetProperties(props)
436            else:
437                self.SetLineColor(Color.Black)
438                self.SetLineWidth(1)
439                self.SetFill(Color.Transparent)
440    
441        def SetProperties(self, props):
442            """Set this class's properties to those in class props."""
443    
444            assert isinstance(props, ClassGroupProperties)
445            self.SetLineColor(props.GetLineColor())
446            self.SetLineWidth(props.GetLineWidth())
447            self.SetFill(props.GetFill())
448            
449        def GetLineColor(self):
450            """Return the line color as a Color object."""
451            return self.__stroke
452    
453        def SetLineColor(self, color):
454            """Set the line color.
455    
456            color -- the color of the line. This must be a Color object.
457            """
458    
459            self.__stroke = color
460    
461        def GetLineWidth(self):
462            """Return the line width."""
463            return self.__strokeWidth
464    
465        def SetLineWidth(self, lineWidth):
466            """Set the line width.
467    
468            lineWidth -- the new line width. This must be > 0.
469            """
470            assert isinstance(lineWidth, types.IntType)
471            if (lineWidth < 1):
472                raise ValueError(_("lineWidth < 1"))
473    
474            self.__strokeWidth = lineWidth
475    
476        def GetFill(self):
477            """Return the fill color as a Color object."""
478            return self.__fill
479    
480        def SetFill(self, fill):
481            """Set the fill color.
482    
483            fill -- the color of the fill. This must be a Color object.
484            """
485    
486            self.__fill = fill
487    
488        def __eq__(self, other):
489            """Return true if 'props' has the same attributes as this class"""
490    
491            #
492            # using 'is' over '==' results in a huge performance gain
493            # in the renderer
494            #
495            return isinstance(other, ClassGroupProperties)   \
496                and (self.__stroke is other.__stroke or      \
497                     self.__stroke == other.__stroke)        \
498                and (self.__fill is other.__fill or          \
499                     self.__fill == other.__fill)            \
500                and self.__strokeWidth == other.__strokeWidth
501    
502        def __ne__(self, other):
503            return not self.__eq__(other)
504    
505        def __copy__(self):
506            return ClassGroupProperties(self)
507    
508        def __deepcopy__(self):
509            return ClassGroupProperties(self)
510    
511        def __repr__(self):
512            return repr((self.__stroke, self.__strokeWidth, self.__fill))
513    
514    class ClassGroup:
515        """A base class for all Groups within a Classification"""
516    
517        def __init__(self, label = "", props = None, group = None):
518            """Constructor.
519    
520            label -- A string representing the Group's label
521            """
522    
523            if group is not None:
524                self.SetLabel(copy.copy(group.GetLabel()))
525                self.SetProperties(copy.copy(group.GetProperties()))
526                self.SetVisible(group.IsVisible())
527            else:
528                self.SetLabel(label)
529                self.SetProperties(props)
530                self.SetVisible(True)
531    
532        def GetLabel(self):
533            """Return the Group's label."""
534            return self.label
535    
536        def SetLabel(self, label):
537            """Set the Group's label.
538    
539            label -- a string representing the Group's label. This must
540                     not be None.
541            """
542            assert isinstance(label, types.StringTypes)
543            self.label = label
544    
545        def GetDisplayText(self):
546            assert False, "GetDisplay must be overridden by subclass!"
547            return ""
548    
549        def Matches(self, value):
550            """Determines if this Group is associated with the given value.
551    
552            Returns False. This needs to be overridden by all subclasses.
553            """
554            assert False, "GetMatches must be overridden by subclass!"
555            return False
556    
557        def GetProperties(self):
558            """Return the properties associated with the given value."""
559    
560            return self.prop
561    
562        def SetProperties(self, prop):
563            """Set the properties associated with this Group.
564    
565            prop -- a ClassGroupProperties object. if prop is None,
566                    a default set of properties is created.
567            """
568    
569            if prop is None: prop = ClassGroupProperties()
570            assert isinstance(prop, ClassGroupProperties)
571            self.prop = prop
572    
573        def IsVisible(self):
574            return self.visible
575    
576        def SetVisible(self, visible):
577            self.visible = visible
578    
579        def __eq__(self, other):
580            return isinstance(other, ClassGroup) \
581                and self.label == other.label \
582                and self.GetProperties() == other.GetProperties()
583    
584        def __ne__(self, other):
585            return not self.__eq__(other)
586    
587        def __repr__(self):
588            return repr(self.label) + ", " + repr(self.GetProperties())
589        
590    class ClassGroupSingleton(ClassGroup):
591        """A Group that is associated with a single value."""
592    
593        def __init__(self, value = 0, props = None, label = "", group = None):
594            """Constructor.
595    
596            value -- the associated value.
597    
598            prop -- a ClassGroupProperites object. If prop is None a default
599                     set of properties is created.
600    
601            label -- a label for this group.
602            """
603            ClassGroup.__init__(self, label, props, group)
604    
605            self.SetValue(value)
606    
607        def __copy__(self):
608            return ClassGroupSingleton(self.GetValue(),
609                                       self.GetProperties(),
610                                       self.GetLabel())
611    
612        def __deepcopy__(self, memo):
613            return ClassGroupSingleton(self.GetValue(), group = self)
614    
615        def GetValue(self):
616            """Return the associated value."""
617            return self.__value
618    
619        def SetValue(self, value):
620            """Associate this Group with the given value."""
621            self.__value = value
622    
623        def Matches(self, value):
624            """Determine if the given value matches the associated Group value."""
625    
626            """Returns True if the value matches, False otherwise."""
627    
628            return self.__value == value
629    
630        def GetDisplayText(self):
631            label = self.GetLabel()
632    
633            if label != "": return label
634    
635            return str(self.GetValue())
636    
637        def __eq__(self, other):
638            return ClassGroup.__eq__(self, other) \
639                and isinstance(other, ClassGroupSingleton) \
640                and self.__value == other.__value
641    
642        def __repr__(self):
643            return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
644    
645    class ClassGroupDefault(ClassGroup):
646        """The default Group. When values do not match any other
647           Group within a Classification, the properties from this
648           class are used."""
649    
650        def __init__(self, props = None, label = "", group = None):
651            """Constructor.
652    
653            prop -- a ClassGroupProperites object. If prop is None a default
654                     set of properties is created.
655    
656            label -- a label for this group.
657            """
658    
659            ClassGroup.__init__(self, label, props, group)
660    
661        def __copy__(self):
662            return ClassGroupDefault(self.GetProperties(), self.GetLabel())
663    
664        def __deepcopy__(self, memo):
665            return ClassGroupDefault(label = self.GetLabel(), group = self)
666    
667        def Matches(self, value):
668            return True
669    
670        def GetDisplayText(self):
671            label = self.GetLabel()
672    
673            if label != "": return label
674    
675            return _("DEFAULT")
676    
677        def __eq__(self, other):
678            return ClassGroup.__eq__(self, other) \
679                and isinstance(other, ClassGroupDefault) \
680                and self.GetProperties() == other.GetProperties()
681    
682        def __repr__(self):
683            return "(" + ClassGroup.__repr__(self) + ")"
684    
685    class ClassGroupRange(ClassGroup):
686        """A Group that represents a range of values that map to the same
687           set of properties."""
688    
689        def __init__(self, min = 0, max = 1, props = None, label = "", group=None):
690            """Constructor.
691    
692            The minumum value must be strictly less than the maximum.
693    
694            min -- the minimum range value
695    
696            max -- the maximum range value
697    
698            prop -- a ClassGroupProperites object. If prop is None a default
699                     set of properties is created.
700    
701            label -- a label for this group.
702            """
703    
704            ClassGroup.__init__(self, label, props, group)
705    
706            #self.__min = self.__max = 0
707            #self.__range = Range("[" + repr(float(min)) + ";" +
708                                       #repr(float(max)) + "[")
709            self.SetRange(min, max)
710    
711        def __copy__(self):
712            return ClassGroupRange(min = self.__range,
713                                   max = None,
714                                   props = self.GetProperties(),
715                                   label = self.GetLabel())
716    
717        def __deepcopy__(self, memo):
718            return ClassGroupRange(min = copy.copy(self.__range),
719                                   max = copy.copy(self.GetMax()),
720                                   group = self)
721    
722        def GetMin(self):
723            """Return the range's minimum value."""
724            return self.__range.GetRange()[1]
725    
726        def SetMin(self, min):
727            """Set the range's minimum value.
728        
729            min -- the new minimum. Note that this must be less than the current
730                   maximum value. Use SetRange() to change both min and max values.
731            """
732        
733            self.SetRange(min, self.__range.GetRange()[2])
734    
735        def GetMax(self):
736            """Return the range's maximum value."""
737            return self.__range.GetRange()[2]
738    
739        def SetMax(self, max):
740            """Set the range's maximum value.
741        
742            max -- the new maximum. Note that this must be greater than the current
743                   minimum value. Use SetRange() to change both min and max values.
744            """
745            self.SetRange(self.__range.GetRange()[1], max)
746    
747        def SetRange(self, min, max = None):
748            """Set a new range.
749    
750            Note that min must be strictly less than max.
751    
752            min -- the new minimum value
753            min -- the new maximum value
754            """
755    
756            if isinstance(min, Range):
757                self.__range = min
758            else:
759                if max is None:
760                    raise ValueError()
761    
762                self.__range = Range(("[", min, max, "["))
763    
764        def GetRange(self):
765            """Return the range as a string"""
766            #return (self.__min, self.__max)
767            return self.__range.string(self.__range.GetRange())
768    
769        def Matches(self, value):
770            """Determine if the given value lies with the current range.
771    
772            The following check is used: min <= value < max.
773            """
774    
775            return operator.contains(self.__range, value)
776            #return self.__min <= value < self.__max
777    
778        def GetDisplayText(self):
779            label = self.GetLabel()
780    
781            if label != "": return label
782    
783            #return _("%s - %s") % (self.GetMin(), self.GetMax())
784            #return repr(self.__range)
785            return self.__range.string(self.__range.GetRange())
786    
787        def __eq__(self, other):
788            return ClassGroup.__eq__(self, other) \
789                and isinstance(other, ClassGroupRange) \
790                and self.__range == other.__range
791                #and self.__min == other.__min \
792                #and self.__max == other.__max
793    
794        def __repr__(self):
795            return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
796            #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
797                   #ClassGroup.__repr__(self) + ")"
798    
799    class ClassGroupMap(ClassGroup):
800        """Currently, this class is not used."""
801    
802        FUNC_ID = "id"
803    
804        def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
805            ClassGroup.__init__(self, label)
806    
807            self.map_type = map_type
808            self.func = func
809    
810            if self.func is None:
811                self.func = func_id
812    
813        def Map(self, value):
814            return self.func(value)
815    
816        def GetProperties(self):
817            return None
818    
819              #      def GetPropertiesFromValue(self, value):
820              # now check the ranges          pass
             #  
             for p in self.__ranges:  
                 if (p[RANGE_MIN] <= value) and (value < p[RANGE_MAX]):  
                     return p[RANGE_DATA]  
821    
822        def GetDisplayText(self):
823            return "Map: " + self.map_type
824    
825          return self.NullData      #
826        # built-in mappings
827        #
828        def func_id(value):
829            return value
830    

Legend:
Removed from v.371  
changed lines
  Added in v.1176

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26