/[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 898 by jonathan, Mon May 12 12:19:58 2003 UTC revision 2191 by jan, Thu Apr 22 15:45:01 2004 UTC
# Line 1  Line 1 
1  # Copyright (c) 2003 by Intevation GmbH  # Copyright (c) 2003, 2004 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4  #  #
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  """The Classification Generator Dialog"""
9    
10    __version__ = "$Revision$"
11    # $Source$
12    # $Id$
13    
14  from Thuban import _  
15    import sys
16    
17  from wxPython.wx import *  from wxPython.wx import *
18    
19  from Thuban.Model.classification import Classification, ClassGroupRange, \  from Thuban import _
20      ClassGroupSingleton, ClassGroupProperties  
21    from Thuban.Model.classification import ClassGroupProperties
22    
23  from Thuban.Model.table import Table, FIELDTYPE_INT, FIELDTYPE_DOUBLE, \  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
24       FIELDTYPE_STRING       FIELDTYPE_STRING
25    
26  from Thuban.Model.color import Color  from Thuban.Model.layer import SHAPETYPE_ARC
27  from Thuban.Model.range import Range  from Thuban.Model.range import Range
28    from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
29    
30  import classifier, resource  import classifier, resource
31    
32  from Thuban.Model.classgen import ClassGenerator, \  from Thuban.Model.classgen import \
33      CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \      generate_uniform_distribution, generate_singletons, generate_quantiles, \
34      HotToColdRamp      CustomRamp, grey_ramp, red_ramp, green_ramp, blue_ramp, green_to_red_ramp, \
35        HotToColdRamp, FixedRamp
36    
37    
38  USEALL_BMP  = "group_use_all"  USEALL_BMP  = "group_use_all"
39  USE_BMP     = "group_use"  USE_BMP     = "group_use"
# Line 46  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold Line 55  PROPCOMBOSTR_HOT2COLD   = _("Hot-to-Cold
55  ID_CLASSGEN_GENCOMBO = 4007  ID_CLASSGEN_GENCOMBO = 4007
56  ID_CLASSGEN_PROPCOMBO = 4008  ID_CLASSGEN_PROPCOMBO = 4008
57    
58    ID_BORDER_COLOR = 4009
59    ID_BORDER_COLOR_CHANGE = 4010
60    
61  class ClassGenDialog(wxDialog):  class ClassGenDialog(wxDialog):
62    
63      def __init__(self, parent, layer, fieldName):      def __init__(self, parent, layer, fieldName):
# Line 61  class ClassGenDialog(wxDialog): Line 73  class ClassGenDialog(wxDialog):
73          self.layer = layer          self.layer = layer
74          self.clazz = None          self.clazz = None
75    
76          col = layer.table.Column(fieldName)          col = layer.ShapeStore().Table().Column(fieldName)
77          self.type = col.type          self.type = col.type
78    
79          self.fieldName = fieldName          self.fieldName = fieldName
# Line 76  class ClassGenDialog(wxDialog): Line 88  class ClassGenDialog(wxDialog):
88          # panels they will call AllowGenerate() which uses genButton.          # panels they will call AllowGenerate() which uses genButton.
89          #          #
90          self.genButton = wxButton(self, wxID_OK, _("Generate"))          self.genButton = wxButton(self, wxID_OK, _("Generate"))
91            self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
92          self.genButton.SetDefault()          self.genButton.SetDefault()
93    
94          self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)          self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
95    
96          self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))          self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
# Line 89  class ClassGenDialog(wxDialog): Line 103  class ClassGenDialog(wxDialog):
103    
104          self.genChoice.SetSelection(0)          self.genChoice.SetSelection(0)
105    
106          self.propPanel = None          for i in range(self.genChoice.GetCount()):
107          custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())              clazz, obj = self.genChoice.GetClientData(i)
108    
109          self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)              if obj is None:
110          self.propCombo.Append(PROPCOMBOSTR_GREY,  GreyRamp())                  obj = clazz(self, self.layer, self.fieldName, self.fieldType)
111          self.propCombo.Append(PROPCOMBOSTR_RED,   RedRamp())                  obj.Hide()
112          self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())                  self.genChoice.SetClientData(i, [clazz, obj])
         self.propCombo.Append(PROPCOMBOSTR_BLUE,  BlueRamp())  
         self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())  
         self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())  
         self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)  
113    
         self.propCombo.SetSelection(0)  
114    
115          #############          #############
116    
# Line 127  class ClassGenDialog(wxDialog): Line 136  class ClassGenDialog(wxDialog):
136          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wxBoxSizer(wxHORIZONTAL)
137          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),          psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
138              0, wxALIGN_CENTER_VERTICAL, 0)              0, wxALIGN_CENTER_VERTICAL, 0)
139    
140            # Properties (Ramp) ComboBox
141            self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
142    
143            self.propPanel = None
144            custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
145    
146            self.propCombo.Append(PROPCOMBOSTR_GREY,  grey_ramp)
147            self.propCombo.Append(PROPCOMBOSTR_RED,   red_ramp)
148            self.propCombo.Append(PROPCOMBOSTR_GREEN, green_ramp)
149            self.propCombo.Append(PROPCOMBOSTR_BLUE,  blue_ramp)
150            self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, green_to_red_ramp)
151            self.propCombo.Append(PROPCOMBOSTR_HOT2COLD,  HotToColdRamp())
152            self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
153    
154            self.propCombo.SetSelection(0)
155    
156          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)          psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
157          sizer.Add(psizer, 0, wxALL | wxGROW, 4)          sizer.Add(psizer, 0, wxALL | wxGROW, 4)
158    
159            if layer.ShapeType() != SHAPETYPE_ARC:
160                psizer = wxBoxSizer(wxHORIZONTAL)
161                self.fix_border_check = wxCheckBox(self, -1, _("Fix Border Color"))
162                psizer.Add(self.fix_border_check, 0, wxALL | wxGROW, 4)
163                self.border_color = classifier.ClassGroupPropertiesCtrl(
164                    self, ID_BORDER_COLOR,
165                    ClassGroupProperties(), SHAPETYPE_ARC,
166                    style=wxSIMPLE_BORDER, size=(40, 20))
167                psizer.Add(self.border_color, 0, wxALL | wxGROW, 4)
168                psizer.Add(wxButton(self, ID_BORDER_COLOR_CHANGE, _("Change")),
169                        0, wxALL, 4)
170                sizer.Add(psizer, 0, wxALL | wxGROW, 4)
171                EVT_BUTTON(self, ID_BORDER_COLOR_CHANGE, self.OnBorderColorChange)
172            else:
173                self.border_color = None
174    
175          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)          sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
176          sizer.Show(custom_ramp_panel, False)          sizer.Show(custom_ramp_panel, False)
177    
178            # Finally place the main buttons
179          buttonSizer = wxBoxSizer(wxHORIZONTAL)          buttonSizer = wxBoxSizer(wxHORIZONTAL)
180          buttonSizer.Add(self.genButton, 0, wxALL, 4)          buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
181          buttonSizer.Add(60, 20, 0, wxALL, 4)          buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
182          buttonSizer.Add(wxButton(self, wxID_CANCEL, _("Close")),          sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
                         0, wxALL, 4)  
         sizer.Add(buttonSizer, 0,  
                   wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 4)  
183    
184          self.SetSizer(sizer)          self.SetSizer(sizer)
185          self.SetAutoLayout(True)          self.SetAutoLayout(True)
# Line 190  class ClassGenDialog(wxDialog): Line 230  class ClassGenDialog(wxDialog):
230              propPanel = self.propCombo.GetClientData(index)              propPanel = self.propCombo.GetClientData(index)
231    
232              ramp = propPanel.GetRamp()              ramp = propPanel.GetRamp()
233                if self.border_color and self.fix_border_check.IsChecked():
234                    props = self.border_color.GetProperties()
235                    ramp = FixedRamp(ramp,
236                        (props.GetLineColor(), props.GetLineWidth(), None))
237    
238              if genSel == GENCOMBOSTR_UNIFORM:              if genSel == GENCOMBOSTR_UNIFORM:
239    
# Line 200  class ClassGenDialog(wxDialog): Line 244  class ClassGenDialog(wxDialog):
244                      and max is not None \                      and max is not None \
245                      and numGroups is not None:                      and numGroups is not None:
246    
247                      self.clazz = ClassGenerator().GenUnifromDistribution(                      self.clazz = generate_uniform_distribution(
248                                  min, max, numGroups, ramp,                                  min, max, numGroups, ramp,
249                                  self.type == FIELDTYPE_INT)                                  self.type == FIELDTYPE_INT)
250    
# Line 210  class ClassGenDialog(wxDialog): Line 254  class ClassGenDialog(wxDialog):
254    
255                  list = genPanel.GetValueList()                  list = genPanel.GetValueList()
256    
257                  if len(list) > 0 \                  if len(list) > 0:
258                      and numGroups is not None:                      self.clazz = generate_singletons(list, ramp)
   
                     self.clazz = ClassGenerator().GenSingletonsFromList(  
                                     list, numGroups, ramp)  
   
259                      self.parent._SetClassification(self.clazz)                      self.parent._SetClassification(self.clazz)
260    
261              elif genSel == GENCOMBOSTR_QUANTILES:              elif genSel == GENCOMBOSTR_QUANTILES:
# Line 227  class ClassGenDialog(wxDialog): Line 267  class ClassGenDialog(wxDialog):
267                  delta = 1 / float(numGroups)                  delta = 1 / float(numGroups)
268                  percents = [delta * i for i in range(1, numGroups + 1)]                  percents = [delta * i for i in range(1, numGroups + 1)]
269                  adjusted, self.clazz = \                  adjusted, self.clazz = \
270                      ClassGenerator().GenQuantiles(_list, percents, ramp, _range)                      generate_quantiles(_list, percents, ramp, _range)
271    
272                  if adjusted:                  if adjusted:
273                      dlg = wxMessageDialog(self,                      dlg = wxMessageDialog(self,
274                          _("Based on the data from the table and the input\n" +                          _("Based on the data from the table and the input\n"
275                            "values, the exact quantiles could not be generated.\n\n" +                       "values, the exact quantiles could not be generated.\n\n"
276                            "Accept a close estimate?"),                            "Accept a close estimate?"),
277                          _("Problem with Quantiles"),                          _("Problem with Quantiles"),
278    
# Line 245  class ClassGenDialog(wxDialog): Line 285  class ClassGenDialog(wxDialog):
285      def OnCancel(self, event):      def OnCancel(self, event):
286          self.Close()          self.Close()
287    
288        def OnBorderColorChange(self, event):
289            self.border_color.DoEdit()
290    
291      def _OnGenTypeSelect(self, event):      def _OnGenTypeSelect(self, event):
292          self.__DoOnGenTypeSelect()          self.__DoOnGenTypeSelect()
293          return          return
# Line 288  class ClassGenDialog(wxDialog): Line 331  class ClassGenDialog(wxDialog):
331    
332          clazz, obj = choice.GetClientData(sel)          clazz, obj = choice.GetClientData(sel)
333    
         if obj is None:  
             obj = clazz(self, self.layer, self.fieldName, self.fieldType)  
             choice.SetClientData(sel, [clazz, obj])  
   
334          if self.curGenPanel is not None:          if self.curGenPanel is not None:
335              self.curGenPanel.Hide()              self.curGenPanel.Hide()
336              self.sizer_genPanel.Remove(self.curGenPanel)              self.sizer_genPanel.Remove(self.curGenPanel)
# Line 497  class GenUniformPanel(wxPanel): Line 536  class GenUniformPanel(wxPanel):
536              self.parent.AllowGenerate(False)              self.parent.AllowGenerate(False)
537    
538      def _OnRetrieve(self, event):      def _OnRetrieve(self, event):
539            table = self.layer.ShapeStore().Table()
540          if self.layer.table is not None:          if table is not None:
541              wxBeginBusyCursor()              ThubanBeginBusyCursor()
542              min, max = self.layer.table.ValueRange(self.fieldName)              try:
543              self.minCtrl.SetValue(str(min))                  min, max = table.ValueRange(self.fieldName)
544              self.maxCtrl.SetValue(str(max))                  self.minCtrl.SetValue(str(min))
545              wxEndBusyCursor()                  self.maxCtrl.SetValue(str(max))
546                finally:
547                    ThubanEndBusyCursor()
548    
549      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):      def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
550    
# Line 545  class GenUniformPanel(wxPanel): Line 586  class GenUniformPanel(wxPanel):
586          return valid          return valid
587    
588      def __CalcStepping(self, min, max, ngroups):      def __CalcStepping(self, min, max, ngroups):
         step = (max - min) / float(ngroups)  
589          if self.fieldType == FIELDTYPE_INT:          if self.fieldType == FIELDTYPE_INT:
590              step = int(step)              step = int((max - min + 1) / float(ngroups))
591            else:
592                step = (max - min) / float(ngroups)
593    
594          return step          return step
595    
# Line 602  class GenUniquePanel(wxPanel): Line 644  class GenUniquePanel(wxPanel):
644          psizer = wxBoxSizer(wxVERTICAL)          psizer = wxBoxSizer(wxVERTICAL)
645          self.list_avail = wxListCtrl(self, -1,          self.list_avail = wxListCtrl(self, -1,
646                          style=wxLC_REPORT | wxLC_SINGLE_SEL)                          style=wxLC_REPORT | wxLC_SINGLE_SEL)
647          self.list_avail.InsertColumn(0, "Available")          self.list_avail.InsertColumn(0, _("Available"))
648          self.list_avail_data = []          self.list_avail_data = []
649          psizer.Add(self.list_avail, 1, wxGROW, 0)          psizer.Add(self.list_avail, 1, wxGROW, 0)
650    
# Line 642  class GenUniquePanel(wxPanel): Line 684  class GenUniquePanel(wxPanel):
684          psizer = wxBoxSizer(wxVERTICAL)          psizer = wxBoxSizer(wxVERTICAL)
685          self.list_use = wxListCtrl(self, -1,          self.list_use = wxListCtrl(self, -1,
686                          style=wxLC_REPORT | wxLC_SINGLE_SEL)                          style=wxLC_REPORT | wxLC_SINGLE_SEL)
687          self.list_use.InsertColumn(0, "Use")          self.list_use.InsertColumn(0, _("Use"))
688          self.list_use_data = []          self.list_use_data = []
689          psizer.Add(self.list_use, 1, wxGROW, 0)          psizer.Add(self.list_use, 1, wxGROW, 0)
690    
# Line 664  class GenUniquePanel(wxPanel): Line 706  class GenUniquePanel(wxPanel):
706          self.SetAutoLayout(True)          self.SetAutoLayout(True)
707          topSizer.SetSizeHints(self)          topSizer.SetSizeHints(self)
708    
709            width, height = self.list_avail.GetSizeTuple()
710            self.list_avail.SetColumnWidth(0,width)
711            width, height = self.list_use.GetSizeTuple()
712            self.list_use.SetColumnWidth(0,width)
713    
714          self.parent.AllowGenerate(False)          self.parent.AllowGenerate(False)
715    
716      def GetNumGroups(self):      def GetNumGroups(self):
# Line 705  class GenUniquePanel(wxPanel): Line 752  class GenUniquePanel(wxPanel):
752          self.list_avail.DeleteAllItems()          self.list_avail.DeleteAllItems()
753          self.list_avail_data = []          self.list_avail_data = []
754    
755          list = self.layer.table.UniqueValues(self.fieldName)          ThubanBeginBusyCursor()
756          index = 0          try:
757          for v in list:              list = self.layer.ShapeStore().Table().UniqueValues(self.fieldName)
758              self.dataList.append(v)              index = 0
759              i = self.list_avail.InsertStringItem(index, str(v))              for v in list:
760              self.list_avail.SetItemData(index, i)                  self.dataList.append(v)
761                    i = self.list_avail.InsertStringItem(index, str(v))
762              self.list_avail_data.append(v)                  self.list_avail.SetItemData(index, i)
763              index += 1      
764                    self.list_avail_data.append(v)
765                    index += 1
766            finally:
767                ThubanEndBusyCursor()
768    
769      def _OnUseAll(self, event):      def _OnUseAll(self, event):
770          for i in range(self.list_avail.GetItemCount()):          for i in range(self.list_avail.GetItemCount()):
# Line 817  class GenQuantilesPanel(wxPanel): Line 868  class GenQuantilesPanel(wxPanel):
868          return self.__range          return self.__range
869    
870      def GetList(self):      def GetList(self):
   
871          _list = []          _list = []
872            table = self.layer.ShapeStore().Table()
873          if self.layer.table is not None:          if table is not None:
874              wxBeginBusyCursor()              ThubanBeginBusyCursor()
875                try:
876              #                  #
877              # FIXME: Replace with a call to table when the method                  # FIXME: Replace with a call to table when the method
878              # has been written to get all the values                  # has been written to get all the values
879              #                  #
880              table = self.layer.table                  for i in range(table.NumRows()):
881              for i in range(table.NumRows()):                      _list.append(table.ReadValue(i, self.fieldName,
882                  _list.append(table.ReadValue(i, self.fieldName))                                                   row_is_ordinal = True))
883                finally:
884              wxEndBusyCursor()                  ThubanEndBusyCursor()
885    
886          return _list          return _list
887    
# Line 848  class GenQuantilesPanel(wxPanel): Line 898  class GenQuantilesPanel(wxPanel):
898              self.text_range.SetForegroundColour(wxRED)              self.text_range.SetForegroundColour(wxRED)
899    
900      def OnRetrieve(self, event):      def OnRetrieve(self, event):
901            table = self.layer.ShapeStore().Table()
902          if self.layer.table is not None:          if table is not None:
903              wxBeginBusyCursor()              ThubanBeginBusyCursor()
904              min, max = self.layer.table.ValueRange(self.fieldName)              try:
905              self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")                  min, max = table.ValueRange(self.fieldName)
906              wxEndBusyCursor()                  self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
907                finally:
908                    ThubanEndBusyCursor()
909    
910  ID_CUSTOMRAMP_COPYSTART = 4001  ID_CUSTOMRAMP_COPYSTART = 4001
911  ID_CUSTOMRAMP_COPYEND = 4002  ID_CUSTOMRAMP_COPYEND = 4002

Legend:
Removed from v.898  
changed lines
  Added in v.2191

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26