/[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 834 by bh, Tue May 6 15:52:36 2003 UTC revision 1526 by jonathan, Wed Jul 30 15:43:06 2003 UTC
# Line 11  from Thuban import _ Line 11  from Thuban import _
11    
12  from wxPython.wx import *  from wxPython.wx import *
13    
14  from Thuban.Model.classification import Classification, ClassGroupRange, \  from Thuban.Model.classification import ClassGroupProperties
     ClassGroupSingleton, ClassGroupProperties  
15    
16  from Thuban.Model.table import Table, FIELDTYPE_INT, FIELDTYPE_DOUBLE, \  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
17       FIELDTYPE_STRING       FIELDTYPE_STRING
18    
19  from Thuban.Model.color import Color  from Thuban.Model.layer import SHAPETYPE_ARC
20    from Thuban.Model.range import Range
21    from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
22    
23    import classifier, resource
24    
25    from Thuban.Model.classgen import \
26        generate_uniform_distribution, generate_singletons, generate_quantiles, \
27        CustomRamp, grey_ramp, red_ramp, green_ramp, blue_ramp, green_to_red_ramp, \
28        HotToColdRamp, FixedRamp
29    
 import classifier  
   
 import resource  
   
 ID_CLASSGEN_GENCOMBO = 4007  
 ID_CLASSGEN_PROPCOMBO = 4008  
30    
31  USEALL_BMP  = "group_use_all"  USEALL_BMP  = "group_use_all"
32  USE_BMP     = "group_use"  USE_BMP     = "group_use"
# Line 33  USENONE_BMP = "group_use_none" Line 35  USENONE_BMP = "group_use_none"
35    
36  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
37  GENCOMBOSTR_UNIQUE = _("Unique Values")  GENCOMBOSTR_UNIQUE = _("Unique Values")
38    GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
39    
40  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")
41  PROPCOMBOSTR_GREY       = _("Grey Ramp")  PROPCOMBOSTR_GREY       = _("Grey Ramp")
42  PROPCOMBOSTR_RED        = _("Red Ramp")  PROPCOMBOSTR_RED        = _("Red Ramp")
43  PROPCOMBOSTR_GREEN      = _("Green Ramp")  PROPCOMBOSTR_GREEN      = _("Green Ramp")
44  PROPCOMBOSTR_BLUE       = _("Blue Ramp")  PROPCOMBOSTR_BLUE       = _("Blue Ramp")
45    PROPCOMBOSTR_GREEN2RED  = _("Green-to-Red Ramp")
46  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")
47    
48    ID_CLASSGEN_GENCOMBO = 4007
49    ID_CLASSGEN_PROPCOMBO = 4008
50    
51    ID_BORDER_COLOR = 4009
52    ID_BORDER_COLOR_CHANGE = 4010
53    
54  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
55    
56      def __init__(self, parent, layer, fieldName):      def __init__(self, parent, layer, fieldName):
# Line 53  class ClassGenDialog(wxDialog): Line 63  class ClassGenDialog(wxDialog):
63                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
64    
65          self.parent = parent          self.parent = parent
66            self.layer = layer
67          self.clazz = None          self.clazz = None
68    
69          col = layer.table.Column(fieldName)          col = layer.ShapeStore().Table().Column(fieldName)
70          self.type = col.type          self.type = col.type
71    
72            self.fieldName = fieldName
73            self.fieldType = self.type
74    
75            self.curGenPanel = None
76    
77            self.genpanels = []
78    
79          #############          #############
80          # we need to create genButton first because when we create the          # we need to create genButton first because when we create the
81          # panels they will call AllowGenerate() which uses genButton.          # panels they will call AllowGenerate() which uses genButton.
82          #          #
83          self.genButton = wxButton(self, wxID_OK, _("Generate"))          self.genButton = wxButton(self, wxID_OK, _("Generate"))
84            self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
85          self.genButton.SetDefault()          self.genButton.SetDefault()
86    
87          self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)          self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
88    
89          uniq_panel = GenUniquePanel(self, layer, fieldName, self.type)          self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
   
         self.genPanel = uniq_panel  
         self.genChoice.Append(GENCOMBOSTR_UNIQUE, uniq_panel)  
   
90          if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):          if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
91              uni_panel = GenUniformPanel(self, layer, fieldName, self.type)              self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
92              self.genChoice.Append(GENCOMBOSTR_UNIFORM, uni_panel)              self.genpanels.append((GENCOMBOSTR_QUANTILES, GenQuantilesPanel))
93    
94            for name, clazz in self.genpanels:
95                self.genChoice.Append(name, [clazz, None])
96    
97          self.genChoice.SetSelection(0)          self.genChoice.SetSelection(0)
98    
99          self.propPanel = None          for i in range(self.genChoice.GetCount()):
100          custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())              clazz, obj = self.genChoice.GetClientData(i)
101    
102          self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)              if obj is None:
103          self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())                  obj = clazz(self, self.layer, self.fieldName, self.fieldType)
104          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())                  obj.Hide()
105          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())                  self.genChoice.SetClientData(i, [clazz, obj])
         self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())  
         self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())  
         self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)  
106    
         self.propCombo.SetSelection(0)  
107    
108          #############          #############
109    
# Line 108  class ClassGenDialog(wxDialog): Line 122  class ClassGenDialog(wxDialog):
122          psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)          psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
123    
124          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
         sizer.Add(self.genPanel, 1, wxGROW | wxALL, 4)  
125    
126          sizer.Show(uniq_panel, True)          self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
127          if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):          sizer.Add(self.sizer_genPanel, 1, wxGROW | wxALL, 4)
             sizer.Add(uni_panel, 1, wxGROW | wxALL, 4)  
             sizer.Show(uni_panel, False)  
128    
129          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
130          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
131              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
132    
133            # Properties (Ramp) ComboBox
134            self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
135    
136            self.propPanel = None
137            custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
138    
139            self.propCombo.Append(PROPCOMBOSTR_GREY,  grey_ramp)
140            self.propCombo.Append(PROPCOMBOSTR_RED,   red_ramp)
141            self.propCombo.Append(PROPCOMBOSTR_GREEN, green_ramp)
142            self.propCombo.Append(PROPCOMBOSTR_BLUE,  blue_ramp)
143            self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, green_to_red_ramp)
144            self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
145            self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
146    
147            self.propCombo.SetSelection(0)
148    
149          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
150          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
151    
152            if layer.ShapeType() != SHAPETYPE_ARC:
153                psizer = wxBoxSizer(wxHORIZONTAL)
154                self.fix_border_check = wxCheckBox(self, -1, _("Fix Border Color"))
155                psizer.Add(self.fix_border_check, 0, wxALL | wxGROW, 4)
156                self.border_color = classifier.ClassGroupPropertiesCtrl(
157                    self, ID_BORDER_COLOR,
158                    ClassGroupProperties(), SHAPETYPE_ARC,
159                    style=wxSIMPLE_BORDER, size=(40, 20))
160                psizer.Add(self.border_color, 0, wxALL | wxGROW, 4)
161                psizer.Add(wxButton(self, ID_BORDER_COLOR_CHANGE, _("Change")),
162                        0, wxALL, 4)
163                sizer.Add(psizer, 0, wxALL | wxGROW, 4)
164                EVT_BUTTON(self, ID_BORDER_COLOR_CHANGE, self.OnBorderColorChange)
165            else:
166                self.border_color = None
167    
168          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
169          sizer.Show(custom_ramp_panel, False)          sizer.Show(custom_ramp_panel, False)
170    
171            # Finally place the main buttons
172          buttonSizer = wxBoxSizer(wxHORIZONTAL)          buttonSizer = wxBoxSizer(wxHORIZONTAL)
173          buttonSizer.Add(self.genButton, 0, wxALL, 4)          buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
174          buttonSizer.Add(60, 20, 0, wxALL, 4)          buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
175          buttonSizer.Add(wxButton(self, wxID_CANCEL, _("Close")),          sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
                         0, wxALL, 4)  
         sizer.Add(buttonSizer, 0,  
                   wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)  
176    
177          self.SetSizer(sizer)          self.SetSizer(sizer)
178          self.SetAutoLayout(True)          self.SetAutoLayout(True)
179          sizer.SetSizeHints(self)          sizer.SetSizeHints(self)
180    
181          self.sizer = sizer          self.topBox = sizer
182    
183            self.__DoOnGenTypeSelect()
184    
185          EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)          EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
186          EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)          EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
187          EVT_BUTTON(self, wxID_OK, self.OnOK)          EVT_BUTTON(self, wxID_OK, self.OnOK)
188          EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)          EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
189    
190            self.__DoOnGenTypeSelect()
191    
192          self.genChoice.SetFocus()          self.genChoice.SetFocus()
193    
# Line 159  class ClassGenDialog(wxDialog): Line 204  class ClassGenDialog(wxDialog):
204    
205          index = self.genChoice.GetSelection()          index = self.genChoice.GetSelection()
206    
207            assert index != -1, "button should be disabled!"
208    
209          genSel = self.genChoice.GetString(index)          genSel = self.genChoice.GetString(index)
210          genPanel = self.genChoice.GetClientData(index)          clazz, genPanel = self.genChoice.GetClientData(index)
211    
212          propPanel = self.propPanel          propPanel = self.propPanel
213    
214          if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):          if genSel in (GENCOMBOSTR_UNIFORM,          \
215                          GENCOMBOSTR_UNIQUE,           \
216                          GENCOMBOSTR_QUANTILES):
217    
218              numGroups = genPanel.GetNumGroups()              numGroups = genPanel.GetNumGroups()
219    
220              index = self.propCombo.GetSelection()              index = self.propCombo.GetSelection()
# Line 173  class ClassGenDialog(wxDialog): Line 223  class ClassGenDialog(wxDialog):
223              propPanel = self.propCombo.GetClientData(index)              propPanel = self.propCombo.GetClientData(index)
224    
225              ramp = propPanel.GetRamp()              ramp = propPanel.GetRamp()
226                if self.border_color and self.fix_border_check.IsChecked():
227                    props = self.border_color.GetProperties()
228                    ramp = FixedRamp(ramp,
229                        (props.GetLineColor(), props.GetLineWidth(), None))
230    
231              if genSel == GENCOMBOSTR_UNIFORM:              if genSel == GENCOMBOSTR_UNIFORM:
232    
# Line 183  class ClassGenDialog(wxDialog): Line 237  class ClassGenDialog(wxDialog):
237                      and max is not None \                      and max is not None \
238                      and numGroups is not None:                      and numGroups is not None:
239    
240                      self.clazz = ClassGenerator().GenUnifromDistribution(                      self.clazz = generate_uniform_distribution(
241                                  min, max, numGroups, ramp,                                  min, max, numGroups, ramp,
242                                  self.type == FIELDTYPE_INT)                                  self.type == FIELDTYPE_INT)
243    
# Line 193  class ClassGenDialog(wxDialog): Line 247  class ClassGenDialog(wxDialog):
247    
248                  list = genPanel.GetValueList()                  list = genPanel.GetValueList()
249    
250                  if len(list) > 0 \                  if len(list) > 0:
251                      and numGroups is not None:                      self.clazz = generate_singletons(list, ramp)
252                        self.parent._SetClassification(self.clazz)
253    
254                      self.clazz = ClassGenerator().GenSingletonsFromList(              elif genSel == GENCOMBOSTR_QUANTILES:
                                     list, numGroups, ramp)  
255    
256                    _range = genPanel.GetRange()
257                    _list = genPanel.GetList()
258                    _list.sort()
259    
260                    delta = 1 / float(numGroups)
261                    percents = [delta * i for i in range(1, numGroups + 1)]
262                    adjusted, self.clazz = \
263                        generate_quantiles(_list, percents, ramp, _range)
264    
265                    if adjusted:
266                        dlg = wxMessageDialog(self,
267                            _("Based on the data from the table and the input\n" +
268                              "values, the exact quantiles could not be generated.\n\n" +
269                              "Accept a close estimate?"),
270                            _("Problem with Quantiles"),
271    
272                            wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
273                        if dlg.ShowModal() == wxID_YES:
274                            self.parent._SetClassification(self.clazz)
275                    else:
276                      self.parent._SetClassification(self.clazz)                      self.parent._SetClassification(self.clazz)
277    
278      def OnCancel(self, event):      def OnCancel(self, event):
279          self.Close()          self.Close()
280    
281        def OnBorderColorChange(self, event):
282            self.border_color.DoEdit()
283    
284      def _OnGenTypeSelect(self, event):      def _OnGenTypeSelect(self, event):
285            self.__DoOnGenTypeSelect()
286            return
287    
288          combo = event.GetEventObject()          combo = event.GetEventObject()
289    
290          selIndex = combo.GetSelection()          selIndex = combo.GetSelection()
291    
292          if self.genPanel is not None:          if self.genPanel is not None:
293              self.sizer.Show(self.genPanel, False)              self.topBox.Show(self.genPanel, False)
294    
295          self.genPanel = combo.GetClientData(selIndex)          self.genPanel = combo.GetClientData(selIndex)
296          if self.genPanel is not None:          if self.genPanel is not None:
297              self.sizer.Show(self.genPanel, True)              self.topBox.Show(self.genPanel, True)
298    
299          self.sizer.SetSizeHints(self)          self.topBox.SetSizeHints(self)
300          self.sizer.Layout()          self.topBox.Layout()
301    
302      def _OnPropTypeSelect(self, event):      def _OnPropTypeSelect(self, event):
303          combo = event.GetEventObject()          combo = event.GetEventObject()
# Line 227  class ClassGenDialog(wxDialog): Line 306  class ClassGenDialog(wxDialog):
306          sel = combo.GetString(selIndex)          sel = combo.GetString(selIndex)
307    
308          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
309              self.sizer.Show(self.propPanel, False)              self.topBox.Show(self.propPanel, False)
310    
311          self.propPanel = combo.GetClientData(selIndex)          self.propPanel = combo.GetClientData(selIndex)
312    
313          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
314              self.sizer.Show(self.propPanel, True)              self.topBox.Show(self.propPanel, True)
315    
316            self.topBox.SetSizeHints(self)
317            self.topBox.Layout()
318    
319        def __DoOnGenTypeSelect(self):
320            choice = self.genChoice
321    
322          self.sizer.SetSizeHints(self)          sel = choice.GetSelection()
323          self.sizer.Layout()          if sel == -1: return
324    
325            clazz, obj = choice.GetClientData(sel)
326    
327            if self.curGenPanel is not None:
328                self.curGenPanel.Hide()
329                self.sizer_genPanel.Remove(self.curGenPanel)
330    
331            self.curGenPanel = obj
332            self.curGenPanel.Show()
333    
334            self.sizer_genPanel.Add(self.curGenPanel, 1,
335                wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
336            self.sizer_genPanel.Layout()
337            self.Layout()
338            self.topBox.SetSizeHints(self)
339    
340  ID_UNIFORM_MIN = 4001  ID_UNIFORM_MIN = 4001
341  ID_UNIFORM_MAX = 4002  ID_UNIFORM_MAX = 4002
# Line 430  class GenUniformPanel(wxPanel): Line 529  class GenUniformPanel(wxPanel):
529              self.parent.AllowGenerate(False)              self.parent.AllowGenerate(False)
530    
531      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
532            table = self.layer.ShapeStore().Table()
533          if self.layer.table is not None:          if table is not None:
534              wxBeginBusyCursor()              ThubanBeginBusyCursor()
535              min, max = self.layer.table.ValueRange(self.fieldName)              try:
536              self.minCtrl.SetValue(str(min))                  min, max = table.ValueRange(self.fieldName)
537              self.maxCtrl.SetValue(str(max))                  self.minCtrl.SetValue(str(min))
538              wxEndBusyCursor()                  self.maxCtrl.SetValue(str(max))
539                finally:
540                    ThubanEndBusyCursor()
541    
542      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
543    
# Line 478  class GenUniformPanel(wxPanel): Line 579  class GenUniformPanel(wxPanel):
579          return valid          return valid
580    
581      def __CalcStepping(self, min, max, ngroups):      def __CalcStepping(self, min, max, ngroups):
         step = (max - min) / float(ngroups)  
582          if self.fieldType == FIELDTYPE_INT:          if self.fieldType == FIELDTYPE_INT:
583              step = int(step)              step = int((max - min + 1) / float(ngroups))
584            else:
585                step = (max - min) / float(ngroups)
586    
587          return step          return step
588    
# Line 597  class GenUniquePanel(wxPanel): Line 699  class GenUniquePanel(wxPanel):
699          self.SetAutoLayout(True)          self.SetAutoLayout(True)
700          topSizer.SetSizeHints(self)          topSizer.SetSizeHints(self)
701    
702          self.parent.AllowGenerate(False)          width, height = self.list_avail.GetSizeTuple()
703            self.list_avail.SetColumnWidth(0,width)
704            width, height = self.list_use.GetSizeTuple()
705            self.list_use.SetColumnWidth(0,width)
706    
707          self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]          self.parent.AllowGenerate(False)
708    
709      def GetNumGroups(self):      def GetNumGroups(self):
710          return self.list_use.GetItemCount()          return self.list_use.GetItemCount()
# Line 640  class GenUniquePanel(wxPanel): Line 745  class GenUniquePanel(wxPanel):
745          self.list_avail.DeleteAllItems()          self.list_avail.DeleteAllItems()
746          self.list_avail_data = []          self.list_avail_data = []
747    
748          list = self.layer.table.UniqueValues(self.fieldName)          ThubanBeginBusyCursor()
749          index = 0          try:
750          for v in list:              list = self.layer.ShapeStore().Table().UniqueValues(self.fieldName)
751              self.dataList.append(v)              index = 0
752              i = self.list_avail.InsertStringItem(index, str(v))              for v in list:
753              self.list_avail.SetItemData(index, i)                  self.dataList.append(v)
754                    i = self.list_avail.InsertStringItem(index, str(v))
755              self.list_avail_data.append(v)                  self.list_avail.SetItemData(index, i)
756              index += 1      
757                    self.list_avail_data.append(v)
758                    index += 1
759            finally:
760                ThubanEndBusyCursor()
761    
762      def _OnUseAll(self, event):      def _OnUseAll(self, event):
763          for i in range(self.list_avail.GetItemCount()):          for i in range(self.list_avail.GetItemCount()):
# Line 695  class GenUniquePanel(wxPanel): Line 804  class GenUniquePanel(wxPanel):
804  #       list.SetColumnWidth(0, event.GetSize().GetWidth())  #       list.SetColumnWidth(0, event.GetSize().GetWidth())
805  #        #      
806    
807    ID_QUANTILES_RANGE = 4001
808    ID_QUANTILES_RETRIEVE = 4002
809    
810    class GenQuantilesPanel(wxPanel):
811    
812        def __init__(self, parent, layer, fieldName, fieldType):
813            wxPanel.__init__(self, parent, -1)
814    
815            self.parent = parent
816            self.layer = layer
817            self.fieldName = fieldName
818            self.fieldType = fieldType
819    
820            topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
821                                        wxVERTICAL)
822    
823            self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
824            self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
825                                            _("Retrieve from Table"))
826    
827            self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
828            self.spin_numClasses.SetRange(1, sys.maxint)
829            self.spin_numClasses.SetValue(1)
830    
831    
832            sizer = wxBoxSizer(wxHORIZONTAL)
833            sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
834            sizer.Add(self.text_range, 1, wxALL, 4)
835            sizer.Add(self.button_retrieve, 0, wxALL, 4)
836    
837            topBox.Add(sizer, 0, wxEXPAND, 0)
838    
839            sizer = wxBoxSizer(wxHORIZONTAL)
840            sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
841            sizer.Add(self.spin_numClasses, 1, wxALL, 4)
842    
843            topBox.Add(sizer, 0, wxEXPAND, 0)
844    
845            self.SetSizer(topBox)
846            self.SetAutoLayout(True)
847            topBox.Fit(self)
848            topBox.SetSizeHints(self)
849    
850            EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
851            EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
852    
853            self.__range = None
854    
855        def GetNumGroups(self):
856            return self.spin_numClasses.GetValue()
857    
858        def GetRange(self):
859            assert self.__range is not None
860    
861            return self.__range
862    
863        def GetList(self):
864            _list = []
865            table = self.layer.ShapeStore().Table()
866            if table is not None:
867                ThubanBeginBusyCursor()
868                try:
869                    #
870                    # FIXME: Replace with a call to table when the method
871                    # has been written to get all the values
872                    #
873                    for i in range(table.NumRows()):
874                        _list.append(table.ReadValue(i, self.fieldName))
875                finally:
876                    ThubanEndBusyCursor()
877    
878            return _list
879    
880        def OnRangeText(self, event):
881    
882            try:
883                self.__range = Range(self.text_range.GetValue())
884            except ValueError:
885                self.__range = None
886    
887            if self.__range is not None:
888                self.text_range.SetForegroundColour(wxBLACK)
889            else:
890                self.text_range.SetForegroundColour(wxRED)
891    
892        def OnRetrieve(self, event):
893            table = self.layer.ShapeStore().Table()
894            if table is not None:
895                ThubanBeginBusyCursor()
896                try:
897                    min, max = table.ValueRange(self.fieldName)
898                    self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
899                finally:
900                    ThubanEndBusyCursor()
901    
902  ID_CUSTOMRAMP_COPYSTART = 4001  ID_CUSTOMRAMP_COPYSTART = 4001
903  ID_CUSTOMRAMP_COPYEND = 4002  ID_CUSTOMRAMP_COPYEND = 4002
904  ID_CUSTOMRAMP_EDITSTART = 4003  ID_CUSTOMRAMP_EDITSTART = 4003
# Line 783  class CustomRampPanel(wxPanel): Line 987  class CustomRampPanel(wxPanel):
987      def _OnEditEnd(self, event):      def _OnEditEnd(self, event):
988          self.endPropCtrl.DoEdit()          self.endPropCtrl.DoEdit()
989    
990  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))  
   
         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 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 = (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(cur_min, 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.834  
changed lines
  Added in v.1526

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26