/[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 1425 by jonathan, Wed Jul 16 13:21:59 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):
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    
34      clazz = Classification()      clazz = Classification()
     if numGroups == 0: return clazz  
35    
36      ramp.SetNumGroups(numGroups)      i = 0
37        maxValue = float(len(_list) - 1)
38        if maxValue < 1: maxValue = 1
39    
40      for value, prop in zip(_list, ramp):      for value in _list:
41            prop = ramp.GetProperties(i / maxValue)
42          clazz.AppendGroup(ClassGroupSingleton(value, prop))          clazz.AppendGroup(ClassGroupSingleton(value, prop))
43            i += 1
44    
45      return clazz      return clazz
46    
# Line 58  def generate_uniform_distribution(min, m Line 55  def generate_uniform_distribution(min, m
55      """      """
56    
57      clazz = Classification()      clazz = Classification()
     if numGroups == 0: return clazz  
   
     ramp.SetNumGroups(numGroups)  
58    
59      cur_min = min      cur_min = min
60    
     i = 1  
61      end = "["      end = "["
62      for prop in ramp:      maxValue = float(numGroups - 1)
63        if maxValue < 1: maxValue = 1
64    
65        for i in range(1, numGroups + 1):
66    
67            prop = ramp.GetProperties(float(i-1) / maxValue)
68    
69          if intStep:          if intStep:
70              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 76  def generate_uniform_distribution(min, m
76              end = "]"              end = "]"
77    
78          if cur_min == cur_max:          if cur_min == cur_max:
79              range = Range(("[", cur_min, cur_max, "]"))              _range = Range(("[", cur_min, cur_max, "]"))
80          else:          else:
81              range = Range(("[", cur_min, cur_max, end))              _range = Range(("[", cur_min, cur_max, end))
82    
83          clazz.AppendGroup(ClassGroupRange(range, None, prop))          clazz.AppendGroup(ClassGroupRange(_range, prop))
84    
85          cur_min = cur_max          cur_min = cur_max
         i += 1  
86    
87      return clazz      return clazz
88    
   
89  def generate_quantiles(_list, percents, ramp, _range):  def generate_quantiles(_list, percents, ramp, _range):
90      """Generates a Classification which has groups of ranges that      """Generates a Classification which has groups of ranges that
91      represent quantiles of _list at the percentages given in percents.      represent quantiles of _list at the percentages given in percents.
# Line 126  def generate_quantiles(_list, percents, Line 122  def generate_quantiles(_list, percents,
122    
123              adjusted = quantiles[0]              adjusted = quantiles[0]
124    
             ramp.SetNumGroups(numGroups)  
   
125              start, min, endMax, right = _range.GetRange()              start, min, endMax, right = _range.GetRange()
126    
127              oldp = 0              oldp = 0
128              i = 1              i = 1
129              end = "]"              end = "]"
130    
131              for (q, p), prop in zip(quantiles[3], ramp):              maxValue = float(numGroups - 1)
132                if maxValue < 1: maxValue = 1
133                for (q, p) in quantiles[3]:
134    
135                    prop = ramp.GetProperties(float(i-1) / maxValue)
136    
137                  if i == numGroups:                  if i == numGroups:
138                      max = endMax                      max = endMax
139                      end = right                      end = right
140                  else:                  else:
141                      max = _list[q]                      max = _list[q]
142    
143                  group = ClassGroupRange(Range((start, min, max, end)),                  group = ClassGroupRange(Range((start, min, max, end)), prop)
                                         None, prop)  
144            
145                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
146                                                  round(p*100, 2)))                                                  round(p*100, 2)))
# Line 187  def GenQuantiles0(_list, percents, ramp, Line 185  def GenQuantiles0(_list, percents, ramp,
185          if numGroups > 0:          if numGroups > 0:
186              adjusted = quantiles[0]              adjusted = quantiles[0]
187    
             ramp.SetNumGroups(numGroups)  
   
188              start, min, endMax, right = _range.GetRange()              start, min, endMax, right = _range.GetRange()
189    
190              class0 = quantiles[3][0]              class0 = quantiles[3][0]
# Line 197  def GenQuantiles0(_list, percents, ramp, Line 193  def GenQuantiles0(_list, percents, ramp,
193              i = 1              i = 1
194              end = "]"              end = "]"
195    
196              for (q, p), prop in zip(quantiles[3][1:], ramp):              maxValue = float(numGroups - 1)
197                if maxValue < 1: maxValue = 1
198                for (q, p) in quantiles[3][1:]:
199                    prop = ramp.GetProperties(float(i-1) / maxValue)
200    
201                  if i == numGroups:                  if i == numGroups:
202                      max = endMax                      max = endMax
203                      end = right                      end = right
204                  else:                  else:
205                      max = _list[q]                      max = _list[q]
206    
207                  group = ClassGroupRange(Range((start, min, max, end)),                  group = ClassGroupRange(Range((start, min, max, end)), prop)
                                         None, prop)  
208            
209                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),                  group.SetLabel("%s%% - %s%%" % (round(oldp*100, 2),
210                                                  round(p*100, 2)))                                                  round(p*100, 2)))
# Line 256  def calculate_quantiles(_list, percents, Line 255  def calculate_quantiles(_list, percents,
255      if len(percents) <= 1:      if len(percents) <= 1:
256          raise ValueError("percents parameter must have more than one item")          raise ValueError("percents parameter must have more than one item")
257    
258      if percents[len(percents) - 1] != 1.0:      if percents[-1] != 1.0:
259          raise ValueError("percents does not cover the entire range")          raise ValueError("percents does not cover the entire range")
260    
261      #      #
# Line 375  def calculate_quantiles(_list, percents, Line 374  def calculate_quantiles(_list, percents,
374                  [(q, (q - minIndex+1) / float(numValues)) \                  [(q, (q - minIndex+1) / float(numValues)) \
375                   for q in quantiles])                   for q in quantiles])
376    
 CLR  = 0  
 STEP = 1  
377  class CustomRamp:  class CustomRamp:
378    
379      def __init__(self, prop1, prop2):      def __init__(self, prop1, prop2):
380          self.prop1 = prop1          self.prop1 = prop1
381          self.prop2 = prop2          self.prop2 = prop2
382    
         self.count = 0  
   
     def __iter__(self):  
         return self  
   
383      def GetRamp(self):      def GetRamp(self):
384          return self          return self
385    
386      def SetNumGroups(self, num):      def GetProperties(self, index):
387            """Return a ClassGroupProperties object whose properties
388          if num <= 0:          represent a point at 'index' between prop1 and prop2 in
389              return False          the constructor.
390    
391          self.count = int(num)          index -- a value such that 0 <= index <= 1
392          num = float(num)          """
393    
394          prop1 = self.prop1          if not (0 <= index <= 1):
395          prop2 = self.prop2              raise ValueError(_("invalid index"))
396    
397          clr = prop1.GetLineColor()          newProps = ClassGroupProperties()
398          lineColor2 = prop2.GetLineColor()  
399                    self.__SetProperty(self.prop1.GetLineColor(),
400          self.noLine = clr is not Color.Transparent \                             self.prop2.GetLineColor(),
401                          and lineColor2 is not Color.Transparent                             index, newProps.SetLineColor)
402            self.__SetProperty(self.prop1.GetFill(), self.prop2.GetFill(),
403                               index, newProps.SetFill)
404          self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),  
405                                              prop2.GetLineColor(),          w = (self.prop2.GetLineWidth() - self.prop1.GetLineWidth()) \
406                                              num)              * index \
407                + self.prop1.GetLineWidth()
408          self.fillInfo = self.__GetColorInfo(prop1.GetFill(),          newProps.SetLineWidth(int(round(w)))
409                                              prop2.GetFill(),  
410                                              num)          return newProps
411    
412          self.lineWidth = prop1.GetLineWidth()      def __SetProperty(self, color1, color2, index, setf):
413          self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num  
414            if color1 is Transparent and color2 is Transparent:
415          return True              setf(Transparent)
416            elif color1 is Transparent:
417      def next(self):              setf(Color(
418          if self.count == 0:                   color2.red   * index,
419              raise StopIteration                   color2.green * index,
420                     color2.blue  * index))
421          prop = ClassGroupProperties()          elif color2 is Transparent:
422                setf(Color(
423          if self.lineInfo is None:                   color1.red   * index,
424              prop.SetLineColor(Color.Transparent)                   color1.green * index,
425                     color1.blue  * index))
426          else:          else:
427              prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,              setf(Color(
428                                      self.lineInfo[CLR][1] / 255,                  (color2.red   - color1.red)   * index + color1.red,
429                                      self.lineInfo[CLR][2] / 255))                  (color2.green - color1.green) * index + color1.green,
430                    (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]  
   
         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)  
         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)  
   
   
         return (color, step)  
431    
432  class MonochromaticRamp(CustomRamp):  class MonochromaticRamp(CustomRamp):
433      def __init__(self, start, end):      def __init__(self, start, end):
# Line 498  class MonochromaticRamp(CustomRamp): Line 441  class MonochromaticRamp(CustomRamp):
441    
442          CustomRamp.__init__(self, sp, ep)          CustomRamp.__init__(self, sp, ep)
443    
444  class GreyRamp(MonochromaticRamp):  GreyRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, 0))
445      def __init__(self):  RedRamp        = MonochromaticRamp(Color(1, 1, 1),  Color(.8, 0, 0))
446          MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))  GreenRamp      = MonochromaticRamp(Color(1, 1, 1),  Color(0, .8, 0))
447    BlueRamp       = MonochromaticRamp(Color(1, 1, 1),  Color(0, 0, .8))
448  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))  
449    
450  class HotToColdRamp:  class HotToColdRamp:
451    
     def __iter__(self):  
         return self  
           
452      def GetRamp(self):      def GetRamp(self):
453          return self          return self
454    
455      def SetNumGroups(self, num):      def GetProperties(self, index):
456          if num < 0:          """Return a ClassGroupProperties object whose properties
457              return False          represent a point at 'index' between "hot" and "cold".
458    
459          self.num = float(num)          index -- a value such that 0 <= index <= 1
460          self.index = 0          """
   
         return True  
   
     def next(self):  
         if self.index == self.num:  
             raise StopIteration  
461    
462          clr = [1.0, 1.0, 1.0]          clr = [1.0, 1.0, 1.0]
463    
464          if self.index < (.25 * self.num):          if index < .25:
465              clr[0] = 0              clr[0] = 0
466              clr[1] = 4 * self.index / self.num              clr[1] = 4 * index
467          elif self.index < (.5 * self.num):          elif index < .5:
468              clr[0] = 0              clr[0] = 0
469              clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num              clr[2] = 1 + 4 * (.25 - index)
470          elif self.index < (.75 * self.num):          elif index < .75:
471              clr[0] = 4 * (self.index - .5 * self.num) / self.num              clr[0] = 4 * (index - .5)
472              clr[2] = 0              clr[2] = 0
473          else:          else:
474              clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num              clr[1] = 1 + 4 * (.75 - index)
475              clr[2] = 0              clr[2] = 0
476    
         self.index += 1  
   
477          prop = ClassGroupProperties()          prop = ClassGroupProperties()
478          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))          prop.SetLineColor(Color(clr[0], clr[1], clr[2]))
479          prop.SetFill(Color(clr[0], clr[1], clr[2]))          prop.SetFill(Color(clr[0], clr[1], clr[2]))
480    
481          return prop          return prop
482    
483    class FixedRamp:
484        """FixedRamp allows particular properties of a ramp to be
485        held constant over the ramp.
486        """
487    
488        def __init__(self, ramp, fixes):
489            """
490            ramp -- a source ramp to get the default properties
491    
492            fixes -- a tuple (lineColor, lineWidth, fillColor) such that
493                 if any item is not None, the appropriate property will
494                 be fixed to that item value.
495            """
496    
497            self.fixes = fixes
498            self.ramp = ramp
499    
500        def GetRamp(self):
501            return self
502    
503        def GetProperties(self, index):
504            props = self.ramp.GetProperties(index)
505            if self.fixes[0] is not None: props.SetLineColor(self.fixes[0])
506            if self.fixes[1] is not None: props.SetLineWidth(self.fixes[1])
507            if self.fixes[2] is not None: props.SetFill(self.fixes[2])
508    
509            return props

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26