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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26