/[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 635 by jonathan, Wed Apr 9 15:42:25 2003 UTC revision 877 by jonathan, Fri May 9 16:32:17 2003 UTC
# Line 5  Line 5 
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
7    
8    import sys
9    
10  from Thuban import _  from Thuban import _
11    
12  from wxPython.wx import *  from wxPython.wx import *
# Line 16  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
   
 from Thuban.common import Str2Num  
24    
25  ID_CLASSGEN_GEN = 4001  from Thuban.Model.classgen import ClassGenerator, \
26  ID_CLASSGEN_CLOSE = 4002      CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
27  ID_CLASSGEN_GENCOMBO = 4007      HotToColdRamp
28  ID_CLASSGEN_PROPCOMBO = 4008  
29    USEALL_BMP  = "group_use_all"
30    USE_BMP     = "group_use"
31    USENOT_BMP  = "group_use_not"
32    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_RED    = _("Red Ramp")  PROPCOMBOSTR_GREY       = _("Grey Ramp")
40  PROPCOMBOSTR_GREEN  = _("Green Ramp")  PROPCOMBOSTR_RED        = _("Red Ramp")
41  PROPCOMBOSTR_BLUE   = _("Blue Ramp")  PROPCOMBOSTR_GREEN      = _("Green Ramp")
42    PROPCOMBOSTR_BLUE       = _("Blue Ramp")
43    PROPCOMBOSTR_GREEN2RED  = _("Green-to-Red Ramp")
44    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 44  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 70  class ClassGenDialog(wxDialog): Line 111  class ClassGenDialog(wxDialog):
111                    0, wxALL, 4)                    0, wxALL, 4)
112          sizer.Add(wxStaticText(          sizer.Add(wxStaticText(
113              self, -1,              self, -1,
114              _("Field Type: %s") % classifier.Classifier.type2string[self.type]),              _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
115              0, wxALL, 4)              0, wxALL, 4)
116    
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 = wxComboBox(self,  
                                    ID_CLASSGEN_GENCOMBO,  
                                    "", style = wxCB_READONLY)  
         psizer.Add(self.genCombo, 1, wxALL | wxGROW, 4)  
         EVT_COMBOBOX(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, 0, wxGROW | wxALL, 4)  
             sizer.Show(panel, False)  
   
         #############  
126    
127          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
128          psizer.Add(wxStaticText(self, -1, _("Color Schemes:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
129              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
   
         self.propCombo = wxComboBox(self,  
                                    ID_CLASSGEN_PROPCOMBO,  
                                    "", style = wxCB_READONLY)  
130          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
         EVT_COMBOBOX(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_RED,   RedRamp())  
         self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())  
         self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())  
         self.propCombo.Append(PROPCOMBOSTR_CUSTOM, panel)  
   
   
   
         #############  
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            self.__DoOnGenTypeSelect()
151    
152          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)          EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
153          EVT_BUTTON(self, ID_CLASSGEN_CLOSE, self._OnCloseBtn)          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 149  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.genCombo.GetSelection()          index = self.genChoice.GetSelection()
173    
174          genSel = self.genCombo.GetString(index)          assert index != -1, "button should be disabled!"
175          genPanel = self.genCombo.GetClientData(index)  
176            genSel = self.genChoice.GetString(index)
177            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 195  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 221  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          self.sizer.SetSizeHints(self)      def __DoOnGenTypeSelect(self):
284          self.sizer.Layout()          choice = self.genChoice
285    
286            sel = choice.GetSelection()
287            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 276  class GenUniformPanel(wxPanel): Line 349  class GenUniformPanel(wxPanel):
349          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
350    
351          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
352          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS, style=wxTE_RIGHT)          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
353                                            style=wxTE_RIGHT)
354          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
355          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
356          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
# Line 297  class GenUniformPanel(wxPanel): Line 371  class GenUniformPanel(wxPanel):
371          self.numGroupsChanging = False          self.numGroupsChanging = False
372          self.steppingChanging = False          self.steppingChanging = False
373    
374          self.numGroupsCtrl.SetRange(1, 100)          self.numGroupsCtrl.SetRange(1, sys.maxint)
375    
376          self.numGroupsCtrl.SetValue(1)          self.numGroupsCtrl.SetValue(1)
377          self.stepCtrl.SetValue("1")          self.stepCtrl.SetValue("1")
# Line 347  class GenUniformPanel(wxPanel): Line 421  class GenUniformPanel(wxPanel):
421          self.numGroupsCtrl.Enable(on)          self.numGroupsCtrl.Enable(on)
422          self.stepCtrl.Enable(on)          self.stepCtrl.Enable(on)
423    
         if on:  
             self.numGroupsCtrl.SetRange(1, abs(max - min) / 0.001)  
   
424          ngroups = self.GetNumGroups()          ngroups = self.GetNumGroups()
425    
426          if ngroups is not None  \          if ngroups is not None  \
# Line 380  class GenUniformPanel(wxPanel): Line 451  class GenUniformPanel(wxPanel):
451          min = self.GetMin()          min = self.GetMin()
452          max = self.GetMax()          max = self.GetMax()
453    
         if ngroups >= self.numGroupsCtrl.GetMax():  
             self.numGroupsCtrl.SetRange(1, ngroups + 1)  
   
454          if ngroups is not None  \          if ngroups is not None  \
455              and min is not None \              and min is not None \
456              and max is not None \              and max is not None \
# Line 431  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 475  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 499  ID_UNIQUE_DONTUSE = 4004 Line 569  ID_UNIQUE_DONTUSE = 4004
569  ID_UNIQUE_USENONE = 4005  ID_UNIQUE_USENONE = 4005
570  ID_UNIQUE_SORTAVAIL = 4006  ID_UNIQUE_SORTAVAIL = 4006
571  ID_UNIQUE_SORTUSE = 4007  ID_UNIQUE_SORTUSE = 4007
572    ID_UNIQUE_REVAVAIL = 4008
573    ID_UNIQUE_REVUSE = 4009
574    
575  class GenUniquePanel(wxPanel):  class GenUniquePanel(wxPanel):
576    
# Line 514  class GenUniquePanel(wxPanel): Line 586  class GenUniquePanel(wxPanel):
586                                      wxVERTICAL)                                      wxVERTICAL)
587    
588    
589            #bsizer = wxBoxSizer(wxVERTICAL)
590            topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
591                                _("Retrieve From Table")),
592                       0, wxALL | wxALIGN_RIGHT, 4)
593    
594            EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
595    
596            #topSizer.Add(bsizer, 0, wxALL, 4)
597    
598          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
599    
600          self.dataList = []          self.dataList = []
# Line 525  class GenUniquePanel(wxPanel): Line 606  class GenUniquePanel(wxPanel):
606          self.list_avail_data = []          self.list_avail_data = []
607          psizer.Add(self.list_avail, 1, wxGROW, 0)          psizer.Add(self.list_avail, 1, wxGROW, 0)
608    
609          psizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))          bsizer = wxBoxSizer(wxHORIZONTAL)
610            bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
611            EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
612    
613          EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortAvailList)          bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
614            EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
615    
616            psizer.Add(bsizer, 0, wxGROW, 0)
617          sizer.Add(psizer, 1, wxGROW, 0)          sizer.Add(psizer, 1, wxGROW, 0)
618    
619                    
620          bsizer = wxBoxSizer(wxVERTICAL)          bsizer = wxBoxSizer(wxVERTICAL)
621          bsizer.Add(wxButton(self, ID_UNIQUE_USEALL, _("Use All")),  
622            bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
623            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
624                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
625          bsizer.Add(wxButton(self, ID_UNIQUE_USE, _("Use >>")),          bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
626            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
627                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
628          bsizer.Add(wxButton(self, ID_UNIQUE_DONTUSE, _("<< Don't Use")),          bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
629            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
630                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
631          bsizer.Add(wxButton(self, ID_UNIQUE_USENONE, _("Use None")),          bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
632            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
633                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
634    
635          EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)          EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
# Line 556  class GenUniquePanel(wxPanel): Line 646  class GenUniquePanel(wxPanel):
646          self.list_use_data = []          self.list_use_data = []
647          psizer.Add(self.list_use, 1, wxGROW, 0)          psizer.Add(self.list_use, 1, wxGROW, 0)
648    
649          psizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))          bsizer = wxBoxSizer(wxHORIZONTAL)
650            bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
651            EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
652    
653          EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortUseList)          bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
654            EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
655    
656          sizer.Add(psizer, 1, wxGROW, 0)          psizer.Add(bsizer, 0, wxGROW, 0)
657    
658          bsizer = wxBoxSizer(wxVERTICAL)          sizer.Add(psizer, 1, wxGROW, 0)
         bsizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,  
                             _("Retrieve From Table")),  
                    0, wxGROW | wxALL, 4)  
   
         EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)  
659    
         sizer.Add(bsizer, 0, wxALL, 4)  
660    
661          topSizer.Add(sizer, 1, wxGROW, 0)          topSizer.Add(sizer, 1, wxGROW, 0)
662    
# Line 579  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 590  class GenUniquePanel(wxPanel): Line 675  class GenUniquePanel(wxPanel):
675              list.append(self.dataList[self.list_use.GetItemData(i)])              list.append(self.dataList[self.list_use.GetItemData(i)])
676          return list          return list
677    
678      def _OnSortAvailList(self, event):      def _OnSortList(self, event):
679          self.list_avail.SortItems(lambda i1, i2:          id = event.GetId()
680                                      cmp(self.dataList[i1],  
681                                          self.dataList[i2]))          if id == ID_UNIQUE_SORTUSE:
682                list = self.list_use
683      def _OnSortUseList(self, event):          else:
684          self.list_use.SortItems(lambda i1, i2:              list = self.list_avail
685                                      cmp(self.dataList[i1],  
686                                          self.dataList[i2]))          list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
687                                              self.dataList[i2]))
688    
689        def _OnReverseList(self, event):
690            id = event.GetId()
691    
692            if id == ID_UNIQUE_REVUSE:
693                list = self.list_use
694            else:
695                list = self.list_avail
696    
697            #
698            # always returning 1 reverses the list
699            #
700            list.SortItems(lambda i1, i2: 1)
701    
702      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
703          self.list_use.DeleteAllItems()          self.list_use.DeleteAllItems()
# Line 606  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 621  class GenUniquePanel(wxPanel): Line 720  class GenUniquePanel(wxPanel):
720              self.__MoveListItem(0, self.list_avail, self.list_use)              self.__MoveListItem(0, self.list_avail, self.list_use)
721    
722      def _OnUse(self, event):      def _OnUse(self, event):
         print "_OnUse"  
723          self.__MoveSelectedItems(self.list_avail, self.list_use)          self.__MoveSelectedItems(self.list_avail, self.list_use)
724    
725      def _OnDontUse(self, event):      def _OnDontUse(self, event):
         print "_OnDontUse"  
726          self.__MoveSelectedItems(self.list_use, self.list_avail)          self.__MoveSelectedItems(self.list_use, self.list_avail)
727    
728      def _OnUseNone(self, event):      def _OnUseNone(self, event):
         print "_OnUseNone"  
729    
730          for i in range(self.list_use.GetItemCount()):          for i in range(self.list_use.GetItemCount()):
731              self.__MoveListItem(0, self.list_use, self.list_avail)              self.__MoveListItem(0, self.list_use, self.list_avail)
# Line 664  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 695  class CustomRampPanel(wxPanel): Line 877  class CustomRampPanel(wxPanel):
877                        | wxALIGN_CENTER_VERTICAL, \                        | wxALIGN_CENTER_VERTICAL, \
878                     4)                     4)
879    
880            bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
881          bsizer = wxBoxSizer(wxVERTICAL)          bsizer = wxBoxSizer(wxVERTICAL)
882          bsizer.Add(wxButton(self, ID_CUSTOMRAMP_COPYSTART, _("Copy >>")),          bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
883                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
884          bsizer.Add(wxButton(self, ID_CUSTOMRAMP_COPYEND, _("<< Copy")),          bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
885            bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
886                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
887    
888          topSizer.Add(bsizer,          topSizer.Add(bsizer,
# Line 750  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 RedRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(.2, 0, 0), Color(1, 0, 0))  
   
 class GreenRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(0, .2, 0), Color(0, 1, 0))  
   
 class BlueRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(0, 0, .2), Color(0, 0, 1))  
   

Legend:
Removed from v.635  
changed lines
  Added in v.877

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26