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

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

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

revision 959 by jonathan, Wed May 21 17:22:58 2003 UTC revision 1352 by jonathan, Wed Jul 2 09:36:39 2003 UTC
# Line 5  Line 5 
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
7    
8    """
9    Functions to generate Classifications
10    """
11    
12    __version__ = "$Revision$"
13    # $Source$
14    # $Id$
15    
16  import operator  import operator
17    
18  from color import Color  from color import Color, Transparent
19  from range import Range  from range import Range
20  from classification import Classification, ClassGroupSingleton, \  from classification import Classification, ClassGroupSingleton, \
21      ClassGroupRange, ClassGroupProperties      ClassGroupRange, ClassGroupProperties
22    
23  class ClassGenerator:  def generate_singletons(_list, ramp):
24        """Generate a new classification consisting solely of singletons.
25    
26      def GenSingletonsFromList(self, _list, numGroups, ramp):      The resulting classification will consist of one group for each
27          """Generate a new classification consisting solely of singletons.      item in _list whose properties ramp between 'prop1' and 'prop2'.
28    
29          The resulting classification will consist of at most 'numGroups'      _list -- any object that implements the iterator interface
         groups whose group properties ramp between 'prop1' and 'prop2'. There  
         could be fewer groups if '_list' contains fewer that 'numGroups' items.  
30    
31          _list -- any object that implements the iterator interface      ramp -- an object which implements the CustomRamp interface
32        """
33    
34          numGroups -- how many groups to generate. This can not be      clazz = Classification()
                      determined while the classification is being  
                      generated because the stepping values must  
                      be precalculated to ramp between prop1 and prop2.  
35    
36          ramp -- an object which implements the CustomRamp interface      i = 0
37          """      for value in _list:
38            prop = ramp.GetProperties(float(i) / len(_list))
39            clazz.AppendGroup(ClassGroupSingleton(value, prop))
40            i += 1
41    
42          clazz = Classification()      return clazz
         if numGroups == 0: return clazz  
43    
44          ramp.SetNumGroups(numGroups)  def generate_uniform_distribution(min, max, numGroups, ramp, intStep = False):
45        """Generate a classification with numGroups range groups
46        each with the same interval.
47    
48          for value, prop in zip(_list, ramp):      intStep -- force the calculated stepping to an integer.
49              clazz.AppendGroup(ClassGroupSingleton(value, prop))                 Useful if the values are integers but the
50                   number of groups specified doesn't evenly
51                   divide (max - min).
52        """
53    
54          return clazz      clazz = Classification()
55    
56      def GenSingletons(self, min, max, numGroups, ramp):      cur_min = min
57    
58          clazz = Classification()      end = "["
59        for i in range(1, numGroups + 1):
60    
61          #step = int((max - min) / float(numGroups))          prop = ramp.GetProperties(float(i-1) / numGroups)
62    
63          if numGroups > 0:          if intStep:
64                cur_max = min + int(round((i * (max - min + 1)) / float(numGroups)))
65            else:
66                cur_max = min + (i * (max - min)) / float(numGroups)
67    
68              step = int((max - min + 1) / float(numGroups))          if i == numGroups:
69              cur_value = min              cur_max = max
70                end = "]"
71    
72              ramp.SetNumGroups(numGroups)          if cur_min == cur_max:
73                _range = Range(("[", cur_min, cur_max, "]"))
74            else:
75                _range = Range(("[", cur_min, cur_max, end))
76    
77              for prop in ramp:          clazz.AppendGroup(ClassGroupRange(_range, prop))
                 clazz.AppendGroup(ClassGroupSingleton(cur_value), prop)  
                 cur_value += step  
   
         return clazz  
   
     def GenUniformDistribution(self, min, max, numGroups,  
                                ramp, intStep = False):  
         """Generate a classification with numGroups range groups  
         each with the same interval.  
   
         intStep -- force the calculated stepping to an integer.  
                    Useful if the values are integers but the  
                    number of groups specified doesn't evenly  
                    divide (max - min).  
         """  
78    
79          clazz = Classification()          cur_min = cur_max
         if numGroups == 0: return clazz  
80    
81          ramp.SetNumGroups(numGroups)      return clazz
82    
83          step = (max - min) / float(numGroups)  def generate_quantiles(_list, percents, ramp, _range):
84        """Generates a Classification which has groups of ranges that
85        represent quantiles of _list at the percentages given in percents.
86        Only the values that fall within _range are considered.
87    
88          if intStep:      Returns a tuple (adjusted, Classification) where adjusted is
89              step = int(step)      True if the Classification does not exactly represent the given
90        range, or if the Classification is empty.
91    
92          cur_min = min      _list -- a sort list of values
         cur_max = cur_min + step  
93    
94          i = 0      percents -- a sorted list of floats in the range 0.0-1.0 which
95          end = "["                  represent the upper bound of each quantile. the
96          for prop in ramp:                  union of all percentiles should be the entire
97                    range from 0.0-1.0
98    
99              if i == (numGroups - 1):      ramp -- an object which implements the CustomRamp interface
                 cur_max = max  
                 end = "]"  
100    
101        _range -- a Range object
102    
103              # this check guards against rounding issues      Raises a Value Error if 'percents' has fewer than two items, or
104              if cur_min != cur_max:      does not cover the entire range.
105                  range = Range("[" + str(float(cur_min)) + ";" +      """
                                     str(float(cur_max)) + end)  
                 clazz.AppendGroup(ClassGroupRange(range, None, prop))  
106    
107              cur_min = cur_max      clazz = Classification()
108              cur_max += step      quantiles = calculate_quantiles(_list, percents, _range)
109              i += 1      adjusted = True
110    
111          return clazz      if quantiles is not None:
112    
113            numGroups = len(quantiles[3])
114    
115      def GenQuantiles(self, _list, percents, ramp, _range):          if numGroups != 0:
         """Generates a Classification which has groups of ranges that  
         represent quantiles of _list at the percentages given in percents.  
         Only the values that fall within _range are considered.  
116    
117          Returns a tuple (adjusted, Classification) where adjusted is              adjusted = quantiles[0]
         True if the Classification does not exactly represent the given  
         range, or if the Classification is empty.  
118    
119          _list -- a sort list of values              start, min, endMax, right = _range.GetRange()
120    
121          percents -- a sorted list of floats in the range 0.0-1.0 which              oldp = 0
122                      represent the upper bound of each quantile              i = 1
123                end = "]"
124    
125          ramp -- an object which implements the CustomRamp interface              for (q, p) in quantiles[3]:
126    
127          _range -- a Range object                  prop = ramp.GetProperties(float(i-1) / numGroups)
         """  
128    
129          clazz = Classification()                  if i == numGroups:
130          quantiles = self.CalculateQuantiles(_list, percents, _range)                      max = endMax
131          adjusted = True                      end = right
132                    else:
133                        max = _list[q]
134    
135          if quantiles is not None:                  group = ClassGroupRange(Range((start, min, max, end)), prop)
136        
137                    group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
138                                                    round(p*100, 2)))
139                    oldp = p
140                    start = "]"
141                    min = max
142                    clazz.AppendGroup(group)
143                    i += 1
144    
145              numGroups = len(quantiles[3])      return (adjusted, clazz)
146    
147              if numGroups != 0:  def GenQuantiles0(_list, percents, ramp, _range):
148        """Same as GenQuantiles, but the first class won't be added to
149        the classification.
150    
151                  adjusted = quantiles[0]      Returns a tuple (adjusted, Classification, upper_class0) where
152        upper_class0 is the highest value inside the first class.
153    
154                  ramp.SetNumGroups(numGroups)      _list -- a sort list of values
155    
156                  start, min, endMax, right = _range.GetRange()      percents -- a sorted list of floats in the range 0.0-1.0 which
157                    represent the upper bound of each quantile. the
158                    union of all percentiles should be the entire
159                    range from 0.0-1.0
160    
161                  oldp = 0      ramp -- an object which implements the CustomRamp interface
                 i = 1  
                 end = "]"  
162    
163                  for (q, p), prop in zip(quantiles[3], ramp):      _range -- a Range object
                     if i == numGroups:  
                         max = endMax  
                         end = right  
                     else:  
                         max = _list[q]  
164    
165                      group = ClassGroupRange(Range((start, min, max, end)),      Raises a Value Error if 'percents' has fewer than two items, or
166                                              None, prop)      does not cover the entire range.
167                """
                     group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),  
                                                     round(p*100, 2)))  
                     oldp = p  
                     start = "]"  
                     min = max  
                     clazz.AppendGroup(group)  
                     i += 1  
   
         return (adjusted, clazz)  
   
     def CalculateQuantiles(self, _list, percents, _range):  
         """Calculate quantiles for the given _list of percents from the  
         sorted list of values that are in range.  
                                                                                   
         This may not actually generate len(percents) quantiles if  
         many of the values that fall on quantile borders are the same.  
   
         Returns a tuple of the form:  
             (adjusted, minIndex, maxIndex, [quantile_list])  
   
         where adjusted is True if the the quantile percentages differ from  
         those supplied, minIndex is the index into _list where the  
         minimum value used is located, maxIndex is the index into _list  
         where the maximum value used is located, and quantile_list is a  
         list of tuples of the form: (list_index, quantile_percentage)  
   
         Returns None, if no quantiles could be generated based on the  
         given range or input list.  
168    
169          _list -- a sort list of values      clazz = Classification()
170        quantiles = calculate_quantiles(_list, percents, _range)
171        adjusted = True
172    
173          percents -- a sorted list of floats in the range 0.0-1.0 which      if quantiles is not None:
                     represent the upper bound of each quantile  
174    
175          _range -- a Range object          numGroups = len(quantiles[3]) - 1
         """  
       
         quantiles = []  
         adjusted = False  
176    
177          if len(percents) != 0:          if numGroups > 0:
178                                                                                              adjusted = quantiles[0]
             #  
             # find what part of the _list range covers  
             #  
             minIndex = -1  
             maxIndex = -2  
             for i in xrange(0, len(_list), 1):  
                 if operator.contains(_range, _list[i]):  
                     minIndex = i  
                     break  
   
             for i in xrange(len(_list)-1, -1, -1):  
                 if operator.contains(_range, _list[i]):  
                     maxIndex = i  
                     break  
   
             numValues = maxIndex - minIndex + 1  
   
             if numValues > 0:  
   
                 #  
                 # build a list of unique indices into list of where each  
                 # quantile *should* be. set adjusted if the resulting  
                 # indices are different  
                 #  
                 quantiles = {}  
                 for p in percents:  
                     index = min(minIndex + int(p*numValues)-1, maxIndex)  
   
                     adjusted = adjusted \  
                         or quantiles.has_key(index) \  
                         or ((index - minIndex + 1) / float(numValues)) != p  
   
                     quantiles[index] = 0  
   
                 quantiles = quantiles.keys()  
                 quantiles.sort()  
   
                 #  
                 # the current quantile index must be strictly greater than  
                 # the lowerBound  
                 #  
                 lowerBound = minIndex - 1  
       
                 for qindex in xrange(len(quantiles)):  
                     if lowerBound >= maxIndex:  
                         # discard higher quantiles  
                         quantiles = quantiles[:qindex]  
                         break  
       
                     # lowerBound + 1 is always a valid index  
       
                     #  
                     # bump up the current quantile index to be a usable index  
                     # if it currently falls below the lowerBound  
                     #  
                     if quantiles[qindex] <= lowerBound:  
                         quantiles[qindex] = lowerBound + 1  
           
                     listIndex = quantiles[qindex]  
                     value = _list[listIndex]  
       
                     #  
                     # look for similar values around the quantile index  
                     #  
                     lindex = listIndex - 1  
                     while lindex > lowerBound and value == _list[lindex]:  
                         lindex -= 1  
                     lcount = (listIndex - 1) - lindex  
       
                     rindex = listIndex + 1  
                     while rindex < maxIndex + 1 and value == _list[rindex]:  
                         rindex += 1  
                     rcount = (listIndex + 1) - rindex  
       
                     #  
                     # adjust the current quantile index based on how many  
                     # numbers in the _list are the same as the current value  
                     #  
                     newIndex = listIndex  
                     if lcount == rcount:  
                         if lcount != 0:  
                             #  
                             # there are an equal number of numbers to the left  
                             # and right, try going to the left first unless  
                             # doing so creates an empty quantile.  
                             #  
                             if lindex != lowerBound:  
                                 newIndex = lindex  
                             else:  
                                 newIndex = rindex - 1  
       
                     elif lcount < rcount:  
                         # there are fewer items to the left, so  
                         # try going to the left first unless  
                         # doing so creates an empty quantile.  
                         if lindex != lowerBound:  
                             newIndex = lindex  
                         else:  
                             newIndex = rindex - 1  
       
                     elif rcount < lcount:  
                         # there are fewer items to the right, so go to the right  
                         newIndex = rindex - 1  
       
                     adjusted = adjusted or newIndex != listIndex  
179    
180                      quantiles[qindex] = newIndex              start, min, endMax, right = _range.GetRange()
181                      lowerBound = quantiles[qindex]  
182                class0 = quantiles[3][0]
183                min = _list[class0[0]]
184                oldp = class0[1]
185                i = 1
186                end = "]"
187    
188                for (q, p) in quantiles[3][1:]:
189                    prop = ramp.GetProperties(float(i) / numGroups)
190    
191                    if i == numGroups:
192                        max = endMax
193                        end = right
194                    else:
195                        max = _list[q]
196    
197                    group = ClassGroupRange(Range((start, min, max, end)), prop)
198            
199          #                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
200          # since quantiles is only set if the code is at least a little                                                  round(p*100, 2)))
201          # successful, an empty list will be generated in the case that                  oldp = p
202          # we fail to get to the real body of the algorithm                  start = "]"
203          #                  min = max
204          if len(quantiles) == 0:                  clazz.AppendGroup(group)
205              return None                  i += 1
         else:  
             return (adjusted, minIndex, maxIndex,  
                     [(q, (q - minIndex+1) / float(numValues)) \  
                      for q in quantiles])  
206    
207  CLR  = 0      return (adjusted, clazz, _list[class0[0]])
 STEP = 1  
 class CustomRamp:  
208    
     def __init__(self, prop1, prop2):  
         self.prop1 = prop1  
         self.prop2 = prop2  
209    
210          self.count = 0  def calculate_quantiles(_list, percents, _range):
211        """Calculate quantiles for the given _list of percents from the
212        sorted list of values that are in range.
213                                                                                
214        This may not actually generate len(percents) quantiles if
215        many of the values that fall on quantile borders are the same.
216    
217      def __iter__(self):      Returns a tuple of the form:
218          return self          (adjusted, minIndex, maxIndex, [quantile_list])
219    
220      def GetRamp(self):      where adjusted is True if the the quantile percentages differ from
221          return self      those supplied, minIndex is the index into _list where the
222        minimum value used is located, maxIndex is the index into _list
223        where the maximum value used is located, and quantile_list is a
224        list of tuples of the form: (list_index, quantile_percentage)
225    
226      def SetNumGroups(self, num):      Returns None, if no quantiles could be generated based on the
227        given range or input list.
228    
229          if num <= 0:      _list -- a sort list of values
             return False  
230    
231          self.count = int(num)      percents -- a sorted list of floats in the range 0.0-1.0 which
232          num = float(num)                  represent the upper bound of each quantile. the
233                    union of all percentiles should be the entire
234                    range from 0.0-1.0
235    
236          prop1 = self.prop1      _range -- a Range object
         prop2 = self.prop2  
237    
238          clr = prop1.GetLineColor()      Raises a Value Error if 'percents' has fewer than two items, or
239          lineColor2 = prop2.GetLineColor()      does not cover the entire range.
240                """
         self.noLine = clr is not Color.Transparent \  
                         and lineColor2 is not Color.Transparent  
241    
242        quantiles = []
243        adjusted = False
244    
245          self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),      if len(percents) <= 1:
246                                              prop2.GetLineColor(),          raise ValueError("percents parameter must have more than one item")
                                             num)  
247    
248          self.fillInfo = self.__GetColorInfo(prop1.GetFill(),      if percents[-1] != 1.0:
249                                              prop2.GetFill(),          raise ValueError("percents does not cover the entire range")
                                             num)  
250    
251          self.lineWidth = prop1.GetLineWidth()      #
252          self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num      # find what part of the _list range covers
253        #
254        minIndex = -1
255        maxIndex = -2
256        for i in xrange(0, len(_list), 1):
257            if operator.contains(_range, _list[i]):
258                minIndex = i
259                break
260    
261          return True      for i in xrange(len(_list)-1, -1, -1):
262            if operator.contains(_range, _list[i]):
263                maxIndex = i
264                break
265    
266      def next(self):      numValues = maxIndex - minIndex + 1
         if self.count == 0:  
             raise StopIteration  
267    
268          prop = ClassGroupProperties()      if numValues > 0:
269    
270          if self.lineInfo is None:          #
271              prop.SetLineColor(Color.Transparent)          # build a list of unique indices into list of where each
272          else:          # quantile *should* be. set adjusted if the resulting
273              prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,          # indices are different
274                                      self.lineInfo[CLR][1] / 255,          #
275                                      self.lineInfo[CLR][2] / 255))          quantiles = {}
276            for p in percents:
277              self.lineInfo[CLR][0] += self.lineInfo[STEP][0]              index = min(minIndex + int(p*numValues)-1, maxIndex)
278              self.lineInfo[CLR][1] += self.lineInfo[STEP][1]  
279              self.lineInfo[CLR][2] += self.lineInfo[STEP][2]              adjusted = adjusted \
280                    or quantiles.has_key(index) \
281                    or ((index - minIndex + 1) / float(numValues)) != p
282    
283          if self.fillInfo is None:              quantiles[index] = 0
             prop.SetFill(Color.Transparent)  
         else:  
             prop.SetFill(Color(self.fillInfo[CLR][0] / 255,  
                             self.fillInfo[CLR][1] / 255,  
                             self.fillInfo[CLR][2] / 255))  
284    
285              self.fillInfo[CLR][0] += self.fillInfo[STEP][0]          quantiles = quantiles.keys()
286              self.fillInfo[CLR][1] += self.fillInfo[STEP][1]          quantiles.sort()
             self.fillInfo[CLR][2] += self.fillInfo[STEP][2]  
287    
288            #
289            # the current quantile index must be strictly greater than
290            # the lowerBound
291            #
292            lowerBound = minIndex - 1
293    
294          prop.SetLineWidth(int(self.lineWidth))          for qindex in xrange(len(quantiles)):
295          self.lineWidth        += self.lineWidthStep              if lowerBound >= maxIndex:
296                    # discard higher quantiles
297                    quantiles = quantiles[:qindex]
298                    break
299    
300          self.count -= 1              # lowerBound + 1 is always a valid index
301    
302          return prop              #
303                # bump up the current quantile index to be a usable index
304                # if it currently falls below the lowerBound
305                #
306                if quantiles[qindex] <= lowerBound:
307                    quantiles[qindex] = lowerBound + 1
308    
309      def __GetColorInfo(self, color1, color2, numGroups):              listIndex = quantiles[qindex]
310                value = _list[listIndex]
311    
         if color1 is Color.Transparent and color2 is Color.Transparent:  
312              #              #
313              # returning early              # look for similar values around the quantile index
314              #              #
315              return None              lindex = listIndex - 1
316          elif color1 is not Color.Transparent and color2 is Color.Transparent:              while lindex > lowerBound and value == _list[lindex]:
317              color = [color1.red   * 255,                  lindex -= 1
318                       color1.green * 255,              lcount = (listIndex - 1) - lindex
319                       color1.blue  * 255]  
320              step = (0, 0, 0)              rindex = listIndex + 1
321          elif color1 is Color.Transparent and color2 is not Color.Transparent:              while rindex < maxIndex + 1 and value == _list[rindex]:
322              color = [color2.red   * 255,                  rindex += 1
323                       color2.green * 255,              rcount = (listIndex + 1) - rindex
324                       color2.blue  * 255]  
325              step = (0, 0, 0)              #
326          else:              # adjust the current quantile index based on how many
327              color = [color1.red   * 255,              # numbers in the _list are the same as the current value
328                       color1.green * 255,              #
329                       color1.blue  * 255]              newIndex = listIndex
330              step = ((color2.red   * 255 - color1.red   * 255)   / numGroups,              if lcount == rcount:
331                      (color2.green * 255 - color1.green * 255) / numGroups,                  if lcount != 0:
332                      (color2.blue  * 255 - color1.blue  * 255)  / numGroups)                      #
333                        # there are an equal number of numbers to the left
334                        # and right, try going to the left first unless
335                        # doing so creates an empty quantile.
336                        #
337                        if lindex != lowerBound:
338                            newIndex = lindex
339                        else:
340                            newIndex = rindex - 1
341    
342                elif lcount < rcount:
343                    # there are fewer items to the left, so
344                    # try going to the left first unless
345                    # doing so creates an empty quantile.
346                    if lindex != lowerBound:
347                        newIndex = lindex
348                    else:
349                        newIndex = rindex - 1
350    
351                elif rcount < lcount:
352                    # there are fewer items to the right, so go to the right
353                    newIndex = rindex - 1
354    
355                adjusted = adjusted or newIndex != listIndex
356    
357                quantiles[qindex] = newIndex
358                lowerBound = quantiles[qindex]
359    
360        if len(quantiles) == 0:
361            return None
362        else:
363            return (adjusted, minIndex, maxIndex,
364                    [(q, (q - minIndex+1) / float(numValues)) \
365                     for q in quantiles])
366    
367    class CustomRamp:
368    
369          return (color, step)      def __init__(self, prop1, prop2):
370            self.prop1 = prop1
371            self.prop2 = prop2
372    
373        def GetRamp(self):
374            return self
375    
376        def GetProperties(self, index):
377            """Return a ClassGroupProperties object whose properties
378            represent a point at 'index' between prop1 and prop2 in
379            the constructor.
380    
381            index -- a value such that 0 <= index <= 1
382            """
383    
384            if not (0 <= index <= 1):
385                raise ValueError(_("invalid index"))
386    
387            newProps = ClassGroupProperties()
388    
389            color1 = self.prop1.GetLineColor()
390            color2 = self.prop2.GetLineColor()
391    
392            self.__SetProperty(color1, color2, index, newProps.SetLineColor)
393            self.__SetProperty(color1, color2, index, newProps.SetFill)
394    
395            w = (self.prop2.GetLineWidth() - self.prop1.GetLineWidth()) \
396                * index \
397                + self.prop1.GetLineWidth()
398    
399            newProps.SetLineWidth(int(round(w)))
400    
401            return newProps
402    
403        def __SetProperty(self, color1, color2, index, setf):
404    
405            if color1 is Transparent and color2 is Transparent:
406                setf(Transparent)
407            elif color1 is Transparent:
408                setf(Color(
409                     color2.red   * index,
410                     color2.green * index,
411                     color2.blue  * index))
412            elif color2 is Transparent:
413                setf(Color(
414                     color1.red   * index,
415                     color1.green * index,
416                     color1.blue  * index))
417            else:
418                setf(Color(
419                    (color2.red   - color1.red)   * index + color1.red,
420                    (color2.green - color1.green) * index + color1.green,
421                    (color2.blue  - color1.blue)  * index + color1.blue))
422    
423  class MonochromaticRamp(CustomRamp):  class MonochromaticRamp(CustomRamp):
424      def __init__(self, start, end):      def __init__(self, start, end):
# Line 441  class MonochromaticRamp(CustomRamp): Line 432  class MonochromaticRamp(CustomRamp):
432    
433          CustomRamp.__init__(self, sp, ep)          CustomRamp.__init__(self, sp, ep)
434    
435  class GreyRamp(MonochromaticRamp):  GreyRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, 0))
436      def __init__(self):  RedRamp        = MonochromaticRamp(Color(1, 1, 1),  Color(.8, 0, 0))
437          MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))  GreenRamp      = MonochromaticRamp(Color(1, 1, 1),  Color(0, .8, 0))
438    BlueRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, .8))
439  class RedRamp(MonochromaticRamp):  GreenToRedRamp = MonochromaticRamp(Color(1, .8, 1), Color(1, 0, 0))
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(.8, 0, 0))  
   
 class GreenRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, .8, 0))  
   
 class BlueRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, .8))  
   
 class GreenToRedRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(0, .8, 0), Color(1, 0, 0))  
440    
441  class HotToColdRamp:  class HotToColdRamp:
442    
     def __iter__(self):  
         return self  
           
443      def GetRamp(self):      def GetRamp(self):
444          return self          return self
445    
446      def SetNumGroups(self, num):      def GetProperties(self, index):
447          if num < 0:          """Return a ClassGroupProperties object whose properties
448              return False          represent a point at 'index' between "hot" and "cold".
449    
450          self.num = float(num)          index -- a value such that 0 <= index <= 1
451          self.index = 0          """
   
         return True  
   
     def next(self):  
         if self.index == self.num:  
             raise StopIteration  
452    
453          clr = [1.0, 1.0, 1.0]          clr = [1.0, 1.0, 1.0]
454    
455          if self.index < (.25 * self.num):          if index < .25:
456              clr[0] = 0              clr[0] = 0
457              clr[1] = 4 * self.index / self.num              clr[1] = 4 * index
458          elif self.index < (.5 * self.num):          elif index < .5:
459              clr[0] = 0              clr[0] = 0
460              clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num              clr[2] = 1 + 4 * (.25 - index)
461          elif self.index < (.75 * self.num):          elif index < .75:
462              clr[0] = 4 * (self.index - .5 * self.num) / self.num              clr[0] = 4 * (index - .5)
463              clr[2] = 0              clr[2] = 0
464          else:          else:
465              clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num              clr[1] = 1 + 4 * (.75 - index)
466              clr[2] = 0              clr[2] = 0
467    
         self.index += 1  
   
468          prop = ClassGroupProperties()          prop = ClassGroupProperties()
469          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))
470          prop.SetFill(Color(clr[0], clr[1], clr[2]))          prop.SetFill(Color(clr[0], clr[1], clr[2]))
471    
472          return prop          return prop
473    
 #class Colors16Ramp:  
 #  
     #def __iter__(self):  
         #return self  
 #  
     #def GetRamp(self):  
         #return self  
 #  
     #def SetNumGroups(self, num):  
         #if num < 0:  
             #return False  
 #  
         #self.index = 0  
 #  
         #return True  

Legend:
Removed from v.959  
changed lines
  Added in v.1352

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26