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

Legend:
Removed from v.1128  
changed lines
  Added in v.2385

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26