/[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 978 by frank, Thu May 22 11:40:32 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 *
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.range import Range
   
 import classifier  
20    
21  from Thuban.common import Str2Num  import classifier, resource
22    
23  ID_CLASSGEN_GEN = 4001  from Thuban.Model.classgen import ClassGenerator, \
24  ID_CLASSGEN_CLOSE = 4002      CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
25  ID_CLASSGEN_GENCOMBO = 4007      HotToColdRamp
26  ID_CLASSGEN_PROPCOMBO = 4008  
27    USEALL_BMP  = "group_use_all"
28    USE_BMP     = "group_use"
29    USENOT_BMP  = "group_use_not"
30    USENONE_BMP = "group_use_none"
31    
32  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
33  GENCOMBOSTR_UNIQUE = _("Unique Values")  GENCOMBOSTR_UNIQUE = _("Unique Values")
34    GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
35    
36    PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")
37    PROPCOMBOSTR_GREY       = _("Grey Ramp")
38    PROPCOMBOSTR_RED        = _("Red Ramp")
39    PROPCOMBOSTR_GREEN      = _("Green Ramp")
40    PROPCOMBOSTR_BLUE       = _("Blue Ramp")
41    PROPCOMBOSTR_GREEN2RED  = _("Green-to-Red Ramp")
42    PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")
43    
44  PROPCOMBOSTR_CUSTOM = _("Custom Ramp")  ID_CLASSGEN_GENCOMBO = 4007
45  PROPCOMBOSTR_RED    = _("Red Ramp")  ID_CLASSGEN_PROPCOMBO = 4008
 PROPCOMBOSTR_GREEN  = _("Green Ramp")  
 PROPCOMBOSTR_BLUE   = _("Blue Ramp")  
46    
47  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
48                                                                                    
49      def __init__(self, parent, layer, fieldName):      def __init__(self, parent, layer, fieldName):
50          """Inialize the class generating dialog.          """Inialize the class generating dialog.
51    
# Line 44  class ClassGenDialog(wxDialog): Line 54  class ClassGenDialog(wxDialog):
54    
55          wxDialog.__init__(self, parent, -1, _("Generate Classification"),          wxDialog.__init__(self, parent, -1, _("Generate Classification"),
56                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
57                                                                                    
58          self.parent = parent          self.parent = parent
59            self.layer = layer
60          self.clazz = None          self.clazz = None
61    
62          self.type, name, width, prec = layer.table.field_info_by_name(fieldName)          col = layer.table.Column(fieldName)
63            self.type = col.type
64    
65            self.fieldName = fieldName
66            self.fieldType = self.type
67    
68            self.curGenPanel = None
69    
70            self.genpanels = []
71    
72          #############          #############
73          # we need to create genButton first because when we create the          # we need to create genButton first because when we create the
74          # panels they will call AllowGenerate() which uses genButton.          # panels they will call AllowGenerate() which uses genButton.
75          #          #
76          buttonSizer = wxBoxSizer(wxHORIZONTAL)          self.genButton = wxButton(self, wxID_OK, _("Generate"))
77          self.genButton = wxButton(self, ID_CLASSGEN_GEN, _("Generate"))          self.genButton.SetDefault()
78            self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
79    
80            self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
81    
82            self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
83            if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
84                self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
85                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            for i in range(self.genChoice.GetCount()):
93                clazz, obj = self.genChoice.GetClientData(i)
94    
95                if obj is None:
96                    obj = clazz(self, self.layer, self.fieldName, self.fieldType)
97                    obj.Hide()
98                    self.genChoice.SetClientData(i, [clazz, obj])
99    
         buttonSizer.Add(self.genButton, 0, wxALL, 4)  
         buttonSizer.Add(60, 20, 0, wxALL, 4)  
         buttonSizer.Add(wxButton(self, ID_CLASSGEN_CLOSE, _("Close")),  
                         0, wxALL, 4)  
100    
101          #############          #############
102    
# Line 70  class ClassGenDialog(wxDialog): Line 106  class ClassGenDialog(wxDialog):
106                    0, wxALL, 4)                    0, wxALL, 4)
107          sizer.Add(wxStaticText(          sizer.Add(wxStaticText(
108              self, -1,              self, -1,
109              _("Field Type: %s") % classifier.Classifier.type2string[self.type]),              _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
110              0, wxALL, 4)              0, wxALL, 4)
111    
112          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
113          psizer.Add(wxStaticText(self, -1, _("Generate:")),          psizer.Add(wxStaticText(self, -1, _("Generate:")),
114              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
115            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)  
116    
117          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
118    
119          #############          self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
120            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)  
   
         #############  
121    
122          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
123          psizer.Add(wxStaticText(self, -1, _("Color Schemes:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
124              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
125    
126          self.propCombo = wxComboBox(self,          # Properties (Ramp) ComboBox
127                                     ID_CLASSGEN_PROPCOMBO,          self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
                                    "", style = wxCB_READONLY)  
         psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)  
         EVT_COMBOBOX(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)  
         sizer.Add(psizer, 0, wxALL | wxGROW, 4)  
   
         #############  
128    
129          self.propPanel = None          self.propPanel = None
130          panel = CustomRampPanel(self, layer.ShapeType())          custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
         sizer.Add(panel, 1, wxALL | wxGROW, 4)  
         sizer.Show(panel, False)  
131    
132            self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())
133          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())
134          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
135          self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())          self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())
136          self.propCombo.Append(PROPCOMBOSTR_CUSTOM, panel)          self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())
137            self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
138            self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
139    
140            self.propCombo.SetSelection(0)
141    
142          #############          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
143            sizer.Add(psizer, 0, wxALL | wxGROW, 4)
144    
145          sizer.Add(buttonSizer, 0,          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
146                    wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)          sizer.Show(custom_ramp_panel, False)
147    
148            # Finally place the main buttons
149            buttonSizer = wxBoxSizer(wxHORIZONTAL)
150            buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
151            buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
152            sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
153    
154          self.SetSizer(sizer)          self.SetSizer(sizer)
155          self.SetAutoLayout(True)          self.SetAutoLayout(True)
156          sizer.SetSizeHints(self)          sizer.SetSizeHints(self)
157    
158          self.sizer = sizer          self.topBox = sizer
159    
160            self.__DoOnGenTypeSelect()
161    
162            EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
163            EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
164            EVT_BUTTON(self, wxID_OK, self.OnOK)
165            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
166    
167          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)          self.__DoOnGenTypeSelect()
168          EVT_BUTTON(self, ID_CLASSGEN_CLOSE, self._OnCloseBtn)  
169            self.genChoice.SetFocus()
170    
171      def GetClassification(self):      def GetClassification(self):
172          return self.clazz          return self.clazz
# Line 149  class ClassGenDialog(wxDialog): Line 174  class ClassGenDialog(wxDialog):
174      def AllowGenerate(self, on):      def AllowGenerate(self, on):
175          pass #self.genButton.Enable(on)          pass #self.genButton.Enable(on)
176    
177      def _OnGenerate(self, event):      def OnOK(self, event):
178            """This is really the generate button, but we want to override
179            the wxDialog class.
180            """
181    
182            index = self.genChoice.GetSelection()
183    
184          index = self.genCombo.GetSelection()          assert index != -1, "button should be disabled!"
185    
186          genSel = self.genCombo.GetString(index)          genSel = self.genChoice.GetString(index)
187          genPanel = self.genCombo.GetClientData(index)          clazz, genPanel = self.genChoice.GetClientData(index)
188    
189          propPanel = self.propPanel          propPanel = self.propPanel
190    
191          if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):          if genSel in (GENCOMBOSTR_UNIFORM,          \
192                          GENCOMBOSTR_UNIQUE,           \
193                          GENCOMBOSTR_QUANTILES):
194    
195              numGroups = genPanel.GetNumGroups()              numGroups = genPanel.GetNumGroups()
196    
197              index = self.propCombo.GetSelection()              index = self.propCombo.GetSelection()
# Line 177  class ClassGenDialog(wxDialog): Line 210  class ClassGenDialog(wxDialog):
210                      and max is not None \                      and max is not None \
211                      and numGroups is not None:                      and numGroups is not None:
212    
213                      self.clazz = ClassGenerator().GenUnifromDistribution(                      self.clazz = ClassGenerator().GenUniformDistribution(
214                                  min, max, numGroups, ramp,                                  min, max, numGroups, ramp,
215                                  self.type == FIELDTYPE_INT)                                  self.type == FIELDTYPE_INT)
216    
# Line 195  class ClassGenDialog(wxDialog): Line 228  class ClassGenDialog(wxDialog):
228    
229                      self.parent._SetClassification(self.clazz)                      self.parent._SetClassification(self.clazz)
230    
231      def _OnCloseBtn(self, event):              elif genSel == GENCOMBOSTR_QUANTILES:
232    
233                    _range = genPanel.GetRange()
234                    _list = genPanel.GetList()
235                    _list.sort()
236    
237                    delta = 1 / float(numGroups)
238                    percents = [delta * i for i in range(1, numGroups + 1)]
239                    adjusted, self.clazz = \
240                        ClassGenerator().GenQuantiles(_list, percents, ramp, _range)
241    
242                    if adjusted:
243                        dlg = wxMessageDialog(self,
244                            _("Based on the data from the table and the input\n" +
245                              "values, the exact quantiles could not be generated.\n\n" +
246                              "Accept a close estimate?"),
247                            _("Problem with Quantiles"),
248    
249                            wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
250                        if dlg.ShowModal() == wxID_YES:
251                            self.parent._SetClassification(self.clazz)
252                    else:
253                        self.parent._SetClassification(self.clazz)
254    
255        def OnCancel(self, event):
256          self.Close()          self.Close()
257    
258      def _OnGenTypeSelect(self, event):      def _OnGenTypeSelect(self, event):
259            self.__DoOnGenTypeSelect()
260            return
261    
262          combo = event.GetEventObject()          combo = event.GetEventObject()
263    
264          selIndex = combo.GetSelection()          selIndex = combo.GetSelection()
265    
266          if self.genPanel is not None:          if self.genPanel is not None:
267              self.sizer.Show(self.genPanel, False)              self.topBox.Show(self.genPanel, False)
268    
269          self.genPanel = combo.GetClientData(selIndex)          self.genPanel = combo.GetClientData(selIndex)
270          if self.genPanel is not None:          if self.genPanel is not None:
271              self.sizer.Show(self.genPanel, True)              self.topBox.Show(self.genPanel, True)
272    
273          self.sizer.SetSizeHints(self)          self.topBox.SetSizeHints(self)
274          self.sizer.Layout()          self.topBox.Layout()
275    
276      def _OnPropTypeSelect(self, event):      def _OnPropTypeSelect(self, event):
277          combo = event.GetEventObject()          combo = event.GetEventObject()
# Line 221  class ClassGenDialog(wxDialog): Line 280  class ClassGenDialog(wxDialog):
280          sel = combo.GetString(selIndex)          sel = combo.GetString(selIndex)
281    
282          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
283              self.sizer.Show(self.propPanel, False)              self.topBox.Show(self.propPanel, False)
284    
285          self.propPanel = combo.GetClientData(selIndex)          self.propPanel = combo.GetClientData(selIndex)
286    
287          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
288              self.sizer.Show(self.propPanel, True)              self.topBox.Show(self.propPanel, True)
289    
290            self.topBox.SetSizeHints(self)
291            self.topBox.Layout()
292    
293        def __DoOnGenTypeSelect(self):
294            choice = self.genChoice
295    
296            sel = choice.GetSelection()
297            if sel == -1: return
298    
299            clazz, obj = choice.GetClientData(sel)
300    
301            if self.curGenPanel is not None:
302                self.curGenPanel.Hide()
303                self.sizer_genPanel.Remove(self.curGenPanel)
304    
305          self.sizer.SetSizeHints(self)          self.curGenPanel = obj
306          self.sizer.Layout()          self.curGenPanel.Show()
307    
308            self.sizer_genPanel.Add(self.curGenPanel, 1,
309                wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
310            self.sizer_genPanel.Layout()
311            self.Layout()
312            self.topBox.SetSizeHints(self)
313    
314  ID_UNIFORM_MIN = 4001  ID_UNIFORM_MIN = 4001
315  ID_UNIFORM_MAX = 4002  ID_UNIFORM_MAX = 4002
# Line 276  class GenUniformPanel(wxPanel): Line 355  class GenUniformPanel(wxPanel):
355          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
356    
357          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
358          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS, style=wxTE_RIGHT)          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
359                                            style=wxTE_RIGHT)
360          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
361          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
362          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
# Line 297  class GenUniformPanel(wxPanel): Line 377  class GenUniformPanel(wxPanel):
377          self.numGroupsChanging = False          self.numGroupsChanging = False
378          self.steppingChanging = False          self.steppingChanging = False
379    
380          self.numGroupsCtrl.SetRange(1, 100)          self.numGroupsCtrl.SetRange(1, sys.maxint)
381    
382          self.numGroupsCtrl.SetValue(1)          self.numGroupsCtrl.SetValue(1)
383          self.stepCtrl.SetValue("1")          self.stepCtrl.SetValue("1")
# Line 347  class GenUniformPanel(wxPanel): Line 427  class GenUniformPanel(wxPanel):
427          self.numGroupsCtrl.Enable(on)          self.numGroupsCtrl.Enable(on)
428          self.stepCtrl.Enable(on)          self.stepCtrl.Enable(on)
429    
         if on:  
             self.numGroupsCtrl.SetRange(1, abs(max - min) / 0.001)  
   
430          ngroups = self.GetNumGroups()          ngroups = self.GetNumGroups()
431    
432          if ngroups is not None  \          if ngroups is not None  \
# Line 380  class GenUniformPanel(wxPanel): Line 457  class GenUniformPanel(wxPanel):
457          min = self.GetMin()          min = self.GetMin()
458          max = self.GetMax()          max = self.GetMax()
459    
         if ngroups >= self.numGroupsCtrl.GetMax():  
             self.numGroupsCtrl.SetRange(1, ngroups + 1)  
   
460          if ngroups is not None  \          if ngroups is not None  \
461              and min is not None \              and min is not None \
462              and max is not None \              and max is not None \
# Line 431  class GenUniformPanel(wxPanel): Line 505  class GenUniformPanel(wxPanel):
505      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
506    
507          if self.layer.table is not None:          if self.layer.table is not None:
508              range = self.layer.table.field_range(self.fieldName)              wxBeginBusyCursor()
509              self.minCtrl.SetValue(str(range[0][0]))              min, max = self.layer.table.ValueRange(self.fieldName)
510              self.maxCtrl.SetValue(str(range[1][0]))              self.minCtrl.SetValue(str(min))
511                self.maxCtrl.SetValue(str(max))
512                wxEndBusyCursor()
513    
514      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
515    
# Line 475  class GenUniformPanel(wxPanel): Line 551  class GenUniformPanel(wxPanel):
551          return valid          return valid
552    
553      def __CalcStepping(self, min, max, ngroups):      def __CalcStepping(self, min, max, ngroups):
554          step = Str2Num(str((max - min) / float(ngroups)))          step = (max - min) / float(ngroups)
555          if self.fieldType == FIELDTYPE_INT:          if self.fieldType == FIELDTYPE_INT:
556              step = int(step)              step = int(step)
557    
# Line 499  ID_UNIQUE_DONTUSE = 4004 Line 575  ID_UNIQUE_DONTUSE = 4004
575  ID_UNIQUE_USENONE = 4005  ID_UNIQUE_USENONE = 4005
576  ID_UNIQUE_SORTAVAIL = 4006  ID_UNIQUE_SORTAVAIL = 4006
577  ID_UNIQUE_SORTUSE = 4007  ID_UNIQUE_SORTUSE = 4007
578    ID_UNIQUE_REVAVAIL = 4008
579    ID_UNIQUE_REVUSE = 4009
580    
581  class GenUniquePanel(wxPanel):  class GenUniquePanel(wxPanel):
582    
# Line 514  class GenUniquePanel(wxPanel): Line 592  class GenUniquePanel(wxPanel):
592                                      wxVERTICAL)                                      wxVERTICAL)
593    
594    
595            #bsizer = wxBoxSizer(wxVERTICAL)
596            topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
597                                _("Retrieve From Table")),
598                       0, wxALL | wxALIGN_RIGHT, 4)
599    
600            EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
601    
602            #topSizer.Add(bsizer, 0, wxALL, 4)
603    
604          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
605    
606          self.dataList = []          self.dataList = []
# Line 525  class GenUniquePanel(wxPanel): Line 612  class GenUniquePanel(wxPanel):
612          self.list_avail_data = []          self.list_avail_data = []
613          psizer.Add(self.list_avail, 1, wxGROW, 0)          psizer.Add(self.list_avail, 1, wxGROW, 0)
614    
615          psizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))          bsizer = wxBoxSizer(wxHORIZONTAL)
616            bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
617            EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
618    
619          EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortAvailList)          bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
620            EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
621    
622            psizer.Add(bsizer, 0, wxGROW, 0)
623          sizer.Add(psizer, 1, wxGROW, 0)          sizer.Add(psizer, 1, wxGROW, 0)
624    
625                    
626          bsizer = wxBoxSizer(wxVERTICAL)          bsizer = wxBoxSizer(wxVERTICAL)
627          bsizer.Add(wxButton(self, ID_UNIQUE_USEALL, _("Use All")),  
628            bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
629            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
630                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
631          bsizer.Add(wxButton(self, ID_UNIQUE_USE, _("Use >>")),          bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
632            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
633                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
634          bsizer.Add(wxButton(self, ID_UNIQUE_DONTUSE, _("<< Don't Use")),          bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
635            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
636                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
637          bsizer.Add(wxButton(self, ID_UNIQUE_USENONE, _("Use None")),          bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
638            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
639                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
640    
641          EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)          EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
# Line 556  class GenUniquePanel(wxPanel): Line 652  class GenUniquePanel(wxPanel):
652          self.list_use_data = []          self.list_use_data = []
653          psizer.Add(self.list_use, 1, wxGROW, 0)          psizer.Add(self.list_use, 1, wxGROW, 0)
654    
655          psizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))          bsizer = wxBoxSizer(wxHORIZONTAL)
656            bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
657          EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortUseList)          EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
658    
659          sizer.Add(psizer, 1, wxGROW, 0)          bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
660            EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
661    
662          bsizer = wxBoxSizer(wxVERTICAL)          psizer.Add(bsizer, 0, wxGROW, 0)
         bsizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,  
                             _("Retrieve From Table")),  
                    0, wxGROW | wxALL, 4)  
663    
664          EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)          sizer.Add(psizer, 1, wxGROW, 0)
665    
         sizer.Add(bsizer, 0, wxALL, 4)  
666    
667          topSizer.Add(sizer, 1, wxGROW, 0)          topSizer.Add(sizer, 1, wxGROW, 0)
668    
# Line 577  class GenUniquePanel(wxPanel): Line 670  class GenUniquePanel(wxPanel):
670          self.SetAutoLayout(True)          self.SetAutoLayout(True)
671          topSizer.SetSizeHints(self)          topSizer.SetSizeHints(self)
672    
673          self.parent.AllowGenerate(False)          width, height = self.list_avail.GetSizeTuple()
674            self.list_avail.SetColumnWidth(0,width)
675            width, height = self.list_use.GetSizeTuple()
676            self.list_use.SetColumnWidth(0,width)
677    
678          self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]          self.parent.AllowGenerate(False)
679    
680      def GetNumGroups(self):      def GetNumGroups(self):
681          return self.list_use.GetItemCount()          return self.list_use.GetItemCount()
# Line 590  class GenUniquePanel(wxPanel): Line 686  class GenUniquePanel(wxPanel):
686              list.append(self.dataList[self.list_use.GetItemData(i)])              list.append(self.dataList[self.list_use.GetItemData(i)])
687          return list          return list
688    
689      def _OnSortAvailList(self, event):      def _OnSortList(self, event):
690          self.list_avail.SortItems(lambda i1, i2:          id = event.GetId()
691                                      cmp(self.dataList[i1],  
692                                          self.dataList[i2]))          if id == ID_UNIQUE_SORTUSE:
693                list = self.list_use
694      def _OnSortUseList(self, event):          else:
695          self.list_use.SortItems(lambda i1, i2:              list = self.list_avail
696                                      cmp(self.dataList[i1],  
697                                          self.dataList[i2]))          list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
698                                              self.dataList[i2]))
699    
700        def _OnReverseList(self, event):
701            id = event.GetId()
702    
703            if id == ID_UNIQUE_REVUSE:
704                list = self.list_use
705            else:
706                list = self.list_avail
707    
708            #
709            # always returning 1 reverses the list
710            #
711            list.SortItems(lambda i1, i2: 1)
712    
713      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
714          self.list_use.DeleteAllItems()          self.list_use.DeleteAllItems()
# Line 606  class GenUniquePanel(wxPanel): Line 716  class GenUniquePanel(wxPanel):
716          self.list_avail.DeleteAllItems()          self.list_avail.DeleteAllItems()
717          self.list_avail_data = []          self.list_avail_data = []
718    
719          list = self.layer.table.GetUniqueValues(self.fieldName)          list = self.layer.table.UniqueValues(self.fieldName)
720          index = 0          index = 0
721          for v in list:          for v in list:
722              self.dataList.append(v)              self.dataList.append(v)
# Line 621  class GenUniquePanel(wxPanel): Line 731  class GenUniquePanel(wxPanel):
731              self.__MoveListItem(0, self.list_avail, self.list_use)              self.__MoveListItem(0, self.list_avail, self.list_use)
732    
733      def _OnUse(self, event):      def _OnUse(self, event):
         print "_OnUse"  
734          self.__MoveSelectedItems(self.list_avail, self.list_use)          self.__MoveSelectedItems(self.list_avail, self.list_use)
735    
736      def _OnDontUse(self, event):      def _OnDontUse(self, event):
         print "_OnDontUse"  
737          self.__MoveSelectedItems(self.list_use, self.list_avail)          self.__MoveSelectedItems(self.list_use, self.list_avail)
738    
739      def _OnUseNone(self, event):      def _OnUseNone(self, event):
         print "_OnUseNone"  
740    
741          for i in range(self.list_use.GetItemCount()):          for i in range(self.list_use.GetItemCount()):
742              self.__MoveListItem(0, self.list_use, self.list_avail)              self.__MoveListItem(0, self.list_use, self.list_avail)
# Line 664  class GenUniquePanel(wxPanel): Line 771  class GenUniquePanel(wxPanel):
771  #       list.SetColumnWidth(0, event.GetSize().GetWidth())  #       list.SetColumnWidth(0, event.GetSize().GetWidth())
772  #        #      
773    
774    ID_QUANTILES_RANGE = 4001
775    ID_QUANTILES_RETRIEVE = 4002
776    
777    class GenQuantilesPanel(wxPanel):
778    
779        def __init__(self, parent, layer, fieldName, fieldType):
780            wxPanel.__init__(self, parent, -1)
781    
782            self.parent = parent
783            self.layer = layer
784            self.fieldName = fieldName
785            self.fieldType = fieldType
786    
787            topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
788                                        wxVERTICAL)
789    
790            self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
791            self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
792                                            _("Retrieve from Table"))
793    
794            self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
795            self.spin_numClasses.SetRange(1, sys.maxint)
796            self.spin_numClasses.SetValue(1)
797    
798    
799            sizer = wxBoxSizer(wxHORIZONTAL)
800            sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
801            sizer.Add(self.text_range, 1, wxALL, 4)
802            sizer.Add(self.button_retrieve, 0, wxALL, 4)
803    
804            topBox.Add(sizer, 0, wxEXPAND, 0)
805    
806            sizer = wxBoxSizer(wxHORIZONTAL)
807            sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
808            sizer.Add(self.spin_numClasses, 1, wxALL, 4)
809    
810            topBox.Add(sizer, 0, wxEXPAND, 0)
811    
812            self.SetSizer(topBox)
813            self.SetAutoLayout(True)
814            topBox.Fit(self)
815            topBox.SetSizeHints(self)
816    
817            EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
818            EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
819    
820            self.__range = None
821    
822        def GetNumGroups(self):
823            return self.spin_numClasses.GetValue()
824    
825        def GetRange(self):
826            assert self.__range is not None
827    
828            return self.__range
829    
830        def GetList(self):
831    
832            _list = []
833    
834            if self.layer.table is not None:
835                wxBeginBusyCursor()
836    
837                #
838                # FIXME: Replace with a call to table when the method
839                # has been written to get all the values
840                #
841                table = self.layer.table
842                for i in range(table.NumRows()):
843                    _list.append(table.ReadValue(i, self.fieldName))
844    
845                wxEndBusyCursor()
846    
847            return _list
848    
849        def OnRangeText(self, event):
850    
851            try:
852                self.__range = Range(self.text_range.GetValue())
853            except ValueError:
854                self.__range = None
855    
856            if self.__range is not None:
857                self.text_range.SetForegroundColour(wxBLACK)
858            else:
859                self.text_range.SetForegroundColour(wxRED)
860    
861        def OnRetrieve(self, event):
862    
863            if self.layer.table is not None:
864                wxBeginBusyCursor()
865                min, max = self.layer.table.ValueRange(self.fieldName)
866                self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
867                wxEndBusyCursor()
868    
869  ID_CUSTOMRAMP_COPYSTART = 4001  ID_CUSTOMRAMP_COPYSTART = 4001
870  ID_CUSTOMRAMP_COPYEND = 4002  ID_CUSTOMRAMP_COPYEND = 4002
871  ID_CUSTOMRAMP_EDITSTART = 4003  ID_CUSTOMRAMP_EDITSTART = 4003
# Line 695  class CustomRampPanel(wxPanel): Line 897  class CustomRampPanel(wxPanel):
897                        | wxALIGN_CENTER_VERTICAL, \                        | wxALIGN_CENTER_VERTICAL, \
898                     4)                     4)
899    
900            bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
901          bsizer = wxBoxSizer(wxVERTICAL)          bsizer = wxBoxSizer(wxVERTICAL)
902          bsizer.Add(wxButton(self, ID_CUSTOMRAMP_COPYSTART, _("Copy >>")),          bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
903                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
904          bsizer.Add(wxButton(self, ID_CUSTOMRAMP_COPYEND, _("<< Copy")),          bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
905            bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
906                     0, wxGROW | wxALL, 4)                     0, wxGROW | wxALL, 4)
907    
908          topSizer.Add(bsizer,          topSizer.Add(bsizer,
# Line 750  class CustomRampPanel(wxPanel): Line 954  class CustomRampPanel(wxPanel):
954      def _OnEditEnd(self, event):      def _OnEditEnd(self, event):
955          self.endPropCtrl.DoEdit()          self.endPropCtrl.DoEdit()
956    
957  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.978

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26