/[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 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 316  class GenRangePanel(wxPanel): Line 476  class GenRangePanel(wxPanel):
476          win.Refresh()          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            self.parent.AllowGenerate(False)
601    
602  class GenSingletonPanel(wxPanel):          self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]
603    
604      def __init__(self, parent, table, fieldName, fieldType):      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 348  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    
812            for value, prop in zip(list, ramp):
813              clazz.AppendGroup(ClassGroupSingleton(value, prop))              clazz.AppendGroup(ClassGroupSingleton(value, prop))
814    
815          return clazz          return clazz
816    
817      def GenerateRanges(self, min, max, numGroups, prop1, prop2):      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
835    
836        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
# Line 379  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.620  
changed lines
  Added in v.834

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26