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

Legend:
Removed from v.614  
changed lines
  Added in v.812

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26