/[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 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 316  class GenRangePanel(wxPanel): Line 475  class GenRangePanel(wxPanel):
475          win.Refresh()          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  class GenSingletonPanel(wxPanel):          topSizer.Add(sizer, 1, wxGROW, 0)
594    
595      def __init__(self, parent, table, fieldName, fieldType):          self.SetSizer(topSizer)
596            self.SetAutoLayout(True)
597            topSizer.SetSizeHints(self)
598    
599            self.parent.AllowGenerate(False)
600    
601            self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]
602    
603        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 348  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 379  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            self.count = 0
884    
885      def __init__(self, num, prop1, prop2):      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.620  
changed lines
  Added in v.812

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26