/[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 895 by jonathan, Mon May 12 11:21:02 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          prop1 -- initial 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          prop2 -- final group property values      return clazz
         """  
43    
44          clazz = Classification()  def generate_uniform_distribution(min, max, numGroups, ramp, intStep = False):
45          if numGroups == 0: return clazz      """Generate a classification with numGroups range groups
46        each with the same interval.
47    
48          ramp.SetNumGroups(numGroups)      intStep -- force the calculated stepping to an integer.
49                   Useful if the values are integers but the
50                   number of groups specified doesn't evenly
51                   divide (max - min).
52        """
53    
54          for value, prop in zip(_list, ramp):      clazz = Classification()
             clazz.AppendGroup(ClassGroupSingleton(value, prop))  
55    
56          return clazz      cur_min = min
57    
58      def GenSingletons(self, min, max, numGroups, ramp):      end = "["
59        for i in range(1, numGroups + 1):
60    
61          clazz = Classification()          prop = ramp.GetProperties(float(i-1) / numGroups)
62    
63          #step = int((max - min) / float(numGroups))          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          if numGroups > 0:          if i == numGroups:
69                cur_max = max
70                end = "]"
71    
72              step = int((max - min + 1) / float(numGroups))          if cur_min == cur_max:
73              cur_value = min              _range = Range(("[", cur_min, cur_max, "]"))
74            else:
75                _range = Range(("[", cur_min, cur_max, end))
76    
77              ramp.SetNumGroups(numGroups)          clazz.AppendGroup(ClassGroupRange(_range, prop))
78    
79              for prop in ramp:          cur_min = cur_max
                 clazz.AppendGroup(ClassGroupSingleton(cur_value), prop)  
                 cur_value += step  
   
         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).  
         """  
80    
81          clazz = Classification()      return clazz
         if numGroups == 0: return clazz  
82    
83          ramp.SetNumGroups(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          step = (max - min) / float(numGroups)      Returns a tuple (adjusted, Classification) where adjusted is
89        True if the Classification does not exactly represent the given
90        range, or if the Classification is empty.
91    
92          if intStep:      _list -- a sort list of values
             step = int(step)  
93    
94          cur_min = min      percents -- a sorted list of floats in the range 0.0-1.0 which
95          cur_max = cur_min + step                  represent the upper bound of each quantile. the
96                    union of all percentiles should be the entire
97                    range from 0.0-1.0
98    
99          i = 0      ramp -- an object which implements the CustomRamp interface
         end = "["  
         for prop in ramp:  
100    
101              if i == (numGroups - 1):      _range -- a Range object
                 cur_max = max  
                 end = "]"  
102    
103        Raises a Value Error if 'percents' has fewer than two items, or
104        does not cover the entire range.
105        """
106    
107              # this check guards against rounding issues      clazz = Classification()
108              if cur_min != cur_max:      quantiles = calculate_quantiles(_list, percents, _range)
109                  range = Range("[" + str(float(cur_min)) + ";" +      adjusted = True
                                     str(float(cur_max)) + end)  
                 clazz.AppendGroup(ClassGroupRange(range, None, prop))  
110    
111              cur_min = cur_max      if quantiles is not None:
             cur_max += step  
             i += 1  
112    
113          return clazz          numGroups = len(quantiles[3])
114    
115            if numGroups != 0:
116    
117      def GenQuantiles(self, _list, percents, ramp, _range):              adjusted = quantiles[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.  
118    
119          Returns a tuple (adjusted, Classification) where adjusted is              start, min, endMax, right = _range.GetRange()
         True if the Classification does not exactly represent the given  
         range, or if the Classification is empty.  
120    
121          _list -- a sort list of values              oldp = 0
122                i = 1
123                end = "]"
124    
125          percents -- a sorted list of floats in the range 0.0-1.0 which              for (q, p) in quantiles[3]:
                     represent the upper bound of each quantile  
126    
127          ramp -- an object which implements the CustomRamp interface                  prop = ramp.GetProperties(float(i-1) / numGroups)
128    
129          _range -- a Range object                  if i == numGroups:
130          """                      max = endMax
131                        end = right
132                    else:
133                        max = _list[q]
134    
135          clazz = Classification()                  group = ClassGroupRange(Range((start, min, max, end)), prop)
136          quantiles = self.CalculateQuantiles(_list, percents, _range)      
137          adjusted = True                  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          if quantiles is not None:      return (adjusted, clazz)
146    
147              numGroups = len(quantiles[3])  def GenQuantiles0(_list, percents, ramp, _range):
148        """Same as GenQuantiles, but the first class won't be added to
149        the classification.
150    
151              if numGroups != 0:      Returns a tuple (adjusted, Classification, upper_class0) where
152        upper_class0 is the highest value inside the first class.
153    
154                  adjusted = quantiles[0]      _list -- a sort list of values
155    
156                  ramp.SetNumGroups(numGroups)      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                  min = _list[quantiles[1]]      ramp -- an object which implements the CustomRamp interface
                 start = "["  
                 oldp = 0  
                 for (q, p), prop in zip(quantiles[3], ramp):  
                     max = _list[q]  
                     group = ClassGroupRange(Range(start + str(min) + ";" +  
                                                           str(max) + "]"),  
                                             None, prop)  
           
                     group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),  
                                                     round(p*100, 2)))  
                     oldp = p  
                     start = "]"  
                     min = max  
                     clazz.AppendGroup(group)  
   
         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.  
162    
163          _list -- a sort list of values      _range -- a Range object
164    
165          percents -- a sorted list of floats in the range 0.0-1.0 which      Raises a Value Error if 'percents' has fewer than two items, or
166                      represent the upper bound of each quantile      does not cover the entire range.
167        """
168    
169          _range -- a Range object      clazz = Classification()
170          """      quantiles = calculate_quantiles(_list, percents, _range)
171            adjusted = True
         quantiles = []  
         adjusted = False  
172    
173          if len(percents) != 0:      if quantiles is not None:
                                                                                 
             #  
             # 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  
174    
175                      quantiles[qindex] = newIndex          numGroups = len(quantiles[3]) - 1
                     lowerBound = quantiles[qindex]  
       
         #  
         # since quantiles is only set if the code is at least a little  
         # successful, an empty list will be generated in the case that  
         # we fail to get to the real body of the algorithm  
         #  
         if len(quantiles) == 0:  
             return None  
         else:  
             return (adjusted, minIndex, maxIndex,  
                     [(q, (q - minIndex+1) / float(numValues)) \  
                      for q in quantiles])  
176    
177  CLR  = 0          if numGroups > 0:
178  STEP = 1              adjusted = quantiles[0]
 class CustomRamp:  
179    
180      def __init__(self, prop1, prop2):              start, min, endMax, right = _range.GetRange()
         self.prop1 = prop1  
         self.prop2 = prop2  
181    
182          self.count = 0              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      def __iter__(self):                  group = ClassGroupRange(Range((start, min, max, end)), prop)
198          return self      
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      def GetRamp(self):      numValues = maxIndex - minIndex + 1
         return self  
267    
268      def SetNumGroups(self, num):      if numValues > 0:
269    
270          if num <= 0:          #
271              return False          # 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          self.count = int(num)              quantiles[index] = 0
         num = float(num)  
284    
285          prop1 = self.prop1          quantiles = quantiles.keys()
286          prop2 = self.prop2          quantiles.sort()
287    
288          clr = prop1.GetLineColor()          #
289          lineColor2 = prop2.GetLineColor()          # the current quantile index must be strictly greater than
290                    # the lowerBound
291          self.noLine = clr is not Color.Transparent \          #
292                          and lineColor2 is not Color.Transparent          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 435  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.895  
changed lines
  Added in v.1352

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26