/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26