/[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 620 by jonathan, Mon Apr 7 10:14:25 2003 UTC revision 781 by jonathan, Tue Apr 29 16:53:38 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 17  from Thuban.Model.table import Table, FI Line 19  from Thuban.Model.table import Table, FI
19    
20  from Thuban.Model.color import Color  from Thuban.Model.color import Color
21    
22    import classifier
23    
24    import resource
25    
26  ID_CLASSGEN_GEN = 4001  ID_CLASSGEN_GEN = 4001
27  ID_CLASSGEN_CANCEL = 4002  ID_CLASSGEN_CLOSE = 4002
28    ID_CLASSGEN_GENCOMBO = 4007
29    ID_CLASSGEN_PROPCOMBO = 4008
30    
31    USEALL_BMP  = "group_use_all"
32    USE_BMP     = "group_use"
33    USENOT_BMP  = "group_use_not"
34    USENONE_BMP = "group_use_none"
35    
36    GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
37    GENCOMBOSTR_UNIQUE = _("Unique Values")
38    
39    PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")
40    PROPCOMBOSTR_GREY       = _("Grey Ramp")
41    PROPCOMBOSTR_RED        = _("Red Ramp")
42    PROPCOMBOSTR_GREEN      = _("Green Ramp")
43    PROPCOMBOSTR_BLUE       = _("Blue Ramp")
44    PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")
45    
46  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
47                                                                                                                                                                    
48      def __init__(self, parent, table, fieldName):      def __init__(self, parent, layer, fieldName):
49            """Inialize the class generating dialog.
50    
51            parent -- this must be an instance of the Classifier class
52            """
53    
54          wxDialog.__init__(self, parent, -1, _("Generate Classification"),          wxDialog.__init__(self, parent, -1, _("Generate Classification"),
55                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
56                                                                                                                                                                    
57            self.parent = parent
58          self.clazz = None          self.clazz = None
59    
60          type, name, width, prec = table.field_info_by_name(fieldName)          self.type, name, width, prec = layer.table.field_info_by_name(fieldName)
   
         sizer = wxBoxSizer(wxVERTICAL)  
61    
62            #############
63            # we need to create genButton first because when we create the
64            # panels they will call AllowGenerate() which uses genButton.
65            #
66          buttonSizer = wxBoxSizer(wxHORIZONTAL)          buttonSizer = wxBoxSizer(wxHORIZONTAL)
67          self.genButton = wxButton(self, ID_CLASSGEN_GEN, _("Generate"))          self.genButton = wxButton(self, ID_CLASSGEN_GEN, _("Generate"))
68    
69          buttonSizer.Add(self.genButton, 0, wxALL, 4)          buttonSizer.Add(self.genButton, 0, wxALL, 4)
70          buttonSizer.Add(60, 20, 0, wxALL, 4)          buttonSizer.Add(60, 20, 0, wxALL, 4)
71          buttonSizer.Add(wxButton(self, ID_CLASSGEN_CANCEL, _("Cancel")),          buttonSizer.Add(wxButton(self, ID_CLASSGEN_CLOSE, _("Close")),
72                          0, wxALL, 4)                          0, wxALL, 4)
73    
74          if type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):          #############
75              self.panel = GenRangePanel(self, table, fieldName, type)  
76          elif type == FIELDTYPE_STRING:          sizer = wxBoxSizer(wxVERTICAL)
77              print "Select a field that is an int/decimal"  
78              #panel = GenSingletonPanel(self, table, fieldName)          sizer.Add(wxStaticText(self, -1, _("Field: %s") % fieldName),
79          else:                    0, wxALL, 4)
80              assert False, "Shouldn't be here."          sizer.Add(wxStaticText(
81              pass              self, -1,
82                _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
83                0, wxALL, 4)
84    
85            psizer = wxBoxSizer(wxHORIZONTAL)
86            psizer.Add(wxStaticText(self, -1, _("Generate:")),
87                0, wxALIGN_CENTER_VERTICAL, 0)
88    
89            self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
90            psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
91            EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
92    
93            sizer.Add(psizer, 0, wxALL | wxGROW, 4)
94    
95            #############
96    
97            self.genPanel = None
98    
99            panel = GenUniquePanel(self, layer, fieldName, self.type)
100            self.genChoice.Append(GENCOMBOSTR_UNIQUE, panel)
101            sizer.Add(panel, 1, wxGROW | wxALL, 4)
102    
103            self.genPanel = panel
104    
105            if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
106                panel = GenUniformPanel(self, layer, fieldName, self.type)
107                self.genChoice.Append(GENCOMBOSTR_UNIFORM, panel)
108                sizer.Add(panel, 1, wxGROW | wxALL, 4)
109                sizer.Show(panel, False)
110    
111            self.genChoice.SetSelection(0)
112    
113            #############
114    
115            psizer = wxBoxSizer(wxHORIZONTAL)
116            psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
117                0, wxALIGN_CENTER_VERTICAL, 0)
118    
119            self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
120            psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
121            EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
122            sizer.Add(psizer, 0, wxALL | wxGROW, 4)
123    
124            #############
125    
126            self.propPanel = None
127            panel = CustomRampPanel(self, layer.ShapeType())
128            sizer.Add(panel, 1, wxALL | wxGROW, 4)
129            sizer.Show(panel, False)
130    
131            self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())
132            self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())
133            self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
134            self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())
135            self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
136            self.propCombo.Append(PROPCOMBOSTR_CUSTOM, panel)
137    
138            self.propCombo.SetSelection(0)
139    
140    
141            #############
142    
         sizer.Add(self.panel, 1, wxGROW | wxALL, 4)  
143          sizer.Add(buttonSizer, 0,          sizer.Add(buttonSizer, 0,
144                    wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)                    wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)
145    
146    
147          self.SetSizer(sizer)          self.SetSizer(sizer)
148          self.SetAutoLayout(True)          self.SetAutoLayout(True)
149          sizer.SetSizeHints(self)          sizer.SetSizeHints(self)
150    
151            self.sizer = sizer
152    
153          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)
154          EVT_BUTTON(self, ID_CLASSGEN_CANCEL, self._OnCancel)          EVT_BUTTON(self, ID_CLASSGEN_CLOSE, self._OnCloseBtn)
155    
156      def GetClassification(self):      def GetClassification(self):
157          return self.clazz          return self.clazz
158    
159      def AllowGenerate(self, on):      def AllowGenerate(self, on):
160          self.genButton.Enable(on)          pass #self.genButton.Enable(on)
161    
162      def _OnGenerate(self, event):      def _OnGenerate(self, event):
         min = self.panel.GetMin()  
         max = self.panel.GetMax()  
         numGroups = self.panel.GetNumGroups()  
         cgp = ClassGroupProperties()  
         cgp2 = ClassGroupProperties()  
                                                                                   
         cgp.SetLineColor(Color(.5, 0, 0))  
         cgp2.SetLineColor(Color(1, 0, 1))  
         cgp2.SetLineWidth(10)  
163    
164          if min is not None \          index = self.genChoice.GetSelection()
             and max is not None \  
             and numGroups is not None:  
             self.clazz = ClassGenerator().GenerateRanges(min, max,  
                                                          numGroups, cgp, cgp2)  
         else:    
             self.clazz = None # for now  
165    
166          self.EndModal(wxID_OK)          genSel = self.genChoice.GetString(index)
167                                                                                            genPanel = self.genChoice.GetClientData(index)
168      def _OnCancel(self, event):  
169          self.EndModal(wxID_CANCEL)          propPanel = self.propPanel
170    
171            if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):
172                numGroups = genPanel.GetNumGroups()
173    
174                index = self.propCombo.GetSelection()
175    
176                propSel = self.propCombo.GetString(index)
177                propPanel = self.propCombo.GetClientData(index)
178    
179                ramp = propPanel.GetRamp()
180    
181                if genSel == GENCOMBOSTR_UNIFORM:
182    
183                    min = genPanel.GetMin()
184                    max = genPanel.GetMax()
185    
186                    if min is not None \
187                        and max is not None \
188                        and numGroups is not None:
189    
190                        self.clazz = ClassGenerator().GenUnifromDistribution(
191                                    min, max, numGroups, ramp,
192                                    self.type == FIELDTYPE_INT)
193    
194                        self.parent._SetClassification(self.clazz)
195    
196                elif genSel == GENCOMBOSTR_UNIQUE:
197    
198                    list = genPanel.GetValueList()
199    
200                    if len(list) > 0 \
201                        and numGroups is not None:
202    
203                        self.clazz = ClassGenerator().GenSingletonsFromList(
204                                        list, numGroups, ramp)
205    
206                        self.parent._SetClassification(self.clazz)
207    
208        def _OnCloseBtn(self, event):
209            self.Close()
210    
211        def _OnGenTypeSelect(self, event):
212    
213            combo = event.GetEventObject()
214    
215            selIndex = combo.GetSelection()
216    
217            if self.genPanel is not None:
218                self.sizer.Show(self.genPanel, False)
219    
220  ID_RANGE_MIN = 4001          self.genPanel = combo.GetClientData(selIndex)
221  ID_RANGE_MAX = 4002          if self.genPanel is not None:
222  ID_RANGE_NGROUPS = 4003              self.sizer.Show(self.genPanel, True)
 ID_RANGE_STEP = 4004  
223    
224  class GenRangePanel(wxPanel):          self.sizer.SetSizeHints(self)
225            self.sizer.Layout()
226    
227      def __init__(self, parent, table, fieldName, fieldType):      def _OnPropTypeSelect(self, event):
228            combo = event.GetEventObject()
229    
230            selIndex = combo.GetSelection()
231            sel = combo.GetString(selIndex)
232    
233            if isinstance(self.propPanel, wxPanel):
234                self.sizer.Show(self.propPanel, False)
235    
236            self.propPanel = combo.GetClientData(selIndex)
237    
238            if isinstance(self.propPanel, wxPanel):
239                self.sizer.Show(self.propPanel, True)
240    
241            self.sizer.SetSizeHints(self)
242            self.sizer.Layout()
243    
244    
245    ID_UNIFORM_MIN = 4001
246    ID_UNIFORM_MAX = 4002
247    ID_UNIFORM_NGROUPS = 4003
248    ID_UNIFORM_STEP = 4004
249    ID_UNIFORM_RETRIEVE = 4005
250    
251    class GenUniformPanel(wxPanel):
252    
253        def __init__(self, parent, layer, fieldName, fieldType):
254          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
255    
256          self.parent = parent          self.parent = parent
257            self.layer = layer
258            self.fieldName = fieldName
259          self.fieldType = fieldType          self.fieldType = fieldType
260    
261          topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, "Ranges"),          topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
262                                      wxVERTICAL)                                      wxVERTICAL)
263    
264            #############
265    
266          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
267    
268          sizer.Add(wxStaticText(self, -1, _("Min:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Min:")), 0, wxALL, 4)
269          self.minCtrl = wxTextCtrl(self, ID_RANGE_MIN, style=wxTE_RIGHT)          self.minCtrl = wxTextCtrl(self, ID_UNIFORM_MIN, style=wxTE_RIGHT)
270          sizer.Add(self.minCtrl, 0, wxALL, 4)          sizer.Add(self.minCtrl, 1, wxALL, 4)
271          EVT_TEXT(self, ID_RANGE_MIN, self._OnRangeChanged)          EVT_TEXT(self, ID_UNIFORM_MIN, self._OnRangeChanged)
         self.goodTextColour = self.minCtrl.GetForegroundColour()  
         self.badTextColour = wxRED  
272    
273          sizer.Add(wxStaticText(self, -1, _("Max:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Max:")), 0, wxALL, 4)
274          self.maxCtrl = wxTextCtrl(self, ID_RANGE_MAX, style=wxTE_RIGHT)          self.maxCtrl = wxTextCtrl(self, ID_UNIFORM_MAX, style=wxTE_RIGHT)
275          sizer.Add(self.maxCtrl, 0, wxALL, 4)          sizer.Add(self.maxCtrl, 1, wxALL, 4)
276          EVT_TEXT(self, ID_RANGE_MAX, self._OnRangeChanged)          EVT_TEXT(self, ID_UNIFORM_MAX, self._OnRangeChanged)
277          topSizer.Add(sizer, 0, wxALL, 4)  
278            sizer.Add(wxButton(self, ID_UNIFORM_RETRIEVE, _("Retrieve From Table")),
279                0, wxALL, 4)
280            EVT_BUTTON(self, ID_UNIFORM_RETRIEVE, self._OnRetrieve)
281    
282            topSizer.Add(sizer, 1, wxGROW, 0)
283    
284            #############
285    
286          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
287    
288          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
289          self.numGroupsCtrl = wxSpinCtrl(self, ID_RANGE_NGROUPS, style=wxTE_RIGHT)          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
290          EVT_TEXT(self, ID_RANGE_NGROUPS, self._OnNumGroupsChanged)                                          style=wxTE_RIGHT)
291          EVT_SPINCTRL(self, ID_RANGE_NGROUPS, self._OnNumGroupsChanged)          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
292          sizer.Add(self.numGroupsCtrl, 0, wxALL, 4)          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
293            sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
294    
295          sizer.Add(wxStaticText(self, -1, _("Stepping:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Stepping:")), 0, wxALL, 4)
296          self.stepCtrl = wxTextCtrl(self, ID_RANGE_STEP, style=wxTE_RIGHT)          self.stepCtrl = wxTextCtrl(self, ID_UNIFORM_STEP, style=wxTE_RIGHT)
297          EVT_TEXT(self, ID_RANGE_STEP, self._OnSteppingChanged)          EVT_TEXT(self, ID_UNIFORM_STEP, self._OnSteppingChanged)
298          sizer.Add(self.stepCtrl , 0, wxALL, 4)          sizer.Add(self.stepCtrl , 1, wxALL, 4)
299          topSizer.Add(sizer, 0, wxALL, 4)  
300            topSizer.Add(sizer, 1, wxGROW, 0)
301    
302            #############
303    
304          self.SetSizer(topSizer)          self.SetSizer(topSizer)
305          self.SetAutoLayout(True)          self.SetAutoLayout(True)
# Line 141  class GenRangePanel(wxPanel): Line 308  class GenRangePanel(wxPanel):
308          self.numGroupsChanging = False          self.numGroupsChanging = False
309          self.steppingChanging = False          self.steppingChanging = False
310    
311          self.numGroupsCtrl.SetRange(1, 100)          self.numGroupsCtrl.SetRange(1, sys.maxint)
312    
313          self.numGroupsCtrl.SetValue(1)          self.numGroupsCtrl.SetValue(1)
314          self.stepCtrl.SetValue("1")          self.stepCtrl.SetValue("1")
# Line 156  class GenRangePanel(wxPanel): Line 323  class GenRangePanel(wxPanel):
323                                              FIELDTYPE_INT,                                              FIELDTYPE_INT,
324                                              None)                                              None)
325    
         ##if self.__ValidateEntry(self.numGroupsCtrl, value, int):  
             #return value  
   
         #return None  
   
326      def GetStepping(self):      def GetStepping(self):
327          step = self.stepCtrl.GetValue()          step = self.stepCtrl.GetValue()
328          return self.__GetValidatedTypeEntry(self.stepCtrl,          return self.__GetValidatedTypeEntry(self.stepCtrl,
# Line 196  class GenRangePanel(wxPanel): Line 358  class GenRangePanel(wxPanel):
358          self.numGroupsCtrl.Enable(on)          self.numGroupsCtrl.Enable(on)
359          self.stepCtrl.Enable(on)          self.stepCtrl.Enable(on)
360    
         if on:  
             self.numGroupsCtrl.SetRange(1, abs(max - min) / 0.001)  
   
361          ngroups = self.GetNumGroups()          ngroups = self.GetNumGroups()
362    
363          if ngroups is not None  \          if ngroups is not None  \
# Line 206  class GenRangePanel(wxPanel): Line 365  class GenRangePanel(wxPanel):
365              and max is not None \              and max is not None \
366              and ngroups != 0:              and ngroups != 0:
367    
368              self.stepCtrl.SetValue(str((max - min) / ngroups))              #self.stepCtrl.SetValue(str((max - min) / ngroups))
369                self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
370                #self.numGroupsCtrl.SetValue(ngroups)
371    
372              self.parent.AllowGenerate(self.GetStepping() is not None)              self.parent.AllowGenerate(self.GetStepping() is not None)
373          else:          else:
# Line 227  class GenRangePanel(wxPanel): Line 388  class GenRangePanel(wxPanel):
388          min = self.GetMin()          min = self.GetMin()
389          max = self.GetMax()          max = self.GetMax()
390    
         if ngroups >= self.numGroupsCtrl.GetMax():  
             self.numGroupsCtrl.SetRange(1, ngroups + 1)  
   
391          if ngroups is not None  \          if ngroups is not None  \
392              and min is not None \              and min is not None \
393              and max is not None \              and max is not None \
# Line 243  class GenRangePanel(wxPanel): Line 401  class GenRangePanel(wxPanel):
401              # called steppingChanging tries to prevent the recursion.              # called steppingChanging tries to prevent the recursion.
402              #              #
403              self.numGroupsChanging = True              self.numGroupsChanging = True
404              self.stepCtrl.SetValue(str((max - min) / ngroups))  
405                self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
406    
407              self.parent.AllowGenerate(self.GetStepping() is not None)              self.parent.AllowGenerate(self.GetStepping() is not None)
408          else:          else:
# Line 268  class GenRangePanel(wxPanel): Line 427  class GenRangePanel(wxPanel):
427              # see note in _OnNumGroupsChanged              # see note in _OnNumGroupsChanged
428              #              #
429              self.steppingChanging = True              self.steppingChanging = True
430              n = int((max - min) / step)              self.numGroupsCtrl.SetValue(self.__CalcNumGroups(min, max, step))
             if n == 0:  
                 n = 1  
   
             self.numGroupsCtrl.SetValue(n)  
431    
432              self.parent.AllowGenerate(self.GetNumGroups() is not None)              self.parent.AllowGenerate(self.GetNumGroups() is not None)
433          else:          else:
434              self.parent.AllowGenerate(False)              self.parent.AllowGenerate(False)
435    
436        def _OnRetrieve(self, event):
437    
438            if self.layer.table is not None:
439                range = self.layer.table.field_range(self.fieldName)
440                self.minCtrl.SetValue(str(range[0][0]))
441                self.maxCtrl.SetValue(str(range[1][0]))
442    
443      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
444    
445          if type == FIELDTYPE_INT:          if type == FIELDTYPE_INT:
# Line 316  class GenRangePanel(wxPanel): Line 478  class GenRangePanel(wxPanel):
478          win.Refresh()          win.Refresh()
479    
480          return valid          return valid
481    
482        def __CalcStepping(self, min, max, ngroups):
483            step = (max - min) / float(ngroups)
484            if self.fieldType == FIELDTYPE_INT:
485                step = int(step)
486    
487            return step
488    
489        def __CalcNumGroups(self, min, max, step):
490            n = int((max - min) / step)
491            if n == 0:
492                n = 1
493    
494            if self.fieldType == FIELDTYPE_INT and step == 1:
495                n += 1
496    
497            return n
498    
499    
500    ID_UNIQUE_RETRIEVE = 4001
501    ID_UNIQUE_USEALL = 4002
502    ID_UNIQUE_USE = 4003
503    ID_UNIQUE_DONTUSE = 4004
504    ID_UNIQUE_USENONE = 4005
505    ID_UNIQUE_SORTAVAIL = 4006
506    ID_UNIQUE_SORTUSE = 4007
507    ID_UNIQUE_REVAVAIL = 4008
508    ID_UNIQUE_REVUSE = 4009
509    
510    class GenUniquePanel(wxPanel):
511    
512        def __init__(self, parent, layer, fieldName, fieldType):
513            wxPanel.__init__(self, parent, -1)
514    
515            self.parent = parent
516            self.layer = layer
517            self.fieldName = fieldName
518            self.fieldType = fieldType
519    
520            topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
521                                        wxVERTICAL)
522    
523    
524            #bsizer = wxBoxSizer(wxVERTICAL)
525            topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
526                                _("Retrieve From Table")),
527                       0, wxALL | wxALIGN_RIGHT, 4)
528    
529            EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
530    
531            #topSizer.Add(bsizer, 0, wxALL, 4)
532    
533            sizer = wxBoxSizer(wxHORIZONTAL)
534    
535            self.dataList = []
536    
537            psizer = wxBoxSizer(wxVERTICAL)
538            self.list_avail = wxListCtrl(self, -1,
539                            style=wxLC_REPORT | wxLC_SINGLE_SEL)
540            self.list_avail.InsertColumn(0, "Available")
541            self.list_avail_data = []
542            psizer.Add(self.list_avail, 1, wxGROW, 0)
543    
544            bsizer = wxBoxSizer(wxHORIZONTAL)
545            bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
546            EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
547    
548            bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
549            EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
550    
551            psizer.Add(bsizer, 0, wxGROW, 0)
552            sizer.Add(psizer, 1, wxGROW, 0)
553    
554                    
555            bsizer = wxBoxSizer(wxVERTICAL)
556    
557            bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
558            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
559                       0, wxGROW | wxALL, 4)
560            bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
561            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
562                       0, wxGROW | wxALL, 4)
563            bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
564            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
565                       0, wxGROW | wxALL, 4)
566            bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
567            bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
568                       0, wxGROW | wxALL, 4)
569    
570            EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
571            EVT_BUTTON(self, ID_UNIQUE_USE, self._OnUse)
572            EVT_BUTTON(self, ID_UNIQUE_DONTUSE, self._OnDontUse)
573            EVT_BUTTON(self, ID_UNIQUE_USENONE, self._OnUseNone)
574    
575            sizer.Add(bsizer, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
576    
577            psizer = wxBoxSizer(wxVERTICAL)
578            self.list_use = wxListCtrl(self, -1,
579                            style=wxLC_REPORT | wxLC_SINGLE_SEL)
580            self.list_use.InsertColumn(0, "Use")
581            self.list_use_data = []
582            psizer.Add(self.list_use, 1, wxGROW, 0)
583    
584            bsizer = wxBoxSizer(wxHORIZONTAL)
585            bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
586            EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
587    
588            bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
589            EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
590    
591            psizer.Add(bsizer, 0, wxGROW, 0)
592    
593            sizer.Add(psizer, 1, wxGROW, 0)
594    
595    
596            topSizer.Add(sizer, 1, wxGROW, 0)
597    
598            self.SetSizer(topSizer)
599            self.SetAutoLayout(True)
600            topSizer.SetSizeHints(self)
601    
602            self.parent.AllowGenerate(False)
603    
604            self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]
605    
606        def GetNumGroups(self):
607            return self.list_use.GetItemCount()
608    
609        def GetValueList(self):
610            list = []
611            for i in range(self.list_use.GetItemCount()):
612                list.append(self.dataList[self.list_use.GetItemData(i)])
613            return list
614    
615        def _OnSortList(self, event):
616            id = event.GetId()
617    
618            if id == ID_UNIQUE_SORTUSE:
619                list = self.list_use
620            else:
621                list = self.list_avail
622    
623            list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
624                                              self.dataList[i2]))
625    
626        def _OnReverseList(self, event):
627            id = event.GetId()
628    
629            if id == ID_UNIQUE_REVUSE:
630                list = self.list_use
631            else:
632                list = self.list_avail
633    
634            #
635            # always returning 1 reverses the list
636            #
637            list.SortItems(lambda i1, i2: 1)
638    
639        def _OnRetrieve(self, event):
640            self.list_use.DeleteAllItems()
641            self.list_use_data = []
642            self.list_avail.DeleteAllItems()
643            self.list_avail_data = []
644    
645            list = self.layer.table.GetUniqueValues(self.fieldName)
646            index = 0
647            for v in list:
648                self.dataList.append(v)
649                i = self.list_avail.InsertStringItem(index, str(v))
650                self.list_avail.SetItemData(index, i)
651    
652                self.list_avail_data.append(v)
653                index += 1
654    
655        def _OnUseAll(self, event):
656            for i in range(self.list_avail.GetItemCount()):
657                self.__MoveListItem(0, self.list_avail, self.list_use)
658    
659        def _OnUse(self, event):
660            self.__MoveSelectedItems(self.list_avail, self.list_use)
661    
662        def _OnDontUse(self, event):
663            self.__MoveSelectedItems(self.list_use, self.list_avail)
664    
665        def _OnUseNone(self, event):
666    
667            for i in range(self.list_use.GetItemCount()):
668                self.__MoveListItem(0, self.list_use, self.list_avail)
669    
670        def __MoveSelectedItems(self, list_src, list_dest):
671            while True:
672                index = list_src.GetNextItem(-1,
673                                             wxLIST_NEXT_ALL,
674                                             wxLIST_STATE_SELECTED)
675    
676                if index == -1:
677                    break
678    
679                self.__MoveListItem(index, list_src, list_dest)
680    
681    
682        def __MoveListItem(self, index, list_src, list_dest):
683    
684            item = list_src.GetItem(index)
685    
686  class GenSingletonPanel(wxPanel):          x = list_dest.InsertStringItem(
687                    list_dest.GetItemCount(),
688                    str(self.dataList[item.GetData()]))
689    
690      def __init__(self, parent, table, fieldName, fieldType):          list_dest.SetItemData(x, item.GetData())
691    
692            list_src.DeleteItem(index)
693    
694    #   def _OnListSize(self, event):
695    #       list = event.GetEventObject()
696    
697    #       list.SetColumnWidth(0, event.GetSize().GetWidth())
698    #      
699    
700    ID_CUSTOMRAMP_COPYSTART = 4001
701    ID_CUSTOMRAMP_COPYEND = 4002
702    ID_CUSTOMRAMP_EDITSTART = 4003
703    ID_CUSTOMRAMP_EDITEND = 4004
704    ID_CUSTOMRAMP_SPROP = 4005
705    ID_CUSTOMRAMP_EPROP = 4006
706    
707    class CustomRampPanel(wxPanel):
708    
709        def __init__(self, parent, shapeType):
710          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
711    
712            topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""), wxHORIZONTAL)
713    
714            bsizer = wxBoxSizer(wxVERTICAL)
715            bsizer.Add(wxStaticText(self, -1, _("Start:")), 0, wxALL | wxCENTER, 4)
716            self.startPropCtrl = classifier.ClassGroupPropertiesCtrl(
717                self, ID_CUSTOMRAMP_SPROP,
718                ClassGroupProperties(), shapeType,
719                style=wxSIMPLE_BORDER, size=(40, 20))
720            bsizer.Add(self.startPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
721            bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITSTART, _("Change")),
722                       0, wxGROW | wxALL | wxCENTER, 4)
723    
724            topSizer.Add(bsizer,
725                       1, wxALL \
726                          | wxSHAPED \
727                          | wxALIGN_CENTER_HORIZONTAL \
728                          | wxALIGN_CENTER_VERTICAL, \
729                       4)
730    
731            bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
732            bsizer = wxBoxSizer(wxVERTICAL)
733            bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
734                       0, wxGROW | wxALL, 4)
735            bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
736            bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
737                       0, wxGROW | wxALL, 4)
738    
739            topSizer.Add(bsizer,
740                       0, wxALL \
741                          | wxALIGN_CENTER_HORIZONTAL \
742                          | wxALIGN_CENTER_VERTICAL,
743                       4)
744    
745            bsizer = wxBoxSizer(wxVERTICAL)
746            bsizer.Add(wxStaticText(self, -1, _("End:")), 0, wxALL | wxCENTER, 4)
747            self.endPropCtrl = classifier.ClassGroupPropertiesCtrl(
748                self, ID_CUSTOMRAMP_EPROP,
749                ClassGroupProperties(), shapeType,
750                style=wxSIMPLE_BORDER, size=(40, 20))
751            bsizer.Add(self.endPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
752            bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITEND, _("Change")),
753                       0, wxGROW | wxALL | wxCENTER, 4)
754    
755            topSizer.Add(bsizer,
756                       1, wxALL \
757                          | wxSHAPED \
758                          | wxALIGN_RIGHT \
759                          | wxALIGN_CENTER_HORIZONTAL \
760                          | wxALIGN_CENTER_VERTICAL,
761                       4)
762    
763            EVT_BUTTON(self, ID_CUSTOMRAMP_COPYSTART, self._OnCopyStart)
764            EVT_BUTTON(self, ID_CUSTOMRAMP_COPYEND, self._OnCopyEnd)
765            EVT_BUTTON(self, ID_CUSTOMRAMP_EDITSTART, self._OnEditStart)
766            EVT_BUTTON(self, ID_CUSTOMRAMP_EDITEND, self._OnEditEnd)
767    
768            self.SetSizer(topSizer)
769            self.SetAutoLayout(True)
770            topSizer.SetSizeHints(self)
771    
772        def GetRamp(self):
773            return CustomRamp(self.startPropCtrl.GetProperties(),
774                              self.endPropCtrl.GetProperties())
775    
776        def _OnCopyStart(self, event):
777            self.endPropCtrl.SetProperties(self.startPropCtrl.GetProperties())
778    
779        def _OnCopyEnd(self, event):
780            self.startPropCtrl.SetProperties(self.endPropCtrl.GetProperties())
781    
782        def _OnEditStart(self, event):
783            self.startPropCtrl.DoEdit()
784    
785        def _OnEditEnd(self, event):
786            self.endPropCtrl.DoEdit()
787    
788  class ClassGenerator:  class ClassGenerator:
789    
790      def GenerateSingletons(self, list, numGroups, prop1, prop2):      def GenSingletonsFromList(self, list, numGroups, ramp):
791          """Generate a new classification consisting solely of singletons.          """Generate a new classification consisting solely of singletons.
792    
793          The resulting classification will consist of at most 'numGroups'          The resulting classification will consist of at most 'numGroups'
# Line 348  class ClassGenerator: Line 809  class ClassGenerator:
809          clazz = Classification()          clazz = Classification()
810          if numGroups == 0: return clazz          if numGroups == 0: return clazz
811    
812          for value, prop in zip(list, PropertyRamp(numGroups, prop1, prop2)):          ramp.SetNumGroups(numGroups)
813    
814            for value, prop in zip(list, ramp):
815              clazz.AppendGroup(ClassGroupSingleton(value, prop))              clazz.AppendGroup(ClassGroupSingleton(value, prop))
816    
817          return clazz          return clazz
818    
819      def GenerateRanges(self, min, max, numGroups, prop1, prop2):      def GenSingletons(self, min, max, numGroups, ramp):
820    
821            clazz = Classification()
822    
823            #step = int((max - min) / float(numGroups))
824    
825            if numGroups > 0:
826    
827                step = int((max - min + 1) / float(numGroups))
828                cur_value = min
829    
830                ramp.SetNumGroups(numGroups)
831    
832                for prop in ramp:
833                    clazz.AppendGroup(ClassGroupSingleton(cur_value), prop)
834                    cur_value += step
835    
836            return clazz
837    
838        def GenUnifromDistribution(self, min, max, numGroups,
839                                   ramp, intStep = False):
840            """Generate a classification with numGroups range groups
841            each with the same interval.
842    
843            intStep -- force the calculated stepping to an integer.
844                       Useful if the values are integers but the
845                       number of groups specified doesn't evenly
846                       divide (max - min).
847            """
848    
849          clazz = Classification()          clazz = Classification()
850          if numGroups == 0: return clazz          if numGroups == 0: return clazz
851    
852            ramp.SetNumGroups(numGroups)
853    
854          step = (max - min) / float(numGroups)          step = (max - min) / float(numGroups)
855    
856            if intStep:
857                step = int(step)
858    
859          cur_min = min          cur_min = min
860          cur_max = cur_min + step          cur_max = cur_min + step
861    
862          i = 0          i = 0
863          for prop in PropertyRamp(numGroups, prop1, prop2):          for prop in ramp:
864    
865              if i == (numGroups - 1):              if i == (numGroups - 1):
866                  cur_max = max                  cur_max = max
# Line 379  class ClassGenerator: Line 875  class ClassGenerator:
875    
876          return clazz          return clazz
877    
878  class PropertyRamp:  CLR  = 0
879    STEP = 1
880    class CustomRamp:
881    
882        def __init__(self, prop1, prop2):
883            self.prop1 = prop1
884            self.prop2 = prop2
885    
886            self.count = 0
887    
888        def __iter__(self):
889            return self
890    
891        def GetRamp(self):
892            return self
893    
894        def SetNumGroups(self, num):
895    
896      def __init__(self, num, prop1, prop2):          if num <= 0:
897                return False
898    
899          self.count = int(num)          self.count = int(num)
900          num = float(num)          num = float(num)
901    
902            prop1 = self.prop1
903            prop2 = self.prop2
904    
905          self.lineColor = prop1.GetLineColor()          clr = prop1.GetLineColor()
         self.fillColor = prop1.GetFill()  
         self.lineWidth = prop1.GetLineWidth()  
   
906          lineColor2 = prop2.GetLineColor()          lineColor2 = prop2.GetLineColor()
907          fillColor2 = prop2.GetFill()          
908          lineWidth2 = prop2.GetLineWidth()          self.noLine = clr is not Color.Transparent \
909                            and lineColor2 is not Color.Transparent
910    
         self.line_redStep   = (lineColor2.red   - self.lineColor.red)   / num  
         self.line_greenStep = (lineColor2.green - self.lineColor.green) / num  
         self.line_blueStep  = (lineColor2.blue  - self.lineColor.blue)  / num  
   
         self.line_widthStep = (lineWidth2 - self.lineWidth) / num  
   
         self.fill_redStep   = (fillColor2.red   - self.fillColor.red)   / num  
         self.fill_greenStep = (fillColor2.green - self.fillColor.green) / num  
         self.fill_blueStep  = (fillColor2.blue  - self.fillColor.blue)  / num  
911    
912      def __iter__(self):          self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),
913          return self                                              prop2.GetLineColor(),
914                                                num)
915    
916            self.fillInfo = self.__GetColorInfo(prop1.GetFill(),
917                                                prop2.GetFill(),
918                                                num)
919    
920            self.lineWidth = prop1.GetLineWidth()
921            self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num
922    
923            return True
924    
925      def next(self):      def next(self):
926          if self.count == 0:          if self.count == 0:
927              raise StopIteration              raise StopIteration
928    
929          prop = ClassGroupProperties()          prop = ClassGroupProperties()
930          prop.SetFill(self.fillColor)  
931          prop.SetLineColor(self.lineColor)          if self.lineInfo is None:
932                prop.SetLineColor(Color.Transparent)
933            else:
934                prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,
935                                        self.lineInfo[CLR][1] / 255,
936                                        self.lineInfo[CLR][2] / 255))
937    
938                self.lineInfo[CLR][0] += self.lineInfo[STEP][0]
939                self.lineInfo[CLR][1] += self.lineInfo[STEP][1]
940                self.lineInfo[CLR][2] += self.lineInfo[STEP][2]
941    
942            if self.fillInfo is None:
943                prop.SetFill(Color.Transparent)
944            else:
945                prop.SetFill(Color(self.fillInfo[CLR][0] / 255,
946                                self.fillInfo[CLR][1] / 255,
947                                self.fillInfo[CLR][2] / 255))
948    
949                self.fillInfo[CLR][0] += self.fillInfo[STEP][0]
950                self.fillInfo[CLR][1] += self.fillInfo[STEP][1]
951                self.fillInfo[CLR][2] += self.fillInfo[STEP][2]
952    
953    
954          prop.SetLineWidth(int(self.lineWidth))          prop.SetLineWidth(int(self.lineWidth))
955            self.lineWidth        += self.lineWidthStep
956    
957            self.count -= 1
958    
959            return prop
960    
961        def __GetColorInfo(self, color1, color2, numGroups):
962    
963            if color1 is Color.Transparent and color2 is Color.Transparent:
964                #
965                # returning early
966                #
967                return None
968            elif color1 is not Color.Transparent and color2 is Color.Transparent:
969                color = [color1.red   * 255,
970                         color1.green * 255,
971                         color1.blue  * 255]
972                step = (0, 0, 0)
973            elif color1 is Color.Transparent and color2 is not Color.Transparent:
974                color = [color2.red   * 255,
975                         color2.green * 255,
976                         color2.blue  * 255]
977                step = (0, 0, 0)
978            else:
979                color = [color1.red   * 255,
980                         color1.green * 255,
981                         color1.blue  * 255]
982                step = ((color2.red   * 255 - color1.red   * 255)   / numGroups,
983                        (color2.green * 255 - color1.green * 255) / numGroups,
984                        (color2.blue  * 255 - color1.blue  * 255)  / numGroups)
985    
986    
987            return (color, step)
988    
989    class MonochromaticRamp(CustomRamp):
990        def __init__(self, start, end):
991            sp = ClassGroupProperties()
992            sp.SetLineColor(start)
993            sp.SetFill(start)
994    
995            ep = ClassGroupProperties()
996            ep.SetLineColor(end)
997            ep.SetFill(end)
998    
999            CustomRamp.__init__(self, sp, ep)
1000    
1001    class GreyRamp(MonochromaticRamp):
1002        def __init__(self):
1003            MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))
1004    
1005    class RedRamp(MonochromaticRamp):
1006        def __init__(self):
1007            MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(.8, 0, 0))
1008    
1009    class GreenRamp(MonochromaticRamp):
1010        def __init__(self):
1011            MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, .8, 0))
1012    
1013    class BlueRamp(MonochromaticRamp):
1014        def __init__(self):
1015            MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, .8))
1016    
1017    class HotToColdRamp:
1018    
1019        def __iter__(self):
1020            return self
1021                    
1022          self.lineColor.red   += self.line_redStep      def GetRamp(self):
1023          self.lineColor.green += self.line_greenStep          return self
         self.lineColor.blue  += self.line_blueStep  
   
         self.fillColor.red   += self.fill_redStep  
         self.fillColor.green += self.fill_greenStep  
         self.fillColor.blue  += self.fill_blueStep  
1024    
1025          self.lineWidth       += self.line_widthStep      def SetNumGroups(self, num):
1026            if num < 0:
1027                return False
1028    
1029          self.count -= 1          self.num = float(num)
1030            self.index = 0
1031    
1032            return True
1033    
1034        def next(self):
1035            if self.index == self.num:
1036                raise StopIteration
1037    
1038            clr = [1.0, 1.0, 1.0]
1039    
1040            if self.index < (.25 * self.num):
1041                clr[0] = 0
1042                clr[1] = 4 * self.index / self.num
1043            elif self.index < (.5 * self.num):
1044                clr[0] = 0
1045                clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num
1046            elif self.index < (.75 * self.num):
1047                clr[0] = 4 * (self.index - .5 * self.num) / self.num
1048                clr[2] = 0
1049            else:
1050                clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num
1051                clr[2] = 0
1052    
1053            self.index += 1
1054    
1055            prop = ClassGroupProperties()
1056            prop.SetLineColor(Color(clr[0], clr[1], clr[2]))
1057            prop.SetFill(Color(clr[0], clr[1], clr[2]))
1058    
1059          return prop          return prop
1060    
1061    #class Colors16Ramp:
1062    #
1063        #def __iter__(self):
1064            #return self
1065    #
1066        #def GetRamp(self):
1067            #return self
1068    #
1069        #def SetNumGroups(self, num):
1070            #if num < 0:
1071                #return False
1072    #
1073            #self.index = 0
1074    #
1075            #return True
1076    
1077        

Legend:
Removed from v.620  
changed lines
  Added in v.781

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26