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

Legend:
Removed from v.620  
changed lines
  Added in v.660

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26