/[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 1157 by jonathan, Thu Jun 12 12:39:54 2003 UTC
# Line 20  from range import Range Line 20  from range import Range
20  from classification import Classification, ClassGroupSingleton, \  from classification import Classification, ClassGroupSingleton, \
21      ClassGroupRange, ClassGroupProperties      ClassGroupRange, ClassGroupProperties
22    
23  def GenSingletonsFromList(_list, numGroups, ramp):  def generate_singletons(_list, numGroups, 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 at most 'numGroups'
# Line 47  def GenSingletonsFromList(_list, numGrou Line 47  def GenSingletonsFromList(_list, numGrou
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 82  def GenUniformDistribution(min, max, num Line 62  def GenUniformDistribution(min, max, num
62    
63      ramp.SetNumGroups(numGroups)      ramp.SetNumGroups(numGroups)
64    
     step = (max - min) / float(numGroups)  
   
     if intStep:  
         step = int(step)  
   
65      cur_min = min      cur_min = min
     cur_max = cur_min + step  
66    
67      i = 0      i = 1
68      end = "["      end = "["
69      for prop in ramp:      for prop in ramp:
70    
71          if i == (numGroups - 1):          if intStep:
72                cur_max = min + int(round((i * (max - min + 1)) / float(numGroups)))
73            else:
74                cur_max = min + (i * (max - min)) / float(numGroups)
75    
76            if i == numGroups:
77              cur_max = max              cur_max = max
78              end = "]"              end = "]"
79    
80            if cur_min == cur_max:
81          # this check guards against rounding issues              range = Range(("[", cur_min, cur_max, "]"))
82          if cur_min != cur_max:          else:
83              range = Range(("[", cur_min, cur_max, end))              range = Range(("[", cur_min, cur_max, end))
84              clazz.AppendGroup(ClassGroupRange(range, None, prop))  
85            clazz.AppendGroup(ClassGroupRange(range, None, prop))
86    
87          cur_min = cur_max          cur_min = cur_max
         cur_max += step  
88          i += 1          i += 1
89    
90      return clazz      return clazz
91    
92    
93  def GenQuantiles(_list, percents, ramp, _range):  def generate_quantiles(_list, percents, ramp, _range):
94      """Generates a Classification which has groups of ranges that      """Generates a Classification which has groups of ranges that
95      represent quantiles of _list at the percentages given in percents.      represent quantiles of _list at the percentages given in percents.
96      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 102  def GenQuantiles(_list, percents, ramp,
102      _list -- a sort list of values      _list -- a sort list of values
103    
104      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
105                  represent the upper bound of each quantile                  represent the upper bound of each quantile. the
106                    union of all percentiles should be the entire
107                    range from 0.0-1.0
108    
109      ramp -- an object which implements the CustomRamp interface      ramp -- an object which implements the CustomRamp interface
110    
111      _range -- a Range object      _range -- a Range object
112    
113        Raises a Value Error if 'percents' has fewer than two items, or
114        does not cover the entire range.
115      """      """
116    
117      clazz = Classification()      clazz = Classification()
118      quantiles = CalculateQuantiles(_list, percents, _range)      quantiles = calculate_quantiles(_list, percents, _range)
119      adjusted = True      adjusted = True
120    
121      if quantiles is not None:      if quantiles is not None:
# Line 170  def GenQuantiles(_list, percents, ramp, Line 154  def GenQuantiles(_list, percents, ramp,
154    
155      return (adjusted, clazz)      return (adjusted, clazz)
156    
   
157  def GenQuantiles0(_list, percents, ramp, _range):  def GenQuantiles0(_list, percents, ramp, _range):
158      """Same as GenQuantiles, but the first class won't be added to      """Same as GenQuantiles, but the first class won't be added to
159      the classification.      the classification.
# Line 181  def GenQuantiles0(_list, percents, ramp, Line 164  def GenQuantiles0(_list, percents, ramp,
164      _list -- a sort list of values      _list -- a sort list of values
165    
166      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
167                  represent the upper bound of each quantile                  represent the upper bound of each quantile. the
168                    union of all percentiles should be the entire
169                    range from 0.0-1.0
170    
171      ramp -- an object which implements the CustomRamp interface      ramp -- an object which implements the CustomRamp interface
172    
173      _range -- a Range object      _range -- a Range object
174    
175        Raises a Value Error if 'percents' has fewer than two items, or
176        does not cover the entire range.
177      """      """
178    
179      clazz = Classification()      clazz = Classification()
180      quantiles = CalculateQuantiles(_list, percents, _range)      quantiles = calculate_quantiles(_list, percents, _range)
181      adjusted = True      adjusted = True
182    
183      if quantiles is not None:      if quantiles is not None:
# Line 230  def GenQuantiles0(_list, percents, ramp, Line 218  def GenQuantiles0(_list, percents, ramp,
218      return (adjusted, clazz, _list[class0[0]])      return (adjusted, clazz, _list[class0[0]])
219    
220    
221  def CalculateQuantiles(_list, percents, _range):  def calculate_quantiles(_list, percents, _range):
222      """Calculate quantiles for the given _list of percents from the      """Calculate quantiles for the given _list of percents from the
223      sorted list of values that are in range.      sorted list of values that are in range.
224                                                                                                                                                            
# Line 252  def CalculateQuantiles(_list, percents, Line 240  def CalculateQuantiles(_list, percents,
240      _list -- a sort list of values      _list -- a sort list of values
241    
242      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
243                  represent the upper bound of each quantile                  represent the upper bound of each quantile. the
244                    union of all percentiles should be the entire
245                    range from 0.0-1.0
246    
247      _range -- a Range object      _range -- a Range object
248    
249        Raises a Value Error if 'percents' has fewer than two items, or
250        does not cover the entire range.
251      """      """
252    
253      quantiles = []      quantiles = []
254      adjusted = False      adjusted = False
255    
256      if len(percents) != 0:      if len(percents) <= 1:
257                                                                                      raise ValueError("percents parameter must have more than one item")
258    
259        if percents[len(percents) - 1] != 1.0:
260            raise ValueError("percents does not cover the entire range")
261    
262        #
263        # find what part of the _list range covers
264        #
265        minIndex = -1
266        maxIndex = -2
267        for i in xrange(0, len(_list), 1):
268            if operator.contains(_range, _list[i]):
269                minIndex = i
270                break
271    
272        for i in xrange(len(_list)-1, -1, -1):
273            if operator.contains(_range, _list[i]):
274                maxIndex = i
275                break
276    
277        numValues = maxIndex - minIndex + 1
278    
279        if numValues > 0:
280    
281          #          #
282          # find what part of the _list range covers          # build a list of unique indices into list of where each
283            # quantile *should* be. set adjusted if the resulting
284            # indices are different
285          #          #
286          minIndex = -1          quantiles = {}
287          maxIndex = -2          for p in percents:
288          for i in xrange(0, len(_list), 1):              index = min(minIndex + int(p*numValues)-1, maxIndex)
289              if operator.contains(_range, _list[i]):  
290                  minIndex = i              adjusted = adjusted \
291                  break                  or quantiles.has_key(index) \
292                    or ((index - minIndex + 1) / float(numValues)) != p
293    
294          for i in xrange(len(_list)-1, -1, -1):              quantiles[index] = 0
295              if operator.contains(_range, _list[i]):  
296                  maxIndex = i          quantiles = quantiles.keys()
297                  break          quantiles.sort()
298    
299            #
300            # the current quantile index must be strictly greater than
301            # the lowerBound
302            #
303            lowerBound = minIndex - 1
304    
305          numValues = maxIndex - minIndex + 1          for qindex in xrange(len(quantiles)):
306                if lowerBound >= maxIndex:
307                    # discard higher quantiles
308                    quantiles = quantiles[:qindex]
309                    break
310    
311          if numValues > 0:              # lowerBound + 1 is always a valid index
312    
313              #              #
314              # build a list of unique indices into list of where each              # bump up the current quantile index to be a usable index
315              # quantile *should* be. set adjusted if the resulting              # if it currently falls below the lowerBound
             # indices are different  
316              #              #
317              quantiles = {}              if quantiles[qindex] <= lowerBound:
318              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  
   
                 quantiles[index] = 0  
319    
320              quantiles = quantiles.keys()              listIndex = quantiles[qindex]
321              quantiles.sort()              value = _list[listIndex]
322    
323              #              #
324              # the current quantile index must be strictly greater than              # look for similar values around the quantile index
             # the lowerBound  
325              #              #
326              lowerBound = minIndex - 1              lindex = listIndex - 1
327                while lindex > lowerBound and value == _list[lindex]:
328              for qindex in xrange(len(quantiles)):                  lindex -= 1
329                  if lowerBound >= maxIndex:              lcount = (listIndex - 1) - lindex
330                      # discard higher quantiles  
331                      quantiles = quantiles[:qindex]              rindex = listIndex + 1
332                      break              while rindex < maxIndex + 1 and value == _list[rindex]:
333                    rindex += 1
334                  # lowerBound + 1 is always a valid index              rcount = (listIndex + 1) - rindex
   
                 #  
                 # bump up the current quantile index to be a usable index  
                 # if it currently falls below the lowerBound  
                 #  
                 if quantiles[qindex] <= lowerBound:  
                     quantiles[qindex] = lowerBound + 1  
       
                 listIndex = quantiles[qindex]  
                 value = _list[listIndex]  
335    
336                  #              #
337                  # look for similar values around the quantile index              # adjust the current quantile index based on how many
338                  #              # numbers in the _list are the same as the current value
339                  lindex = listIndex - 1              #
340                  while lindex > lowerBound and value == _list[lindex]:              newIndex = listIndex
341                      lindex -= 1              if lcount == rcount:
342                  lcount = (listIndex - 1) - lindex                  if lcount != 0:
343                        #
344                  rindex = listIndex + 1                      # there are an equal number of numbers to the left
345                  while rindex < maxIndex + 1 and value == _list[rindex]:                      # and right, try going to the left first unless
                     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  
346                      # doing so creates an empty quantile.                      # doing so creates an empty quantile.
347                        #
348                      if lindex != lowerBound:                      if lindex != lowerBound:
349                          newIndex = lindex                          newIndex = lindex
350                      else:                      else:
351                          newIndex = rindex - 1                          newIndex = rindex - 1
352    
353                  elif rcount < lcount:              elif lcount < rcount:
354                      # there are fewer items to the right, so go to the right                  # there are fewer items to the left, so
355                    # try going to the left first unless
356                    # doing so creates an empty quantile.
357                    if lindex != lowerBound:
358                        newIndex = lindex
359                    else:
360                      newIndex = rindex - 1                      newIndex = rindex - 1
361    
362                  adjusted = adjusted or newIndex != listIndex              elif rcount < lcount:
363                    # there are fewer items to the right, so go to the right
364                    newIndex = rindex - 1
365    
366                  quantiles[qindex] = newIndex              adjusted = adjusted or newIndex != listIndex
367                  lowerBound = quantiles[qindex]  
368                quantiles[qindex] = newIndex
369                lowerBound = quantiles[qindex]
370    
371      if len(quantiles) == 0:      if len(quantiles) == 0:
372          return None          return None
# Line 482  class CustomRamp: Line 479  class CustomRamp:
479              color = [color1.red   * 255,              color = [color1.red   * 255,
480                       color1.green * 255,                       color1.green * 255,
481                       color1.blue  * 255]                       color1.blue  * 255]
482              step = ((color2.red   * 255 - color1.red   * 255)   / numGroups,              step = ((color2.red   * 255 - color1.red   * 255) / numGroups,
483                      (color2.green * 255 - color1.green * 255) / numGroups,                      (color2.green * 255 - color1.green * 255) / numGroups,
484                      (color2.blue  * 255 - color1.blue  * 255)  / numGroups)                      (color2.blue  * 255 - color1.blue  * 255) / numGroups)
485    
486    
487          return (color, step)          return (color, step)
# Line 564  class HotToColdRamp: Line 561  class HotToColdRamp:
561          prop.SetFill(Color(clr[0], clr[1], clr[2]))          prop.SetFill(Color(clr[0], clr[1], clr[2]))
562    
563          return prop          return prop
   
 #class Colors16Ramp:  
 #  
     #def __iter__(self):  
         #return self  
 #  
     #def GetRamp(self):  
         #return self  
 #  
     #def SetNumGroups(self, num):  
         #if num < 0:  
             #return False  
 #  
         #self.index = 0  
 #  
         #return True  

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26