/[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 1157 by jonathan, Thu Jun 12 12:39:54 2003 UTC revision 1387 by jonathan, Thu Jul 10 14:53:03 2003 UTC
# Line 15  __version__ = "$Revision$" Line 15  __version__ = "$Revision$"
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  def generate_singletons(_list, numGroups, ramp):  def generate_singletons(_list, ramp, fixes=(None, None, None)):
24      """Generate a new classification consisting solely of singletons.      """Generate a new classification consisting solely of singletons.
25    
26      The resulting classification will consist of at most 'numGroups'      The resulting classification will consist of one group for each
27      groups whose group properties ramp between 'prop1' and 'prop2'. There      item in _list whose properties ramp between 'prop1' and 'prop2'.
28      could be fewer groups if '_list' contains fewer that 'numGroups' items.  
29        _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.  
30    
31      ramp -- an object which implements the CustomRamp interface      ramp -- an object which implements the CustomRamp interface
32    
33        fixes -- a tuple (lineColor, lineWidth, fillColor) such that
34                 if any item is not None, the appropriate property will
35                 be fixed to that item value.
36      """      """
37    
38      clazz = Classification()      clazz = Classification()
     if numGroups == 0: return clazz  
39    
40      ramp.SetNumGroups(numGroups)      i = 0
41        maxValue = float(len(_list) - 1)
42      for value, prop in zip(_list, ramp):      if maxValue < 1: maxValue = 1
43    
44        for value in _list:
45            prop = ramp.GetProperties(i / maxValue)
46            if fixes[0] is not None: prop.SetLineColor(fixes[0])
47            if fixes[1] is not None: prop.SetLineWidth(fixes[1])
48            if fixes[2] is not None: prop.SetFill(fixes[2])
49          clazz.AppendGroup(ClassGroupSingleton(value, prop))          clazz.AppendGroup(ClassGroupSingleton(value, prop))
50            i += 1
51    
52      return clazz      return clazz
53    
54  def generate_uniform_distribution(min, max, numGroups, ramp, intStep = False):  def generate_uniform_distribution(min, max, numGroups, ramp, intStep = False,
55                                      fixes = (None, None, None)):
56      """Generate a classification with numGroups range groups      """Generate a classification with numGroups range groups
57      each with the same interval.      each with the same interval.
58    
# Line 55  def generate_uniform_distribution(min, m Line 60  def generate_uniform_distribution(min, m
60                 Useful if the values are integers but the                 Useful if the values are integers but the
61                 number of groups specified doesn't evenly                 number of groups specified doesn't evenly
62                 divide (max - min).                 divide (max - min).
63    
64        fixes -- a tuple (lineColor, lineWidth, fillColor) such that
65                 if any item is not None, the appropriate property will
66                 be fixed to that item value.
67      """      """
68    
69      clazz = Classification()      clazz = Classification()
     if numGroups == 0: return clazz  
   
     ramp.SetNumGroups(numGroups)  
70    
71      cur_min = min      cur_min = min
72    
     i = 1  
73      end = "["      end = "["
74      for prop in ramp:      maxValue = float(numGroups - 1)
75        if maxValue < 1: maxValue = 1
76    
77        for i in range(1, numGroups + 1):
78    
79            prop = ramp.GetProperties(float(i-1) / maxValue)
80    
81          if intStep:          if intStep:
82              cur_max = min + int(round((i * (max - min + 1)) / float(numGroups)))              cur_max = min + int(round((i * (max - min + 1)) / float(numGroups)))
# Line 78  def generate_uniform_distribution(min, m Line 88  def generate_uniform_distribution(min, m
88              end = "]"              end = "]"
89    
90          if cur_min == cur_max:          if cur_min == cur_max:
91              range = Range(("[", cur_min, cur_max, "]"))              _range = Range(("[", cur_min, cur_max, "]"))
92          else:          else:
93              range = Range(("[", cur_min, cur_max, end))              _range = Range(("[", cur_min, cur_max, end))
94    
95            if fixes[0] is not None: prop.SetLineColor(fixes[0])
96            if fixes[1] is not None: prop.SetLineWidth(fixes[1])
97            if fixes[2] is not None: prop.SetFill(fixes[2])
98    
99          clazz.AppendGroup(ClassGroupRange(range, None, prop))          clazz.AppendGroup(ClassGroupRange(_range, prop))
100    
101          cur_min = cur_max          cur_min = cur_max
         i += 1  
102    
103      return clazz      return clazz
104    
105    def generate_quantiles(_list, percents, ramp, _range, fixes=(None, None, None)):
 def generate_quantiles(_list, percents, ramp, _range):  
106      """Generates a Classification which has groups of ranges that      """Generates a Classification which has groups of ranges that
107      represent quantiles of _list at the percentages given in percents.      represent quantiles of _list at the percentages given in percents.
108      Only the values that fall within _range are considered.      Only the values that fall within _range are considered.
# Line 110  def generate_quantiles(_list, percents, Line 122  def generate_quantiles(_list, percents,
122    
123      _range -- a Range object      _range -- a Range object
124    
125        fixes -- a tuple (lineColor, lineWidth, fillColor) such that
126                 if any item is not None, the appropriate property will
127                 be fixed to that item value.
128    
129      Raises a Value Error if 'percents' has fewer than two items, or      Raises a Value Error if 'percents' has fewer than two items, or
130      does not cover the entire range.      does not cover the entire range.
131      """      """
# Line 126  def generate_quantiles(_list, percents, Line 142  def generate_quantiles(_list, percents,
142    
143              adjusted = quantiles[0]              adjusted = quantiles[0]
144    
             ramp.SetNumGroups(numGroups)  
   
145              start, min, endMax, right = _range.GetRange()              start, min, endMax, right = _range.GetRange()
146    
147              oldp = 0              oldp = 0
148              i = 1              i = 1
149              end = "]"              end = "]"
150    
151              for (q, p), prop in zip(quantiles[3], ramp):              maxValue = float(numGroups - 1)
152                if maxValue < 1: maxValue = 1
153                for (q, p) in quantiles[3]:
154    
155                    prop = ramp.GetProperties(float(i-1) / maxValue)
156    
157                  if i == numGroups:                  if i == numGroups:
158                      max = endMax                      max = endMax
159                      end = right                      end = right
160                  else:                  else:
161                      max = _list[q]                      max = _list[q]
162    
163                  group = ClassGroupRange(Range((start, min, max, end)),                  if fixes[0] is not None: prop.SetLineColor(fixes[0])
164                                          None, prop)                  if fixes[1] is not None: prop.SetLineWidth(fixes[1])
165                    if fixes[2] is not None: prop.SetFill(fixes[2])
166    
167                    group = ClassGroupRange(Range((start, min, max, end)), prop)
168            
169                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
170                                                  round(p*100, 2)))                                                  round(p*100, 2)))
# Line 187  def GenQuantiles0(_list, percents, ramp, Line 209  def GenQuantiles0(_list, percents, ramp,
209          if numGroups > 0:          if numGroups > 0:
210              adjusted = quantiles[0]              adjusted = quantiles[0]
211    
             ramp.SetNumGroups(numGroups)  
   
212              start, min, endMax, right = _range.GetRange()              start, min, endMax, right = _range.GetRange()
213    
214              class0 = quantiles[3][0]              class0 = quantiles[3][0]
# Line 197  def GenQuantiles0(_list, percents, ramp, Line 217  def GenQuantiles0(_list, percents, ramp,
217              i = 1              i = 1
218              end = "]"              end = "]"
219    
220              for (q, p), prop in zip(quantiles[3][1:], ramp):              maxValue = float(numGroups - 1)
221                if maxValue < 1: maxValue = 1
222                for (q, p) in quantiles[3][1:]:
223                    prop = ramp.GetProperties(float(i-1) / maxValue)
224    
225                  if i == numGroups:                  if i == numGroups:
226                      max = endMax                      max = endMax
227                      end = right                      end = right
228                  else:                  else:
229                      max = _list[q]                      max = _list[q]
230    
231                  group = ClassGroupRange(Range((start, min, max, end)),                  group = ClassGroupRange(Range((start, min, max, end)), prop)
                                         None, prop)  
232            
233                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
234                                                  round(p*100, 2)))                                                  round(p*100, 2)))
# Line 256  def calculate_quantiles(_list, percents, Line 279  def calculate_quantiles(_list, percents,
279      if len(percents) <= 1:      if len(percents) <= 1:
280          raise ValueError("percents parameter must have more than one item")          raise ValueError("percents parameter must have more than one item")
281    
282      if percents[len(percents) - 1] != 1.0:      if percents[-1] != 1.0:
283          raise ValueError("percents does not cover the entire range")          raise ValueError("percents does not cover the entire range")
284    
285      #      #
# Line 375  def calculate_quantiles(_list, percents, Line 398  def calculate_quantiles(_list, percents,
398                  [(q, (q - minIndex+1) / float(numValues)) \                  [(q, (q - minIndex+1) / float(numValues)) \
399                   for q in quantiles])                   for q in quantiles])
400    
 CLR  = 0  
 STEP = 1  
401  class CustomRamp:  class CustomRamp:
402    
403      def __init__(self, prop1, prop2):      def __init__(self, prop1, prop2):
404          self.prop1 = prop1          self.prop1 = prop1
405          self.prop2 = prop2          self.prop2 = prop2
406    
         self.count = 0  
   
     def __iter__(self):  
         return self  
   
407      def GetRamp(self):      def GetRamp(self):
408          return self          return self
409    
410      def SetNumGroups(self, num):      def GetProperties(self, index):
411            """Return a ClassGroupProperties object whose properties
412          if num <= 0:          represent a point at 'index' between prop1 and prop2 in
413              return False          the constructor.
414    
415          self.count = int(num)          index -- a value such that 0 <= index <= 1
416          num = float(num)          """
417    
418          prop1 = self.prop1          if not (0 <= index <= 1):
419          prop2 = self.prop2              raise ValueError(_("invalid index"))
420    
421          clr = prop1.GetLineColor()          newProps = ClassGroupProperties()
422          lineColor2 = prop2.GetLineColor()  
423                    self.__SetProperty(self.prop1.GetLineColor(),
424          self.noLine = clr is not Color.Transparent \                             self.prop2.GetLineColor(),
425                          and lineColor2 is not Color.Transparent                             index, newProps.SetLineColor)
426            self.__SetProperty(self.prop1.GetFill(), self.prop2.GetFill(),
427                               index, newProps.SetFill)
428          self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),  
429                                              prop2.GetLineColor(),          w = (self.prop2.GetLineWidth() - self.prop1.GetLineWidth()) \
430                                              num)              * index \
431                + self.prop1.GetLineWidth()
432          self.fillInfo = self.__GetColorInfo(prop1.GetFill(),          newProps.SetLineWidth(int(round(w)))
433                                              prop2.GetFill(),  
434                                              num)          return newProps
435    
436          self.lineWidth = prop1.GetLineWidth()      def __SetProperty(self, color1, color2, index, setf):
437          self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num  
438            if color1 is Transparent and color2 is Transparent:
439          return True              setf(Transparent)
440            elif color1 is Transparent:
441      def next(self):              setf(Color(
442          if self.count == 0:                   color2.red   * index,
443              raise StopIteration                   color2.green * index,
444                     color2.blue  * index))
445          prop = ClassGroupProperties()          elif color2 is Transparent:
446                setf(Color(
447          if self.lineInfo is None:                   color1.red   * index,
448              prop.SetLineColor(Color.Transparent)                   color1.green * index,
449          else:                   color1.blue  * index))
             prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,  
                                     self.lineInfo[CLR][1] / 255,  
                                     self.lineInfo[CLR][2] / 255))  
   
             self.lineInfo[CLR][0] += self.lineInfo[STEP][0]  
             self.lineInfo[CLR][1] += self.lineInfo[STEP][1]  
             self.lineInfo[CLR][2] += self.lineInfo[STEP][2]  
   
         if self.fillInfo is None:  
             prop.SetFill(Color.Transparent)  
         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)  
450          else:          else:
451              color = [color1.red   * 255,              setf(Color(
452                       color1.green * 255,                  (color2.red   - color1.red)   * index + color1.red,
453                       color1.blue  * 255]                  (color2.green - color1.green) * index + color1.green,
454              step = ((color2.red   * 255 - color1.red   * 255) / numGroups,                  (color2.blue  - color1.blue)  * index + color1.blue))
                     (color2.green * 255 - color1.green * 255) / numGroups,  
                     (color2.blue  * 255 - color1.blue  * 255) / numGroups)  
   
   
         return (color, step)  
455    
456  class MonochromaticRamp(CustomRamp):  class MonochromaticRamp(CustomRamp):
457      def __init__(self, start, end):      def __init__(self, start, end):
# Line 498  class MonochromaticRamp(CustomRamp): Line 465  class MonochromaticRamp(CustomRamp):
465    
466          CustomRamp.__init__(self, sp, ep)          CustomRamp.__init__(self, sp, ep)
467    
468  class GreyRamp(MonochromaticRamp):  GreyRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, 0))
469      def __init__(self):  RedRamp        = MonochromaticRamp(Color(1, 1, 1),  Color(.8, 0, 0))
470          MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))  GreenRamp      = MonochromaticRamp(Color(1, 1, 1),  Color(0, .8, 0))
471    BlueRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, .8))
472  class RedRamp(MonochromaticRamp):  GreenToRedRamp = 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))  
473    
474  class HotToColdRamp:  class HotToColdRamp:
475    
     def __iter__(self):  
         return self  
           
476      def GetRamp(self):      def GetRamp(self):
477          return self          return self
478    
479      def SetNumGroups(self, num):      def GetProperties(self, index):
480          if num < 0:          """Return a ClassGroupProperties object whose properties
481              return False          represent a point at 'index' between "hot" and "cold".
482    
483          self.num = float(num)          index -- a value such that 0 <= index <= 1
484          self.index = 0          """
   
         return True  
   
     def next(self):  
         if self.index == self.num:  
             raise StopIteration  
485    
486          clr = [1.0, 1.0, 1.0]          clr = [1.0, 1.0, 1.0]
487    
488          if self.index < (.25 * self.num):          if index < .25:
489              clr[0] = 0              clr[0] = 0
490              clr[1] = 4 * self.index / self.num              clr[1] = 4 * index
491          elif self.index < (.5 * self.num):          elif index < .5:
492              clr[0] = 0              clr[0] = 0
493              clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num              clr[2] = 1 + 4 * (.25 - index)
494          elif self.index < (.75 * self.num):          elif index < .75:
495              clr[0] = 4 * (self.index - .5 * self.num) / self.num              clr[0] = 4 * (index - .5)
496              clr[2] = 0              clr[2] = 0
497          else:          else:
498              clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num              clr[1] = 1 + 4 * (.75 - index)
499              clr[2] = 0              clr[2] = 0
500    
         self.index += 1  
   
501          prop = ClassGroupProperties()          prop = ClassGroupProperties()
502          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))
503          prop.SetFill(Color(clr[0], clr[1], clr[2]))          prop.SetFill(Color(clr[0], clr[1], clr[2]))
504    
505          return prop          return prop
506    

Legend:
Removed from v.1157  
changed lines
  Added in v.1387

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26