/[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 886 by jonathan, Fri May 9 16:36:56 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.
     def GenSingletonsFromList(self, list, numGroups, ramp):  
         """Generate a new classification consisting solely of singletons.  
25    
26          The resulting classification will consist of at most 'numGroups'      The resulting classification will consist of one group for each
27          groups whose group properties ramp between 'prop1' and 'prop2'. There      item in _list whose properties ramp between 'prop1' and 'prop2'.
         could be fewer groups if 'list' contains fewer that 'numGroups' items.  
28    
29          list -- any object that implements the iterator interface      _list -- any object that implements the iterator interface
30    
31          numGroups -- how many groups to generate. This can not be      ramp -- an object which implements the CustomRamp interface
32                       determined while the classification is being      """
                      generated because the stepping values must  
                      be precalculated to ramp between prop1 and prop2.  
33    
34          prop1 -- initial group property values      clazz = Classification()
35    
36          prop2 -- final group property values      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)
   
         if numGroups > 0:  
62    
63              step = int((max - min + 1) / float(numGroups))          if intStep:
64              cur_value = min              cur_max = min + int(round((i * (max - min + 1)) / float(numGroups)))
65            else:
66                cur_max = min + (i * (max - min)) / float(numGroups)
67    
68              ramp.SetNumGroups(numGroups)          if i == numGroups:
69                cur_max = max
70                end = "]"
71    
72              for prop in ramp:          if cur_min == cur_max:
73                  clazz.AppendGroup(ClassGroupSingleton(cur_value), prop)              _range = Range(("[", cur_min, cur_max, "]"))
74                  cur_value += step          else:
75                _range = Range(("[", cur_min, cur_max, end))
         return clazz  
   
     def GenUnifromDistribution(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).  
         """  
76    
77          clazz = Classification()          clazz.AppendGroup(ClassGroupRange(_range, prop))
         if numGroups == 0: return clazz  
78    
79          ramp.SetNumGroups(numGroups)          cur_min = cur_max
80    
81          step = (max - min) / float(numGroups)      return clazz
82    
83          if intStep:  def generate_quantiles(_list, percents, ramp, _range):
84              step = int(step)      """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          cur_min = min      Returns a tuple (adjusted, Classification) where adjusted is
89          cur_max = cur_min + step      True if the Classification does not exactly represent the given
90        range, or if the Classification is empty.
91    
92          i = 0      _list -- a sort list of values
         end = "["  
         for prop in ramp:  
93    
94              if i == (numGroups - 1):      percents -- a sorted list of floats in the range 0.0-1.0 which
95                  cur_max = max                  represent the upper bound of each quantile. the
96                  end = "]"                  union of all percentiles should be the entire
97                    range from 0.0-1.0
98    
99        ramp -- an object which implements the CustomRamp interface
100    
101              # this check guards against rounding issues      _range -- a Range object
             if cur_min != cur_max:  
                 range = Range("[" + str(float(cur_min)) + ";" +  
                                     str(float(cur_max)) + end)  
                 clazz.AppendGroup(ClassGroupRange(range, None, prop))  
102    
103              cur_min = cur_max      Raises a Value Error if 'percents' has fewer than two items, or
104              cur_max += step      does not cover the entire range.
105              i += 1      """
106    
107          return clazz      clazz = Classification()
108        quantiles = calculate_quantiles(_list, percents, _range)
109        adjusted = True
110    
111        if quantiles is not None:
112    
113      def GenQuantiles(self, list, percents, ramp, _range):          numGroups = len(quantiles[3])
         clazz = Classification()  
         quantiles = self.CalculateQuantiles(list, percents, _range)  
         numGroups = len(quantiles[1])  
         if numGroups == 0: return clazz  
114    
115          ramp.SetNumGroups(numGroups)          if numGroups != 0:
116    
117          left, min, max, right = _range.GetRange()              adjusted = quantiles[0]
118    
119          start = "["              start, min, endMax, right = _range.GetRange()
         oldp = 0  
         for (q, p), prop in zip(quantiles[1], ramp):  
             max = list[q]  
             group = ClassGroupRange(Range(start + str(min) + ";" +  
                                                   str(max) + "]"),  
                                     None, prop)  
120    
121              group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),              oldp = 0
122                                              round(p*100, 2)))              i = 1
123              oldp = p              end = "]"
             start = "]"  
             min = max  
             clazz.AppendGroup(group)  
124    
125          return (quantiles[0], clazz)              for (q, p) in quantiles[3]:
126    
127      def CalculateQuantiles(self, list, percents, _range):                  prop = ramp.GetProperties(float(i-1) / numGroups)
         """Calculate quantiles for the given list of percents from the  
         sorted list of values that are in range.  
                                                                                   
         percents is a sorted list of floats in the range 0.0-1.0  
128    
129          This may not actually generate numGroups quantiles if                  if i == numGroups:
130          many of the values that fall on quantile borders are the same.                      max = endMax
131                        end = right
132                    else:
133                        max = _list[q]
134    
135          Returns a tuple of the form: (adjusted, [quantile_list])                  group = ClassGroupRange(Range((start, min, max, end)), prop)
   
         where adjusted is true if the the quantile percentages differ from  
         those supplied, and quantile_list is a list of tuples of the form:  
             (list_index, quantile_percentage)  
         """  
       
         quantiles = []  
                                                                                   
         adjusted = False  
         if len(percents) != 0:  
                                                                                 
             #print "list:", list  
             #print "percents:", percents  
             #print "numGroups:", numGroups  
136            
137              #                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
138              # find what part of the list range covers                                                  round(p*100, 2)))
139              #                  oldp = p
140              minIndex = -1                  start = "]"
141              maxIndex = -2                  min = max
142              for i in xrange(0, len(list), 1):                  clazz.AppendGroup(group)
143                  if operator.contains(_range, list[i]):                  i += 1
                     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  
             #print "minIndex:", minIndex, "maxIndex:", maxIndex  
             if minIndex <= maxIndex:  
   
                 #  
                 # build a list of unique indices into list of where each  
                 # quantile should be  
                 #  
                 quantiles = {}  
                 for p in percents:  
                     index = min(minIndex + int(p*numValues)-1, maxIndex)  
   
                     adjusted = adjusted \  
                         or quantiles.has_key(index) \  
                         or ((index+1) / float(numValues)) != p  
144    
145                      quantiles[index] = 0      return (adjusted, clazz)
146    
147                  quantiles = quantiles.keys()  def GenQuantiles0(_list, percents, ramp, _range):
148                  quantiles.sort()      """Same as GenQuantiles, but the first class won't be added to
149        the classification.
150    
151                  #print "quantiles:", quantiles      Returns a tuple (adjusted, Classification, upper_class0) where
152            upper_class0 is the highest value inside the first class.
                 #  
                 # the current quantile index must be strictly greater than  
                 # the lowerBound  
                 #  
                 lowerBound = minIndex - 1  
       
                 for qindex in range(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] = min(lowerBound + 1, maxIndex)  
           
                     listIndex = quantiles[qindex]  
                     value = list[quantiles[qindex]]  
       
                     #print "-----------------------------------"  
                     #print "listIndex:", listIndex  
                     #print "value:", value  
       
                     #  
                     # look for similar values around the quantile index  
                     #  
                   
                     #print "lowerBound:", lowerBound  
                     lindex = listIndex - 1  
                     lcount = 0  
                     while lindex > lowerBound:  
                         if value != list[lindex]: break  
                         lcount += 1  
                         lindex -= 1  
       
                     rindex = listIndex + 1  
                     rcount = 0  
                     while rindex < maxIndex + 1:  
                         if value != list[rindex]: break  
                         rcount += 1  
                         rindex += 1  
       
                     #print lcount, "(lcount)", rcount, "(rcount)"  
                     #print lindex, "(lindex)", rindex, "(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  
                                 #quantiles[qindex] = lindex  
                             else:  
                                 newIndex = rindex - 1  
                                 #quantiles[qindex] = 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  
                             #quantiles[qindex] = lindex  
                         else:  
                             newIndex = rindex - 1  
                             #quantiles[qindex] = rindex - 1  
       
                     elif rcount < lcount:  
                         # there are fewer items to the right, so go to the right  
                         #quantiles[qindex] = rindex - 1  
                         newIndex = rindex - 1  
       
                     quantiles[qindex] = newIndex  
                     lowerBound = quantiles[qindex]  
       
                     #print "quantiles:", quantiles  
                     #print "lowerBound:", lowerBound  
           
                 #print "================================="  
                 #print "quantiles:", quantiles  
                 #print "qindex:", qindex  
       
         return (adjusted, [(q, (q+1) / float(numValues)) for q in quantiles])  
153    
154  CLR  = 0      _list -- a sort list of values
 STEP = 1  
 class CustomRamp:  
155    
156      def __init__(self, prop1, prop2):      percents -- a sorted list of floats in the range 0.0-1.0 which
157          self.prop1 = prop1                  represent the upper bound of each quantile. the
158          self.prop2 = prop2                  union of all percentiles should be the entire
159                    range from 0.0-1.0
160    
161          self.count = 0      ramp -- an object which implements the CustomRamp interface
162    
163      def __iter__(self):      _range -- a Range object
         return self  
164    
165      def GetRamp(self):      Raises a Value Error if 'percents' has fewer than two items, or
166          return self      does not cover the entire range.
167        """
168    
169      def SetNumGroups(self, num):      clazz = Classification()
170        quantiles = calculate_quantiles(_list, percents, _range)
171        adjusted = True
172    
173          if num <= 0:      if quantiles is not None:
             return False  
174    
175          self.count = int(num)          numGroups = len(quantiles[3]) - 1
         num = float(num)  
176    
177          prop1 = self.prop1          if numGroups > 0:
178          prop2 = self.prop2              adjusted = quantiles[0]
179    
180          clr = prop1.GetLineColor()              start, min, endMax, right = _range.GetRange()
         lineColor2 = prop2.GetLineColor()  
           
         self.noLine = clr is not Color.Transparent \  
                         and lineColor2 is not Color.Transparent  
181    
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                                                    round(p*100, 2)))
201                    oldp = p
202                    start = "]"
203                    min = max
204                    clazz.AppendGroup(group)
205                    i += 1
206    
207        return (adjusted, clazz, _list[class0[0]])
208    
209    
210    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        Returns a tuple of the form:
218            (adjusted, minIndex, maxIndex, [quantile_list])
219    
220        where adjusted is True if the the quantile percentages differ from
221        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        Returns None, if no quantiles could be generated based on the
227        given range or input list.
228    
229        _list -- a sort list of values
230    
231        percents -- a sorted list of floats in the range 0.0-1.0 which
232                    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        _range -- a Range object
237    
238        Raises a Value Error if 'percents' has fewer than two items, or
239        does not cover the entire range.
240        """
241    
242        quantiles = []
243        adjusted = False
244    
245        if len(percents) <= 1:
246            raise ValueError("percents parameter must have more than one item")
247    
248        if percents[-1] != 1.0:
249            raise ValueError("percents does not cover the entire range")
250    
251        #
252        # 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        for i in xrange(len(_list)-1, -1, -1):
262            if operator.contains(_range, _list[i]):
263                maxIndex = i
264                break
265    
266        numValues = maxIndex - minIndex + 1
267    
268        if numValues > 0:
269    
270            #
271            # build a list of unique indices into list of where each
272            # quantile *should* be. set adjusted if the resulting
273            # indices are different
274            #
275            quantiles = {}
276            for p in percents:
277                index = min(minIndex + int(p*numValues)-1, maxIndex)
278    
279                adjusted = adjusted \
280                    or quantiles.has_key(index) \
281                    or ((index - minIndex + 1) / float(numValues)) != p
282    
283                quantiles[index] = 0
284    
285            quantiles = quantiles.keys()
286            quantiles.sort()
287    
288            #
289            # the current quantile index must be strictly greater than
290            # the lowerBound
291            #
292            lowerBound = minIndex - 1
293    
294            for qindex in xrange(len(quantiles)):
295                if lowerBound >= maxIndex:
296                    # discard higher quantiles
297                    quantiles = quantiles[:qindex]
298                    break
299    
300          self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),              # lowerBound + 1 is always a valid index
                                             prop2.GetLineColor(),  
                                             num)  
301    
302          self.fillInfo = self.__GetColorInfo(prop1.GetFill(),              #
303                                              prop2.GetFill(),              # bump up the current quantile index to be a usable index
304                                              num)              # if it currently falls below the lowerBound
305                #
306                if quantiles[qindex] <= lowerBound:
307                    quantiles[qindex] = lowerBound + 1
308    
309          self.lineWidth = prop1.GetLineWidth()              listIndex = quantiles[qindex]
310          self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num              value = _list[listIndex]
311    
312          return True              #
313                # look for similar values around the quantile index
314                #
315                lindex = listIndex - 1
316                while lindex > lowerBound and value == _list[lindex]:
317                    lindex -= 1
318                lcount = (listIndex - 1) - lindex
319    
320                rindex = listIndex + 1
321                while rindex < maxIndex + 1 and value == _list[rindex]:
322                    rindex += 1
323                rcount = (listIndex + 1) - rindex
324    
325      def next(self):              #
326          if self.count == 0:              # adjust the current quantile index based on how many
327              raise StopIteration              # numbers in the _list are the same as the current value
328                #
329                newIndex = listIndex
330                if lcount == rcount:
331                    if lcount != 0:
332                        #
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          prop = ClassGroupProperties()              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          if self.lineInfo is None:  class CustomRamp:
             prop.SetLineColor(Color.Transparent)  
         else:  
             prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,  
                                     self.lineInfo[CLR][1] / 255,  
                                     self.lineInfo[CLR][2] / 255))  
   
             self.lineInfo[CLR][0] += self.lineInfo[STEP][0]  
             self.lineInfo[CLR][1] += self.lineInfo[STEP][1]  
             self.lineInfo[CLR][2] += self.lineInfo[STEP][2]  
368    
369          if self.fillInfo is None:      def __init__(self, prop1, prop2):
370              prop.SetFill(Color.Transparent)          self.prop1 = prop1
371          else:          self.prop2 = prop2
             prop.SetFill(Color(self.fillInfo[CLR][0] / 255,  
                             self.fillInfo[CLR][1] / 255,  
                             self.fillInfo[CLR][2] / 255))  
372    
373              self.fillInfo[CLR][0] += self.fillInfo[STEP][0]      def GetRamp(self):
374              self.fillInfo[CLR][1] += self.fillInfo[STEP][1]          return self
             self.fillInfo[CLR][2] += self.fillInfo[STEP][2]  
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          prop.SetLineWidth(int(self.lineWidth))          index -- a value such that 0 <= index <= 1
382          self.lineWidth        += self.lineWidthStep          """
383    
384          self.count -= 1          if not (0 <= index <= 1):
385                raise ValueError(_("invalid index"))
386    
387          return prop          newProps = ClassGroupProperties()
388    
389      def __GetColorInfo(self, color1, color2, numGroups):          color1 = self.prop1.GetLineColor()
390            color2 = self.prop2.GetLineColor()
391    
392          if color1 is Color.Transparent and color2 is Color.Transparent:          self.__SetProperty(color1, color2, index, newProps.SetLineColor)
393              #          self.__SetProperty(color1, color2, index, newProps.SetFill)
394              # returning early  
395              #          w = (self.prop2.GetLineWidth() - self.prop1.GetLineWidth()) \
396              return None              * index \
397          elif color1 is not Color.Transparent and color2 is Color.Transparent:              + self.prop1.GetLineWidth()
398              color = [color1.red   * 255,  
399                       color1.green * 255,          newProps.SetLineWidth(int(round(w)))
400                       color1.blue  * 255]  
401              step = (0, 0, 0)          return newProps
402          elif color1 is Color.Transparent and color2 is not Color.Transparent:  
403              color = [color2.red   * 255,      def __SetProperty(self, color1, color2, index, setf):
404                       color2.green * 255,  
405                       color2.blue  * 255]          if color1 is Transparent and color2 is Transparent:
406              step = (0, 0, 0)              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:          else:
418              color = [color1.red   * 255,              setf(Color(
419                       color1.green * 255,                  (color2.red   - color1.red)   * index + color1.red,
420                       color1.blue  * 255]                  (color2.green - color1.green) * index + color1.green,
421              step = ((color2.red   * 255 - color1.red   * 255)   / numGroups,                  (color2.blue  - color1.blue)  * index + color1.blue))
                     (color2.green * 255 - color1.green * 255) / numGroups,  
                     (color2.blue  * 255 - color1.blue  * 255)  / numGroups)  
   
   
         return (color, step)  
422    
423  class MonochromaticRamp(CustomRamp):  class MonochromaticRamp(CustomRamp):
424      def __init__(self, start, end):      def __init__(self, start, end):
# Line 419  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.886  
changed lines
  Added in v.1352

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26