/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 711 by jonathan, Wed Apr 23 08:46:23 2003 UTC revision 877 by jonathan, Fri May 9 16:32:17 2003 UTC
# Line 18  from Thuban.Model.table import Table, FI Line 18  from Thuban.Model.table import Table, FI
18       FIELDTYPE_STRING       FIELDTYPE_STRING
19    
20  from Thuban.Model.color import Color  from Thuban.Model.color import Color
21    from Thuban.Model.range import Range
22    
23  import classifier  import classifier, resource
24    
25  import resource  from Thuban.Model.classgen import ClassGenerator, \
26        CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
27  from Thuban.common import Str2Num      HotToColdRamp
   
 ID_CLASSGEN_GEN = 4001  
 ID_CLASSGEN_CLOSE = 4002  
 ID_CLASSGEN_GENCOMBO = 4007  
 ID_CLASSGEN_PROPCOMBO = 4008  
28    
29  USEALL_BMP  = "group_use_all"  USEALL_BMP  = "group_use_all"
30  USE_BMP     = "group_use"  USE_BMP     = "group_use"
# Line 37  USENONE_BMP = "group_use_none" Line 33  USENONE_BMP = "group_use_none"
33    
34  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
35  GENCOMBOSTR_UNIQUE = _("Unique Values")  GENCOMBOSTR_UNIQUE = _("Unique Values")
36    GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
37    
38  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")
39  PROPCOMBOSTR_GREY       = _("Grey Ramp")  PROPCOMBOSTR_GREY       = _("Grey Ramp")
40  PROPCOMBOSTR_RED        = _("Red Ramp")  PROPCOMBOSTR_RED        = _("Red Ramp")
41  PROPCOMBOSTR_GREEN      = _("Green Ramp")  PROPCOMBOSTR_GREEN      = _("Green Ramp")
42  PROPCOMBOSTR_BLUE       = _("Blue Ramp")  PROPCOMBOSTR_BLUE       = _("Blue Ramp")
43    PROPCOMBOSTR_GREEN2RED  = _("Green-to-Red Ramp")
44  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")
45    
46    ID_CLASSGEN_GENCOMBO = 4007
47    ID_CLASSGEN_PROPCOMBO = 4008
48    
49  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
50                                                                                    
51      def __init__(self, parent, layer, fieldName):      def __init__(self, parent, layer, fieldName):
52          """Inialize the class generating dialog.          """Inialize the class generating dialog.
53    
# Line 55  class ClassGenDialog(wxDialog): Line 56  class ClassGenDialog(wxDialog):
56    
57          wxDialog.__init__(self, parent, -1, _("Generate Classification"),          wxDialog.__init__(self, parent, -1, _("Generate Classification"),
58                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
59                                                                                    
60          self.parent = parent          self.parent = parent
61            self.layer = layer
62          self.clazz = None          self.clazz = None
63    
64          self.type, name, width, prec = layer.table.field_info_by_name(fieldName)          col = layer.table.Column(fieldName)
65            self.type = col.type
66    
67            self.fieldName = fieldName
68            self.fieldType = self.type
69    
70            self.curGenPanel = None
71    
72            self.genpanels = []
73    
74          #############          #############
75          # we need to create genButton first because when we create the          # we need to create genButton first because when we create the
76          # panels they will call AllowGenerate() which uses genButton.          # panels they will call AllowGenerate() which uses genButton.
77          #          #
78          buttonSizer = wxBoxSizer(wxHORIZONTAL)          self.genButton = wxButton(self, wxID_OK, _("Generate"))
79          self.genButton = wxButton(self, ID_CLASSGEN_GEN, _("Generate"))          self.genButton.SetDefault()
80            self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
81    
82          buttonSizer.Add(self.genButton, 0, wxALL, 4)          self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
83          buttonSizer.Add(60, 20, 0, wxALL, 4)          if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
84          buttonSizer.Add(wxButton(self, ID_CLASSGEN_CLOSE, _("Close")),              self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
85                          0, wxALL, 4)              self.genpanels.append((GENCOMBOSTR_QUANTILES, GenQuantilesPanel))
86    
87            for name, clazz in self.genpanels:
88                self.genChoice.Append(name, [clazz, None])
89    
90            self.genChoice.SetSelection(0)
91    
92            self.propPanel = None
93            custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
94    
95            self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
96            self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())
97            self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())
98            self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
99            self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())
100            self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())
101            self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
102            self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
103    
104            self.propCombo.SetSelection(0)
105    
106          #############          #############
107    
# Line 87  class ClassGenDialog(wxDialog): Line 117  class ClassGenDialog(wxDialog):
117          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
118          psizer.Add(wxStaticText(self, -1, _("Generate:")),          psizer.Add(wxStaticText(self, -1, _("Generate:")),
119              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
120            psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
         self.genCombo = wxChoice(self, ID_CLASSGEN_GENCOMBO)  
         psizer.Add(self.genCombo, 1, wxALL | wxGROW, 4)  
         EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)  
121    
122          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
123    
124          #############          self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
125            sizer.Add(self.sizer_genPanel, 1, wxGROW | wxALL, 4)
         self.genPanel = None  
   
         panel = GenUniquePanel(self, layer, fieldName, self.type)  
         self.genCombo.Append(GENCOMBOSTR_UNIQUE, panel)  
         sizer.Add(panel, 1, wxGROW | wxALL, 4)  
   
         self.genPanel = panel  
   
         if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):  
             panel = GenUniformPanel(self, layer, fieldName, self.type)  
             self.genCombo.Append(GENCOMBOSTR_UNIFORM, panel)  
             sizer.Add(panel, 1, wxGROW | wxALL, 4)  
             sizer.Show(panel, False)  
   
         self.genCombo.SetSelection(0)  
   
         #############  
126    
127          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
128          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
129              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
   
         self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)  
130          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
         EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)  
131          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
132    
133          #############          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
134            sizer.Show(custom_ramp_panel, False)
         self.propPanel = None  
         panel = CustomRampPanel(self, layer.ShapeType())  
         sizer.Add(panel, 1, wxALL | wxGROW, 4)  
         sizer.Show(panel, False)  
   
         self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())  
         self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())  
         self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())  
         self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())  
         self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())  
         self.propCombo.Append(PROPCOMBOSTR_CUSTOM, panel)  
   
         self.propCombo.SetSelection(0)  
   
   
         #############  
135    
136            buttonSizer = wxBoxSizer(wxHORIZONTAL)
137            buttonSizer.Add(self.genButton, 0, wxALL, 4)
138            buttonSizer.Add(60, 20, 0, wxALL, 4)
139            buttonSizer.Add(wxButton(self, wxID_CANCEL, _("Close")),
140                            0, wxALL, 4)
141          sizer.Add(buttonSizer, 0,          sizer.Add(buttonSizer, 0,
142                    wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)                    wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)
143    
   
144          self.SetSizer(sizer)          self.SetSizer(sizer)
145          self.SetAutoLayout(True)          self.SetAutoLayout(True)
146          sizer.SetSizeHints(self)          sizer.SetSizeHints(self)
147    
148          self.sizer = sizer          self.topBox = sizer
149    
150          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)          self.__DoOnGenTypeSelect()
151          EVT_BUTTON(self, ID_CLASSGEN_CLOSE, self._OnCloseBtn)  
152            EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
153            EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
154            EVT_BUTTON(self, wxID_OK, self.OnOK)
155            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
156    
157            self.__DoOnGenTypeSelect()
158    
159            self.genChoice.SetFocus()
160    
161      def GetClassification(self):      def GetClassification(self):
162          return self.clazz          return self.clazz
# Line 161  class ClassGenDialog(wxDialog): Line 164  class ClassGenDialog(wxDialog):
164      def AllowGenerate(self, on):      def AllowGenerate(self, on):
165          pass #self.genButton.Enable(on)          pass #self.genButton.Enable(on)
166    
167      def _OnGenerate(self, event):      def OnOK(self, event):
168            """This is really the generate button, but we want to override
169            the wxDialog class.
170            """
171    
172            index = self.genChoice.GetSelection()
173    
174          index = self.genCombo.GetSelection()          assert index != -1, "button should be disabled!"
175    
176          genSel = self.genCombo.GetString(index)          genSel = self.genChoice.GetString(index)
177          genPanel = self.genCombo.GetClientData(index)          clazz, genPanel = self.genChoice.GetClientData(index)
178    
179          propPanel = self.propPanel          propPanel = self.propPanel
180    
181          if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):          if genSel in (GENCOMBOSTR_UNIFORM,          \
182                          GENCOMBOSTR_UNIQUE,           \
183                          GENCOMBOSTR_QUANTILES):
184    
185              numGroups = genPanel.GetNumGroups()              numGroups = genPanel.GetNumGroups()
186    
187              index = self.propCombo.GetSelection()              index = self.propCombo.GetSelection()
# Line 207  class ClassGenDialog(wxDialog): Line 218  class ClassGenDialog(wxDialog):
218    
219                      self.parent._SetClassification(self.clazz)                      self.parent._SetClassification(self.clazz)
220    
221      def _OnCloseBtn(self, event):              elif genSel == GENCOMBOSTR_QUANTILES:
222    
223                    _range = genPanel.GetRange()
224                    _list = genPanel.GetList()
225                    _list.sort()
226    
227                    delta = 1 / float(numGroups)
228                    percents = [delta * i for i in range(1, numGroups + 1)]
229                    adjusted, self.clazz = \
230                        ClassGenerator().GenQuantiles(_list, percents, ramp, _range)
231    
232                    if adjusted:
233                        dlg = wxMessageDialog(self,
234                            _("Based on the data from the table and the input\n" +
235                              "values, the exact quantiles could not be generated.\n\n" +
236                              "Accept a close estimate?"),
237                            _("Problem with Quantiles"),
238    
239                            wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
240                        if dlg.ShowModal() == wxID_YES:
241                            self.parent._SetClassification(self.clazz)
242                    else:
243                        self.parent._SetClassification(self.clazz)
244    
245        def OnCancel(self, event):
246          self.Close()          self.Close()
247    
248      def _OnGenTypeSelect(self, event):      def _OnGenTypeSelect(self, event):
249            self.__DoOnGenTypeSelect()
250            return
251    
252          combo = event.GetEventObject()          combo = event.GetEventObject()
253    
254          selIndex = combo.GetSelection()          selIndex = combo.GetSelection()
255    
256          if self.genPanel is not None:          if self.genPanel is not None:
257              self.sizer.Show(self.genPanel, False)              self.topBox.Show(self.genPanel, False)
258    
259          self.genPanel = combo.GetClientData(selIndex)          self.genPanel = combo.GetClientData(selIndex)
260          if self.genPanel is not None:          if self.genPanel is not None:
261              self.sizer.Show(self.genPanel, True)              self.topBox.Show(self.genPanel, True)
262    
263          self.sizer.SetSizeHints(self)          self.topBox.SetSizeHints(self)
264          self.sizer.Layout()          self.topBox.Layout()
265    
266      def _OnPropTypeSelect(self, event):      def _OnPropTypeSelect(self, event):
267          combo = event.GetEventObject()          combo = event.GetEventObject()
# Line 233  class ClassGenDialog(wxDialog): Line 270  class ClassGenDialog(wxDialog):
270          sel = combo.GetString(selIndex)          sel = combo.GetString(selIndex)
271    
272          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
273              self.sizer.Show(self.propPanel, False)              self.topBox.Show(self.propPanel, False)
274    
275          self.propPanel = combo.GetClientData(selIndex)          self.propPanel = combo.GetClientData(selIndex)
276    
277          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
278              self.sizer.Show(self.propPanel, True)              self.topBox.Show(self.propPanel, True)
279    
280            self.topBox.SetSizeHints(self)
281            self.topBox.Layout()
282    
283        def __DoOnGenTypeSelect(self):
284            choice = self.genChoice
285    
286          self.sizer.SetSizeHints(self)          sel = choice.GetSelection()
287          self.sizer.Layout()          if sel == -1: return
288    
289            clazz, obj = choice.GetClientData(sel)
290    
291            if obj is None:
292                obj = clazz(self, self.layer, self.fieldName, self.fieldType)
293                choice.SetClientData(sel, [clazz, obj])
294    
295            if self.curGenPanel is not None:
296                self.curGenPanel.Hide()
297                self.sizer_genPanel.Remove(self.curGenPanel)
298    
299            self.curGenPanel = obj
300            self.curGenPanel.Show()
301    
302            self.sizer_genPanel.Add(self.curGenPanel, 1,
303                wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
304            self.sizer_genPanel.Layout()
305            self.Layout()
306            self.topBox.SetSizeHints(self)
307    
308  ID_UNIFORM_MIN = 4001  ID_UNIFORM_MIN = 4001
309  ID_UNIFORM_MAX = 4002  ID_UNIFORM_MAX = 4002
# Line 438  class GenUniformPanel(wxPanel): Line 499  class GenUniformPanel(wxPanel):
499      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
500    
501          if self.layer.table is not None:          if self.layer.table is not None:
502              range = self.layer.table.field_range(self.fieldName)              wxBeginBusyCursor()
503              self.minCtrl.SetValue(str(range[0][0]))              min, max = self.layer.table.ValueRange(self.fieldName)
504              self.maxCtrl.SetValue(str(range[1][0]))              self.minCtrl.SetValue(str(min))
505                self.maxCtrl.SetValue(str(max))
506                wxEndBusyCursor()
507    
508      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
509    
# Line 482  class GenUniformPanel(wxPanel): Line 545  class GenUniformPanel(wxPanel):
545          return valid          return valid
546    
547      def __CalcStepping(self, min, max, ngroups):      def __CalcStepping(self, min, max, ngroups):
548          step = Str2Num(str((max - min) / float(ngroups)))          step = (max - min) / float(ngroups)
549          if self.fieldType == FIELDTYPE_INT:          if self.fieldType == FIELDTYPE_INT:
550              step = int(step)              step = int(step)
551    
# Line 603  class GenUniquePanel(wxPanel): Line 666  class GenUniquePanel(wxPanel):
666    
667          self.parent.AllowGenerate(False)          self.parent.AllowGenerate(False)
668    
         self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]  
   
669      def GetNumGroups(self):      def GetNumGroups(self):
670          return self.list_use.GetItemCount()          return self.list_use.GetItemCount()
671    
# Line 644  class GenUniquePanel(wxPanel): Line 705  class GenUniquePanel(wxPanel):
705          self.list_avail.DeleteAllItems()          self.list_avail.DeleteAllItems()
706          self.list_avail_data = []          self.list_avail_data = []
707    
708          list = self.layer.table.GetUniqueValues(self.fieldName)          list = self.layer.table.UniqueValues(self.fieldName)
709          index = 0          index = 0
710          for v in list:          for v in list:
711              self.dataList.append(v)              self.dataList.append(v)
# Line 699  class GenUniquePanel(wxPanel): Line 760  class GenUniquePanel(wxPanel):
760  #       list.SetColumnWidth(0, event.GetSize().GetWidth())  #       list.SetColumnWidth(0, event.GetSize().GetWidth())
761  #        #      
762    
763    ID_QUANTILES_RANGE = 4001
764    ID_QUANTILES_RETRIEVE = 4002
765    
766    class GenQuantilesPanel(wxPanel):
767    
768        def __init__(self, parent, layer, fieldName, fieldType):
769            wxPanel.__init__(self, parent, -1)
770    
771            self.parent = parent
772            self.layer = layer
773            self.fieldName = fieldName
774            self.fieldType = fieldType
775    
776            topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
777                                        wxVERTICAL)
778    
779            self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
780            self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
781                                            _("Retrieve from Table"))
782    
783            self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
784            self.spin_numClasses.SetRange(1, sys.maxint)
785            self.spin_numClasses.SetValue(1)
786    
787    
788            sizer = wxBoxSizer(wxHORIZONTAL)
789            sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
790            sizer.Add(self.text_range, 1, wxALL, 4)
791            sizer.Add(self.button_retrieve, 0, wxALL, 4)
792    
793            topBox.Add(sizer, 0, wxEXPAND, 0)
794    
795            sizer = wxBoxSizer(wxHORIZONTAL)
796            sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
797            sizer.Add(self.spin_numClasses, 1, wxALL, 4)
798    
799            topBox.Add(sizer, 0, wxEXPAND, 0)
800    
801            self.SetSizer(topBox)
802            self.SetAutoLayout(True)
803            topBox.Fit(self)
804            topBox.SetSizeHints(self)
805    
806            EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
807            EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
808    
809            self.__range = None
810    
811        def GetNumGroups(self):
812            return self.spin_numClasses.GetValue()
813    
814        def GetRange(self):
815            assert self.__range is not None
816    
817            return self.__range
818    
819        def GetList(self):
820    
821            if self.layer.table is not None:
822                wxBeginBusyCursor()
823                _list = self.layer.table.UniqueValues(self.fieldName)
824                wxEndBusyCursor()
825                return _list
826    
827            return []
828    
829        def OnRangeText(self, event):
830    
831            try:
832                self.__range = Range(self.text_range.GetValue())
833            except ValueError:
834                self.__range = None
835    
836            if self.__range is not None:
837                self.text_range.SetForegroundColour(wxBLACK)
838            else:
839                self.text_range.SetForegroundColour(wxRED)
840    
841        def OnRetrieve(self, event):
842    
843            if self.layer.table is not None:
844                wxBeginBusyCursor()
845                min, max = self.layer.table.ValueRange(self.fieldName)
846                self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
847                wxEndBusyCursor()
848    
849  ID_CUSTOMRAMP_COPYSTART = 4001  ID_CUSTOMRAMP_COPYSTART = 4001
850  ID_CUSTOMRAMP_COPYEND = 4002  ID_CUSTOMRAMP_COPYEND = 4002
851  ID_CUSTOMRAMP_EDITSTART = 4003  ID_CUSTOMRAMP_EDITSTART = 4003
# Line 787  class CustomRampPanel(wxPanel): Line 934  class CustomRampPanel(wxPanel):
934      def _OnEditEnd(self, event):      def _OnEditEnd(self, event):
935          self.endPropCtrl.DoEdit()          self.endPropCtrl.DoEdit()
936    
937  class ClassGenerator:    
   
     def GenSingletonsFromList(self, list, numGroups, ramp):  
         """Generate a new classification consisting solely of singletons.  
   
         The resulting classification will consist of at most 'numGroups'  
         groups whose group properties ramp between 'prop1' and 'prop2'. There  
         could be fewer groups if 'list' contains fewer that 'numGroups' items.  
   
         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.  
   
         prop1 -- initial group property values  
   
         prop2 -- final group property values  
         """  
   
         clazz = Classification()  
         if numGroups == 0: return clazz  
   
         ramp.SetNumGroups(numGroups)  
   
         for value, prop in zip(list, ramp):  
             clazz.AppendGroup(ClassGroupSingleton(value, prop))  
   
         return clazz  
   
     def GenSingletons(self, min, max, numGroups, ramp):  
   
         clazz = Classification()  
   
         #step = int((max - min) / float(numGroups))  
         step = int(Str2Num(str((max - min + 1) / float(numGroups))))  
   
         if numGroups > 0:  
             cur_value = min  
   
             ramp.SetNumGroups(numGroups)  
   
             for prop in ramp:  
                 clazz.AppendGroup(  
                     ClassGroupSingleton(  
                         Str2Num(str(cur_value)),  
                         prop))  
                 cur_value += step  
   
         return clazz  
   
     def GenUnifromDistribution(self, min, max, numGroups,  
                                ramp, intStep = False):  
         """Generate a classification with numGroups range groups  
         each with the same interval.  
   
         intStep -- force the calculated stepping to an integer.  
                    Useful if the values are integers but the  
                    number of groups specified doesn't evenly  
                    divide (max - min).  
         """  
   
         clazz = Classification()  
         if numGroups == 0: return clazz  
   
         ramp.SetNumGroups(numGroups)  
   
         step = Str2Num(str((max - min) / float(numGroups)))  
   
         if intStep:  
             step = int(step)  
   
         cur_min = min  
         cur_max = cur_min + step  
   
         i = 0  
         for prop in ramp:  
   
             if i == (numGroups - 1):  
                 cur_max = max  
   
             # this check guards against rounding issues  
             if cur_min != cur_max:  
                 clazz.AppendGroup(  
                     ClassGroupRange(  
                         Str2Num(str(cur_min)),  
                         Str2Num(str(cur_max)),  
                         prop))  
   
             cur_min = cur_max  
             cur_max += step  
             i += 1  
   
         return clazz  
   
 CLR  = 0  
 STEP = 1  
 class CustomRamp:  
   
     def __init__(self, prop1, prop2):  
         self.prop1 = prop1  
         self.prop2 = prop2  
   
         self.count = 0  
   
     def __iter__(self):  
         return self  
   
     def GetRamp(self):  
         return self  
   
     def SetNumGroups(self, num):  
   
         if num <= 0:  
             return False  
   
         self.count = int(num)  
         num = float(num)  
   
         prop1 = self.prop1  
         prop2 = self.prop2  
   
         clr = prop1.GetLineColor()  
         lineColor2 = prop2.GetLineColor()  
           
         self.noLine = clr is not Color.Transparent \  
                         and lineColor2 is not Color.Transparent  
   
   
         self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),  
                                             prop2.GetLineColor(),  
                                             num)  
   
         self.fillInfo = self.__GetColorInfo(prop1.GetFill(),  
                                             prop2.GetFill(),  
                                             num)  
   
         self.lineWidth = prop1.GetLineWidth()  
         self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num  
   
         return True  
   
     def next(self):  
         if self.count == 0:  
             raise StopIteration  
   
         prop = ClassGroupProperties()  
   
         if self.lineInfo is None:  
             prop.SetLineColor(Color.Transparent)  
         else:  
             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)  
         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)  
   
 class MonochromaticRamp(CustomRamp):  
     def __init__(self, start, end):  
         sp = ClassGroupProperties()  
         sp.SetLineColor(start)  
         sp.SetFill(start)  
   
         ep = ClassGroupProperties()  
         ep.SetLineColor(end)  
         ep.SetFill(end)  
   
         CustomRamp.__init__(self, sp, ep)  
   
 class GreyRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))  
   
 class RedRamp(MonochromaticRamp):  
     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 HotToColdRamp:  
   
     def __iter__(self):  
         return self  
           
     def GetRamp(self):  
         return self  
   
     def SetNumGroups(self, num):  
         if num < 0:  
             return False  
   
         self.num = float(num)  
         self.index = 0  
   
         return True  
   
     def next(self):  
         if self.index == self.num:  
             raise StopIteration  
   
         clr = [1.0, 1.0, 1.0]  
   
         if self.index < (.25 * self.num):  
             clr[0] = 0  
             clr[1] = 4 * self.index / self.num  
         elif self.index < (.5 * self.num):  
             clr[0] = 0  
             clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num  
         elif self.index < (.75 * self.num):  
             clr[0] = 4 * (self.index - .5 * self.num) / self.num  
             clr[2] = 0  
         else:  
             clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num  
             clr[2] = 0  
   
         self.index += 1  
   
         prop = ClassGroupProperties()  
         prop.SetLineColor(Color(clr[0], clr[1], clr[2]))  
         prop.SetFill(Color(clr[0], clr[1], clr[2]))  
   
         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.711  
changed lines
  Added in v.877

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26