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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26