/[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 1911 by bh, Fri Oct 31 18:16:34 2003 UTC revision 1912 by bh, Mon Nov 3 13:55:41 2003 UTC
# Line 68  class Classification(Publisher): Line 68  class Classification(Publisher):
68      def __SendNotification(self):      def __SendNotification(self):
69          """Notify the layer that this class has changed."""          """Notify the layer that this class has changed."""
70          self.issue(CLASS_CHANGED)          self.issue(CLASS_CHANGED)
71        
72        def __getattr__(self, attr):
73            """Generate the compiled classification on demand"""
74            if attr == "_compiled_classification":
75                self._compile_classification()
76                return self._compiled_classification
77            raise AttributeError(attr)
78    
79        def _compile_classification(self):
80            """Generate the compiled classification
81    
82            The compiled classification is a more compact representation of
83            the classification groups that is also more efficient for
84            performing the classification.
85    
86            The compiled classification is a list of tuples. The first
87            element of the tuple is a string which describes the rest of the
88            tuple. There are two kinds of tuples:
89    
90              'singletons'
91    
92                The second element of the tuple is a dictionary which
93                combines several consecutive ClassGroupSingleton instances.
94                The dictionary maps the values of the singletons (as
95                returned by the GetValue() method) to the corresponding
96                group.
97    
98              'range'
99    
100                The tuple describes a ClassGroupRange instance. The tuples
101                second element is a tuple fo the form (lfunc, min, max,
102                rfunc, group) where group is the original group object,
103                lfunc and rfuct are comparison functions and min and max are
104                lower and upper bounds of the range. Given a value and such
105                a tuple the group matches if and only if
106    
107                    lfunc(min, value) and rfunc(max, value)
108    
109                is true.
110    
111            The compiled classification is bound to
112            self._compile_classification.
113            """
114            compiled = []
115            for group in self.__groups[1:]:
116                if isinstance(group, ClassGroupSingleton):
117                    if not compiled or compiled[-1][0] != "singletons":
118                        compiled.append(("singletons", {}))
119                    compiled[-1][1].setdefault(group.GetValue(), group)
120                elif isinstance(group, ClassGroupRange):
121                    left, min, max, right = group.GetRangeTuple()
122                    if left == "[":
123                        lfunc = operator.le
124                    elif left == "]":
125                        lfunc = operator.lt
126                    if right == "[":
127                        rfunc = operator.gt
128                    elif right == "]":
129                        rfunc = operator.ge
130                    compiled.append(("range", (lfunc, min, max, rfunc, group)))
131                else:
132                    raise TypeError("Unknown group type %s", group)
133            self._compiled_classification = compiled
134    
135        def _clear_compiled_classification(self):
136            """Reset the compiled classification.
137    
138            If will be created on demand when self._compiled_classification
139            is accessed again.
140    
141            Call this method whenever self.__groups is modified.
142            """
143            try:
144                del self._compiled_classification
145            except:
146                pass
147    
148      #      #
149      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
150      # some backward compatibility. they should be considered      # some backward compatibility. they should be considered
# Line 148  class Classification(Publisher): Line 224  class Classification(Publisher):
224      def InsertGroup(self, index, group):      def InsertGroup(self, index, group):
225          assert isinstance(group, ClassGroup)          assert isinstance(group, ClassGroup)
226          self.__groups.insert(index + 1, group)          self.__groups.insert(index + 1, group)
227            self._clear_compiled_classification()
228          self.__SendNotification()          self.__SendNotification()
229    
230      def RemoveGroup(self, index):      def RemoveGroup(self, index):
231          """Remove the classification group with the given index"""          """Remove the classification group with the given index"""
232          self.__groups.pop(index + 1)          self.__groups.pop(index + 1)
233            self._clear_compiled_classification()
234          self.__SendNotification()          self.__SendNotification()
235    
236      def ReplaceGroup(self, index, group):      def ReplaceGroup(self, index, group):
237          assert isinstance(group, ClassGroup)          assert isinstance(group, ClassGroup)
238          self.__groups[index + 1] = group          self.__groups[index + 1] = group
239            self._clear_compiled_classification()
240          self.__SendNotification()          self.__SendNotification()
241    
242      def GetGroup(self, index):      def GetGroup(self, index):
# Line 168  class Classification(Publisher): Line 247  class Classification(Publisher):
247          return len(self.__groups) - 1          return len(self.__groups) - 1
248    
249      def FindGroup(self, value):      def FindGroup(self, value):
250          """Return the associated group, or the default group.          """Return the group that matches the value.
251    
252          Groups are checked in the order the were added to the          Groups are effectively checked in the order the were added to
253          Classification.          the Classification.
254    
255          value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping or value
256                   the field is None or value is None,                   is None, return the default properties
                  return the default properties  
257          """          """
258    
259          if value is not None:          if value is not None:
260              for i in range(1, len(self.__groups)):              for typ, params in self._compiled_classification:
261                  group = self.__groups[i]                  if typ == "singletons":
262                  if group.Matches(value):                      group = params.get(value)
263                      return group                      if group is not None:
264                            return group
265                    elif typ == "range":
266                        lfunc, min, max, rfunc, g = params
267                        if lfunc(min, value) and rfunc(max, value):
268                            return g
269    
270          return self.GetDefaultGroup()          return self.GetDefaultGroup()
271    
# Line 608  class ClassGroupRange(ClassGroup): Line 691  class ClassGroupRange(ClassGroup):
691          """Return the range as a string"""          """Return the range as a string"""
692          return self.__range.string(self.__range.GetRange())          return self.__range.string(self.__range.GetRange())
693    
694        def GetRangeTuple(self):
695            return self.__range.GetRange()
696    
697      def Matches(self, value):      def Matches(self, value):
698          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
699    

Legend:
Removed from v.1911  
changed lines
  Added in v.1912

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26