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

Legend:
Removed from v.607  
changed lines
  Added in v.834

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26