/[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 654 by jonathan, Fri Apr 11 15:49:58 2003 UTC revision 978 by frank, Thu May 22 11:40:32 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 *
13    
14  from Thuban.Model.classification import Classification, ClassGroupRange, \  from Thuban.Model.classification import ClassGroupProperties
     ClassGroupSingleton, ClassGroupProperties  
15    
16  from Thuban.Model.table import Table, FIELDTYPE_INT, FIELDTYPE_DOUBLE, \  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
17       FIELDTYPE_STRING       FIELDTYPE_STRING
18    
19  from Thuban.Model.color import Color  from Thuban.Model.range import Range
   
 import classifier  
   
 import resource  
20    
21  from Thuban.common import Str2Num  import classifier, resource
22    
23  ID_CLASSGEN_GEN = 4001  from Thuban.Model.classgen import ClassGenerator, \
24  ID_CLASSGEN_CLOSE = 4002      CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
25  ID_CLASSGEN_GENCOMBO = 4007      HotToColdRamp
 ID_CLASSGEN_PROPCOMBO = 4008  
26    
27  USEALL_BMP  = "group_use_all"  USEALL_BMP  = "group_use_all"
28  USE_BMP     = "group_use"  USE_BMP     = "group_use"
# Line 35  USENONE_BMP = "group_use_none" Line 31  USENONE_BMP = "group_use_none"
31    
32  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")  GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
33  GENCOMBOSTR_UNIQUE = _("Unique Values")  GENCOMBOSTR_UNIQUE = _("Unique Values")
34    GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
35    
36  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")  PROPCOMBOSTR_CUSTOM     = _("Custom Ramp")
37  PROPCOMBOSTR_GREY       = _("Grey Ramp")  PROPCOMBOSTR_GREY       = _("Grey Ramp")
38  PROPCOMBOSTR_RED        = _("Red Ramp")  PROPCOMBOSTR_RED        = _("Red Ramp")
39  PROPCOMBOSTR_GREEN      = _("Green Ramp")  PROPCOMBOSTR_GREEN      = _("Green Ramp")
40  PROPCOMBOSTR_BLUE       = _("Blue Ramp")  PROPCOMBOSTR_BLUE       = _("Blue Ramp")
41    PROPCOMBOSTR_GREEN2RED  = _("Green-to-Red Ramp")
42  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Ramp")
43    
44    ID_CLASSGEN_GENCOMBO = 4007
45    ID_CLASSGEN_PROPCOMBO = 4008
46    
47  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
48                                                                                    
49      def __init__(self, parent, layer, fieldName):      def __init__(self, parent, layer, fieldName):
50          """Inialize the class generating dialog.          """Inialize the class generating dialog.
51    
# Line 53  class ClassGenDialog(wxDialog): Line 54  class ClassGenDialog(wxDialog):
54    
55          wxDialog.__init__(self, parent, -1, _("Generate Classification"),          wxDialog.__init__(self, parent, -1, _("Generate Classification"),
56                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
57                                                                                    
58          self.parent = parent          self.parent = parent
59            self.layer = layer
60          self.clazz = None          self.clazz = None
61    
62          self.type, name, width, prec = layer.table.field_info_by_name(fieldName)          col = layer.table.Column(fieldName)
63            self.type = col.type
64    
65            self.fieldName = fieldName
66            self.fieldType = self.type
67    
68            self.curGenPanel = None
69    
70            self.genpanels = []
71    
72          #############          #############
73          # we need to create genButton first because when we create the          # we need to create genButton first because when we create the
74          # panels they will call AllowGenerate() which uses genButton.          # panels they will call AllowGenerate() which uses genButton.
75          #          #
76          buttonSizer = wxBoxSizer(wxHORIZONTAL)          self.genButton = wxButton(self, wxID_OK, _("Generate"))
77          self.genButton = wxButton(self, ID_CLASSGEN_GEN, _("Generate"))          self.genButton.SetDefault()
78            self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
79    
80            self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
81    
82            self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
83            if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
84                self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
85                self.genpanels.append((GENCOMBOSTR_QUANTILES, GenQuantilesPanel))
86    
87            for name, clazz in self.genpanels:
88                self.genChoice.Append(name, [clazz, None])
89    
90            self.genChoice.SetSelection(0)
91    
92            for i in range(self.genChoice.GetCount()):
93                clazz, obj = self.genChoice.GetClientData(i)
94    
95                if obj is None:
96                    obj = clazz(self, self.layer, self.fieldName, self.fieldType)
97                    obj.Hide()
98                    self.genChoice.SetClientData(i, [clazz, obj])
99    
         buttonSizer.Add(self.genButton, 0, wxALL, 4)  
         buttonSizer.Add(60, 20, 0, wxALL, 4)  
         buttonSizer.Add(wxButton(self, ID_CLASSGEN_CLOSE, _("Close")),  
                         0, wxALL, 4)  
100    
101          #############          #############
102    
# Line 85  class ClassGenDialog(wxDialog): Line 112  class ClassGenDialog(wxDialog):
112          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
113          psizer.Add(wxStaticText(self, -1, _("Generate:")),          psizer.Add(wxStaticText(self, -1, _("Generate:")),
114              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
115            psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
         self.genCombo = wxComboBox(self,  
                                    ID_CLASSGEN_GENCOMBO,  
                                    "", style = wxCB_READONLY)  
         psizer.Add(self.genCombo, 1, wxALL | wxGROW, 4)  
         EVT_COMBOBOX(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)  
116    
117          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
118    
119          #############          self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
120            sizer.Add(self.sizer_genPanel, 1, wxGROW | wxALL, 4)
         self.genPanel = None  
   
         panel = GenUniquePanel(self, layer, fieldName, self.type)  
         self.genCombo.Append(GENCOMBOSTR_UNIQUE, panel)  
         sizer.Add(panel, 1, wxGROW | wxALL, 4)  
   
         self.genPanel = panel  
   
         if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):  
             panel = GenUniformPanel(self, layer, fieldName, self.type)  
             self.genCombo.Append(GENCOMBOSTR_UNIFORM, panel)  
             sizer.Add(panel, 0, wxGROW | wxALL, 4)  
             sizer.Show(panel, False)  
   
         #############  
121    
122          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
123          psizer.Add(wxStaticText(self, -1, _("Color Schemes:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
124              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
125    
126          self.propCombo = wxComboBox(self,          # Properties (Ramp) ComboBox
127                                     ID_CLASSGEN_PROPCOMBO,          self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
                                    "", style = wxCB_READONLY)  
         psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)  
         EVT_COMBOBOX(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)  
         sizer.Add(psizer, 0, wxALL | wxGROW, 4)  
   
         #############  
128    
129          self.propPanel = None          self.propPanel = None
130          panel = CustomRampPanel(self, layer.ShapeType())          custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
         sizer.Add(panel, 1, wxALL | wxGROW, 4)  
         sizer.Show(panel, False)  
131    
132          self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())          self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())
133          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())
134          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
135          self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())          self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())
136            self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())
137          self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())          self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
138          self.propCombo.Append(PROPCOMBOSTR_CUSTOM, panel)          self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
139    
140            self.propCombo.SetSelection(0)
141    
142            psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
143            sizer.Add(psizer, 0, wxALL | wxGROW, 4)
144    
145          #############          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
146            sizer.Show(custom_ramp_panel, False)
         sizer.Add(buttonSizer, 0,  
                   wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)  
147    
148            # Finally place the main buttons
149            buttonSizer = wxBoxSizer(wxHORIZONTAL)
150            buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
151            buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
152            sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
153    
154          self.SetSizer(sizer)          self.SetSizer(sizer)
155          self.SetAutoLayout(True)          self.SetAutoLayout(True)
156          sizer.SetSizeHints(self)          sizer.SetSizeHints(self)
157    
158          self.sizer = sizer          self.topBox = sizer
159    
160            self.__DoOnGenTypeSelect()
161    
162          EVT_BUTTON(self, ID_CLASSGEN_GEN, self._OnGenerate)          EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
163          EVT_BUTTON(self, ID_CLASSGEN_CLOSE, self._OnCloseBtn)          EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
164            EVT_BUTTON(self, wxID_OK, self.OnOK)
165            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
166    
167            self.__DoOnGenTypeSelect()
168    
169            self.genChoice.SetFocus()
170    
171      def GetClassification(self):      def GetClassification(self):
172          return self.clazz          return self.clazz
# Line 160  class ClassGenDialog(wxDialog): Line 174  class ClassGenDialog(wxDialog):
174      def AllowGenerate(self, on):      def AllowGenerate(self, on):
175          pass #self.genButton.Enable(on)          pass #self.genButton.Enable(on)
176    
177      def _OnGenerate(self, event):      def OnOK(self, event):
178            """This is really the generate button, but we want to override
179            the wxDialog class.
180            """
181    
182          index = self.genCombo.GetSelection()          index = self.genChoice.GetSelection()
183    
184          genSel = self.genCombo.GetString(index)          assert index != -1, "button should be disabled!"
185          genPanel = self.genCombo.GetClientData(index)  
186            genSel = self.genChoice.GetString(index)
187            clazz, genPanel = self.genChoice.GetClientData(index)
188    
189          propPanel = self.propPanel          propPanel = self.propPanel
190    
191          if genSel in (GENCOMBOSTR_UNIFORM, GENCOMBOSTR_UNIQUE):          if genSel in (GENCOMBOSTR_UNIFORM,          \
192                          GENCOMBOSTR_UNIQUE,           \
193                          GENCOMBOSTR_QUANTILES):
194    
195              numGroups = genPanel.GetNumGroups()              numGroups = genPanel.GetNumGroups()
196    
197              index = self.propCombo.GetSelection()              index = self.propCombo.GetSelection()
# Line 188  class ClassGenDialog(wxDialog): Line 210  class ClassGenDialog(wxDialog):
210                      and max is not None \                      and max is not None \
211                      and numGroups is not None:                      and numGroups is not None:
212    
213                      self.clazz = ClassGenerator().GenUnifromDistribution(                      self.clazz = ClassGenerator().GenUniformDistribution(
214                                  min, max, numGroups, ramp,                                  min, max, numGroups, ramp,
215                                  self.type == FIELDTYPE_INT)                                  self.type == FIELDTYPE_INT)
216    
# Line 206  class ClassGenDialog(wxDialog): Line 228  class ClassGenDialog(wxDialog):
228    
229                      self.parent._SetClassification(self.clazz)                      self.parent._SetClassification(self.clazz)
230    
231      def _OnCloseBtn(self, event):              elif genSel == GENCOMBOSTR_QUANTILES:
232    
233                    _range = genPanel.GetRange()
234                    _list = genPanel.GetList()
235                    _list.sort()
236    
237                    delta = 1 / float(numGroups)
238                    percents = [delta * i for i in range(1, numGroups + 1)]
239                    adjusted, self.clazz = \
240                        ClassGenerator().GenQuantiles(_list, percents, ramp, _range)
241    
242                    if adjusted:
243                        dlg = wxMessageDialog(self,
244                            _("Based on the data from the table and the input\n" +
245                              "values, the exact quantiles could not be generated.\n\n" +
246                              "Accept a close estimate?"),
247                            _("Problem with Quantiles"),
248    
249                            wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
250                        if dlg.ShowModal() == wxID_YES:
251                            self.parent._SetClassification(self.clazz)
252                    else:
253                        self.parent._SetClassification(self.clazz)
254    
255        def OnCancel(self, event):
256          self.Close()          self.Close()
257    
258      def _OnGenTypeSelect(self, event):      def _OnGenTypeSelect(self, event):
259            self.__DoOnGenTypeSelect()
260            return
261    
262          combo = event.GetEventObject()          combo = event.GetEventObject()
263    
264          selIndex = combo.GetSelection()          selIndex = combo.GetSelection()
265    
266          if self.genPanel is not None:          if self.genPanel is not None:
267              self.sizer.Show(self.genPanel, False)              self.topBox.Show(self.genPanel, False)
268    
269          self.genPanel = combo.GetClientData(selIndex)          self.genPanel = combo.GetClientData(selIndex)
270          if self.genPanel is not None:          if self.genPanel is not None:
271              self.sizer.Show(self.genPanel, True)              self.topBox.Show(self.genPanel, True)
272    
273          self.sizer.SetSizeHints(self)          self.topBox.SetSizeHints(self)
274          self.sizer.Layout()          self.topBox.Layout()
275    
276      def _OnPropTypeSelect(self, event):      def _OnPropTypeSelect(self, event):
277          combo = event.GetEventObject()          combo = event.GetEventObject()
# Line 232  class ClassGenDialog(wxDialog): Line 280  class ClassGenDialog(wxDialog):
280          sel = combo.GetString(selIndex)          sel = combo.GetString(selIndex)
281    
282          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
283              self.sizer.Show(self.propPanel, False)              self.topBox.Show(self.propPanel, False)
284    
285          self.propPanel = combo.GetClientData(selIndex)          self.propPanel = combo.GetClientData(selIndex)
286    
287          if isinstance(self.propPanel, wxPanel):          if isinstance(self.propPanel, wxPanel):
288              self.sizer.Show(self.propPanel, True)              self.topBox.Show(self.propPanel, True)
289    
290            self.topBox.SetSizeHints(self)
291            self.topBox.Layout()
292    
293        def __DoOnGenTypeSelect(self):
294            choice = self.genChoice
295    
296            sel = choice.GetSelection()
297            if sel == -1: return
298    
299          self.sizer.SetSizeHints(self)          clazz, obj = choice.GetClientData(sel)
         self.sizer.Layout()  
300    
301            if self.curGenPanel is not None:
302                self.curGenPanel.Hide()
303                self.sizer_genPanel.Remove(self.curGenPanel)
304    
305            self.curGenPanel = obj
306            self.curGenPanel.Show()
307    
308            self.sizer_genPanel.Add(self.curGenPanel, 1,
309                wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
310            self.sizer_genPanel.Layout()
311            self.Layout()
312            self.topBox.SetSizeHints(self)
313    
314  ID_UNIFORM_MIN = 4001  ID_UNIFORM_MIN = 4001
315  ID_UNIFORM_MAX = 4002  ID_UNIFORM_MAX = 4002
# Line 287  class GenUniformPanel(wxPanel): Line 355  class GenUniformPanel(wxPanel):
355          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
356    
357          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
358          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS, style=wxTE_RIGHT)          self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
359                                            style=wxTE_RIGHT)
360          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
361          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)          EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
362          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)          sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
# Line 308  class GenUniformPanel(wxPanel): Line 377  class GenUniformPanel(wxPanel):
377          self.numGroupsChanging = False          self.numGroupsChanging = False
378          self.steppingChanging = False          self.steppingChanging = False
379    
380          self.numGroupsCtrl.SetRange(1, 100)          self.numGroupsCtrl.SetRange(1, sys.maxint)
381    
382          self.numGroupsCtrl.SetValue(1)          self.numGroupsCtrl.SetValue(1)
383          self.stepCtrl.SetValue("1")          self.stepCtrl.SetValue("1")
# Line 358  class GenUniformPanel(wxPanel): Line 427  class GenUniformPanel(wxPanel):
427          self.numGroupsCtrl.Enable(on)          self.numGroupsCtrl.Enable(on)
428          self.stepCtrl.Enable(on)          self.stepCtrl.Enable(on)
429    
         if on:  
             self.numGroupsCtrl.SetRange(1, abs(max - min) / 0.001)  
   
430          ngroups = self.GetNumGroups()          ngroups = self.GetNumGroups()
431    
432          if ngroups is not None  \          if ngroups is not None  \
# Line 391  class GenUniformPanel(wxPanel): Line 457  class GenUniformPanel(wxPanel):
457          min = self.GetMin()          min = self.GetMin()
458          max = self.GetMax()          max = self.GetMax()
459    
         if ngroups >= self.numGroupsCtrl.GetMax():  
             self.numGroupsCtrl.SetRange(1, ngroups + 1)  
   
460          if ngroups is not None  \          if ngroups is not None  \
461              and min is not None \              and min is not None \
462              and max is not None \              and max is not None \
# Line 442  class GenUniformPanel(wxPanel): Line 505  class GenUniformPanel(wxPanel):
505      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
506    
507          if self.layer.table is not None:          if self.layer.table is not None:
508              range = self.layer.table.field_range(self.fieldName)              wxBeginBusyCursor()
509              self.minCtrl.SetValue(str(range[0][0]))              min, max = self.layer.table.ValueRange(self.fieldName)
510              self.maxCtrl.SetValue(str(range[1][0]))              self.minCtrl.SetValue(str(min))
511                self.maxCtrl.SetValue(str(max))
512                wxEndBusyCursor()
513    
514      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
515    
# Line 486  class GenUniformPanel(wxPanel): Line 551  class GenUniformPanel(wxPanel):
551          return valid          return valid
552    
553      def __CalcStepping(self, min, max, ngroups):      def __CalcStepping(self, min, max, ngroups):
554          step = Str2Num(str((max - min) / float(ngroups)))          step = (max - min) / float(ngroups)
555          if self.fieldType == FIELDTYPE_INT:          if self.fieldType == FIELDTYPE_INT:
556              step = int(step)              step = int(step)
557    
# Line 605  class GenUniquePanel(wxPanel): Line 670  class GenUniquePanel(wxPanel):
670          self.SetAutoLayout(True)          self.SetAutoLayout(True)
671          topSizer.SetSizeHints(self)          topSizer.SetSizeHints(self)
672    
673          self.parent.AllowGenerate(False)          width, height = self.list_avail.GetSizeTuple()
674            self.list_avail.SetColumnWidth(0,width)
675            width, height = self.list_use.GetSizeTuple()
676            self.list_use.SetColumnWidth(0,width)
677    
678          self.mylist = ["Hallo", "Welt!", "Wie", "geht", "es", "dir", "?"]          self.parent.AllowGenerate(False)
679    
680      def GetNumGroups(self):      def GetNumGroups(self):
681          return self.list_use.GetItemCount()          return self.list_use.GetItemCount()
# Line 648  class GenUniquePanel(wxPanel): Line 716  class GenUniquePanel(wxPanel):
716          self.list_avail.DeleteAllItems()          self.list_avail.DeleteAllItems()
717          self.list_avail_data = []          self.list_avail_data = []
718    
719          list = self.layer.table.GetUniqueValues(self.fieldName)          list = self.layer.table.UniqueValues(self.fieldName)
720          index = 0          index = 0
721          for v in list:          for v in list:
722              self.dataList.append(v)              self.dataList.append(v)
# Line 703  class GenUniquePanel(wxPanel): Line 771  class GenUniquePanel(wxPanel):
771  #       list.SetColumnWidth(0, event.GetSize().GetWidth())  #       list.SetColumnWidth(0, event.GetSize().GetWidth())
772  #        #      
773    
774    ID_QUANTILES_RANGE = 4001
775    ID_QUANTILES_RETRIEVE = 4002
776    
777    class GenQuantilesPanel(wxPanel):
778    
779        def __init__(self, parent, layer, fieldName, fieldType):
780            wxPanel.__init__(self, parent, -1)
781    
782            self.parent = parent
783            self.layer = layer
784            self.fieldName = fieldName
785            self.fieldType = fieldType
786    
787            topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
788                                        wxVERTICAL)
789    
790            self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
791            self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
792                                            _("Retrieve from Table"))
793    
794            self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
795            self.spin_numClasses.SetRange(1, sys.maxint)
796            self.spin_numClasses.SetValue(1)
797    
798    
799            sizer = wxBoxSizer(wxHORIZONTAL)
800            sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
801            sizer.Add(self.text_range, 1, wxALL, 4)
802            sizer.Add(self.button_retrieve, 0, wxALL, 4)
803    
804            topBox.Add(sizer, 0, wxEXPAND, 0)
805    
806            sizer = wxBoxSizer(wxHORIZONTAL)
807            sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
808            sizer.Add(self.spin_numClasses, 1, wxALL, 4)
809    
810            topBox.Add(sizer, 0, wxEXPAND, 0)
811    
812            self.SetSizer(topBox)
813            self.SetAutoLayout(True)
814            topBox.Fit(self)
815            topBox.SetSizeHints(self)
816    
817            EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
818            EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
819    
820            self.__range = None
821    
822        def GetNumGroups(self):
823            return self.spin_numClasses.GetValue()
824    
825        def GetRange(self):
826            assert self.__range is not None
827    
828            return self.__range
829    
830        def GetList(self):
831    
832            _list = []
833    
834            if self.layer.table is not None:
835                wxBeginBusyCursor()
836    
837                #
838                # FIXME: Replace with a call to table when the method
839                # has been written to get all the values
840                #
841                table = self.layer.table
842                for i in range(table.NumRows()):
843                    _list.append(table.ReadValue(i, self.fieldName))
844    
845                wxEndBusyCursor()
846    
847            return _list
848    
849        def OnRangeText(self, event):
850    
851            try:
852                self.__range = Range(self.text_range.GetValue())
853            except ValueError:
854                self.__range = None
855    
856            if self.__range is not None:
857                self.text_range.SetForegroundColour(wxBLACK)
858            else:
859                self.text_range.SetForegroundColour(wxRED)
860    
861        def OnRetrieve(self, event):
862    
863            if self.layer.table is not None:
864                wxBeginBusyCursor()
865                min, max = self.layer.table.ValueRange(self.fieldName)
866                self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
867                wxEndBusyCursor()
868    
869  ID_CUSTOMRAMP_COPYSTART = 4001  ID_CUSTOMRAMP_COPYSTART = 4001
870  ID_CUSTOMRAMP_COPYEND = 4002  ID_CUSTOMRAMP_COPYEND = 4002
871  ID_CUSTOMRAMP_EDITSTART = 4003  ID_CUSTOMRAMP_EDITSTART = 4003
# Line 791  class CustomRampPanel(wxPanel): Line 954  class CustomRampPanel(wxPanel):
954      def _OnEditEnd(self, event):      def _OnEditEnd(self, event):
955          self.endPropCtrl.DoEdit()          self.endPropCtrl.DoEdit()
956    
957  class ClassGenerator:    
   
     def GenSingletonsFromList(self, list, numGroups, ramp):  
         """Generate a new classification consisting solely of singletons.  
   
         The resulting classification will consist of at most 'numGroups'  
         groups whose group properties ramp between 'prop1' and 'prop2'. There  
         could be fewer groups if 'list' contains fewer that 'numGroups' items.  
   
         list -- any object that implements the iterator interface  
   
         numGroups -- how many groups to generate. This can not be  
                      determined while the classification is being  
                      generated because the stepping values must  
                      be precalculated to ramp between prop1 and prop2.  
   
         prop1 -- initial group property values  
   
         prop2 -- final group property values  
         """  
   
         clazz = Classification()  
         if numGroups == 0: return clazz  
   
         ramp.SetNumGroups(numGroups)  
   
         for value, prop in zip(list, ramp):  
             clazz.AppendGroup(ClassGroupSingleton(value, prop))  
   
         return clazz  
   
     def GenSingletons(self, min, max, numGroups, ramp):  
   
         clazz = Classification()  
   
         #step = int((max - min) / float(numGroups))  
         step = int(Str2Num(str((max - min + 1) / float(numGroups))))  
   
         if numGroups > 0:  
             cur_value = min  
   
             ramp.SetNumGroups(numGroups)  
   
             for prop in ramp:  
                 clazz.AppendGroup(  
                     ClassGroupSingleton(  
                         Str2Num(str(cur_value)),  
                         prop))  
                 cur_value += step  
   
         return clazz  
   
     def GenUnifromDistribution(self, min, max, numGroups,  
                                ramp, intStep = False):  
         """Generate a classification with numGroups range groups  
         each with the same interval.  
   
         intStep -- force the calculated stepping to an integer.  
                    Useful if the values are integers but the  
                    number of groups specified doesn't evenly  
                    divide (max - min).  
         """  
   
         clazz = Classification()  
         if numGroups == 0: return clazz  
   
         ramp.SetNumGroups(numGroups)  
   
         step = Str2Num(str((max - min) / float(numGroups)))  
   
         if intStep:  
             step = int(step)  
   
         cur_min = min  
         cur_max = cur_min + step  
   
         i = 0  
         for prop in ramp:  
   
             if i == (numGroups - 1):  
                 cur_max = max  
   
             # this check guards against rounding issues  
             if cur_min != cur_max:  
                 clazz.AppendGroup(  
                     ClassGroupRange(  
                         Str2Num(str(cur_min)),  
                         Str2Num(str(cur_max)),  
                         prop))  
   
             cur_min = cur_max  
             cur_max += step  
             i += 1  
   
         return clazz  
   
 CLR  = 0  
 STEP = 1  
 class CustomRamp:  
   
     def __init__(self, prop1, prop2):  
         self.prop1 = prop1  
         self.prop2 = prop2  
   
         self.count = 0  
   
     def __iter__(self):  
         return self  
   
     def GetRamp(self):  
         return self  
   
     def SetNumGroups(self, num):  
   
         if num <= 0:  
             return False  
   
         self.count = int(num)  
         num = float(num)  
   
         prop1 = self.prop1  
         prop2 = self.prop2  
   
         clr = prop1.GetLineColor()  
         lineColor2 = prop2.GetLineColor()  
           
         self.noLine = clr is not Color.Transparent \  
                         and lineColor2 is not Color.Transparent  
   
   
         self.lineInfo = self.__GetColorInfo(prop1.GetLineColor(),  
                                             prop2.GetLineColor(),  
                                             num)  
   
         self.fillInfo = self.__GetColorInfo(prop1.GetFill(),  
                                             prop2.GetFill(),  
                                             num)  
   
         self.lineWidth = prop1.GetLineWidth()  
         self.lineWidthStep = (prop2.GetLineWidth() - self.lineWidth) / num  
   
         return True  
   
     def next(self):  
         if self.count == 0:  
             raise StopIteration  
   
         prop = ClassGroupProperties()  
   
         if self.lineInfo is None:  
             prop.SetLineColor(Color.Transparent)  
         else:  
             prop.SetLineColor(Color(self.lineInfo[CLR][0] / 255,  
                                     self.lineInfo[CLR][1] / 255,  
                                     self.lineInfo[CLR][2] / 255))  
   
             self.lineInfo[CLR][0] += self.lineInfo[STEP][0]  
             self.lineInfo[CLR][1] += self.lineInfo[STEP][1]  
             self.lineInfo[CLR][2] += self.lineInfo[STEP][2]  
   
         if self.fillInfo is None:  
             prop.SetFill(Color.Transparent)  
         else:  
             prop.SetFill(Color(self.fillInfo[CLR][0] / 255,  
                             self.fillInfo[CLR][1] / 255,  
                             self.fillInfo[CLR][2] / 255))  
   
             self.fillInfo[CLR][0] += self.fillInfo[STEP][0]  
             self.fillInfo[CLR][1] += self.fillInfo[STEP][1]  
             self.fillInfo[CLR][2] += self.fillInfo[STEP][2]  
   
   
         prop.SetLineWidth(int(self.lineWidth))  
         self.lineWidth        += self.lineWidthStep  
   
         self.count -= 1  
   
         return prop  
   
     def __GetColorInfo(self, color1, color2, numGroups):  
   
         if color1 is Color.Transparent and color2 is Color.Transparent:  
             #  
             # returning early  
             #  
             return None  
         elif color1 is not Color.Transparent and color2 is Color.Transparent:  
             color = [color1.red   * 255,  
                      color1.green * 255,  
                      color1.blue  * 255]  
             step = (0, 0, 0)  
         elif color1 is Color.Transparent and color2 is not Color.Transparent:  
             color = [color2.red   * 255,  
                      color2.green * 255,  
                      color2.blue  * 255]  
             step = (0, 0, 0)  
         else:  
             color = [color1.red   * 255,  
                      color1.green * 255,  
                      color1.blue  * 255]  
             step = ((color2.red   * 255 - color1.red   * 255)   / numGroups,  
                     (color2.green * 255 - color1.green * 255) / numGroups,  
                     (color2.blue  * 255 - color1.blue  * 255)  / numGroups)  
   
   
         return (color, step)  
   
 class MonochromaticRamp(CustomRamp):  
     def __init__(self, start, end):  
         sp = ClassGroupProperties()  
         sp.SetLineColor(start)  
         sp.SetFill(start)  
   
         ep = ClassGroupProperties()  
         ep.SetLineColor(end)  
         ep.SetFill(end)  
   
         CustomRamp.__init__(self, sp, ep)  
   
 class GreyRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, 0))  
   
 class RedRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(.8, 0, 0))  
   
 class GreenRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, .8, 0))  
   
 class BlueRamp(MonochromaticRamp):  
     def __init__(self):  
         MonochromaticRamp.__init__(self, Color(1, 1, 1), Color(0, 0, .8))  
   
 class HotToColdRamp:  
   
     def __iter__(self):  
         return self  
           
     def GetRamp(self):  
         return self  
   
     def SetNumGroups(self, num):  
         if num < 0:  
             return False  
   
         self.num = float(num)  
         self.index = 0  
   
         return True  
   
     def next(self):  
         if self.index == self.num:  
             raise StopIteration  
   
         clr = [1.0, 1.0, 1.0]  
   
         if self.index < (.25 * self.num):  
             clr[0] = 0  
             clr[1] = 4 * self.index / self.num  
         elif self.index < (.5 * self.num):  
             clr[0] = 0  
             clr[2] = 1 + 4 * (.25 * self.num - self.index) / self.num  
         elif self.index < (.75 * self.num):  
             clr[0] = 4 * (self.index - .5 * self.num) / self.num  
             clr[2] = 0  
         else:  
             clr[1] = 1 + 4 * (.75 * self.num - self.index) / self.num  
             clr[2] = 0  
   
         self.index += 1  
   
         prop = ClassGroupProperties()  
         prop.SetLineColor(Color(clr[0], clr[1], clr[2]))  
         prop.SetFill(Color(clr[0], clr[1], clr[2]))  
   
         return prop  
   
 #class Colors16Ramp:  
 #  
     #def __iter__(self):  
         #return self  
 #  
     #def GetRamp(self):  
         #return self  
 #  
     #def SetNumGroups(self, num):  
         #if num < 0:  
             #return False  
 #  
         #self.index = 0  
 #  
         #return True  
   
       

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26