/[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

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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26