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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1163 - (hide annotations)
Thu Jun 12 12:41:31 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 30743 byte(s)
Use renamed projection resource functions.
(GenUniformPanel.__CalcStepping): Fix a slight discrepency
        when using integers versus floats.

1 jonathan 607 # Copyright (c) 2003 by Intevation GmbH
2     # Authors:
3     # Jonathan Coles <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8 jonathan 677 import sys
9    
10 jonathan 607 from Thuban import _
11    
12     from wxPython.wx import *
13    
14 bh 907 from Thuban.Model.classification import ClassGroupProperties
15 jonathan 607
16 bh 907 from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
17 jonathan 607 FIELDTYPE_STRING
18    
19 jonathan 877 from Thuban.Model.range import Range
20 jonathan 607
21 jonathan 877 import classifier, resource
22 jonathan 629
23 jonathan 1100 from Thuban.Model.classgen import \
24 jonathan 1163 generate_uniform_distribution, generate_singletons, generate_quantiles, \
25 jonathan 877 CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
26     HotToColdRamp
27 jonathan 649
28     USEALL_BMP = "group_use_all"
29     USE_BMP = "group_use"
30     USENOT_BMP = "group_use_not"
31     USENONE_BMP = "group_use_none"
32    
33 jonathan 635 GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
34     GENCOMBOSTR_UNIQUE = _("Unique Values")
35 jonathan 877 GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
36 jonathan 629
37 jonathan 649 PROPCOMBOSTR_CUSTOM = _("Custom Ramp")
38     PROPCOMBOSTR_GREY = _("Grey Ramp")
39     PROPCOMBOSTR_RED = _("Red Ramp")
40     PROPCOMBOSTR_GREEN = _("Green Ramp")
41     PROPCOMBOSTR_BLUE = _("Blue Ramp")
42 jonathan 877 PROPCOMBOSTR_GREEN2RED = _("Green-to-Red Ramp")
43 jonathan 649 PROPCOMBOSTR_HOT2COLD = _("Hot-to-Cold Ramp")
44 jonathan 635
45 jonathan 877 ID_CLASSGEN_GENCOMBO = 4007
46     ID_CLASSGEN_PROPCOMBO = 4008
47    
48 jonathan 607 class ClassGenDialog(wxDialog):
49 bh 834
50 jonathan 629 def __init__(self, parent, layer, fieldName):
51     """Inialize the class generating dialog.
52    
53     parent -- this must be an instance of the Classifier class
54     """
55    
56 jonathan 607 wxDialog.__init__(self, parent, -1, _("Generate Classification"),
57     style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
58 bh 834
59 jonathan 629 self.parent = parent
60 jonathan 877 self.layer = layer
61 jonathan 607 self.clazz = None
62    
63 bh 834 col = layer.table.Column(fieldName)
64     self.type = col.type
65 jonathan 607
66 jonathan 877 self.fieldName = fieldName
67     self.fieldType = self.type
68    
69     self.curGenPanel = None
70    
71     self.genpanels = []
72    
73 jonathan 629 #############
74     # we need to create genButton first because when we create the
75     # panels they will call AllowGenerate() which uses genButton.
76     #
77 jonathan 812 self.genButton = wxButton(self, wxID_OK, _("Generate"))
78     self.genButton.SetDefault()
79 frank 978 self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
80    
81 jonathan 812 self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
82 jonathan 607
83 jonathan 877 self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
84     if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
85     self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
86     self.genpanels.append((GENCOMBOSTR_QUANTILES, GenQuantilesPanel))
87 jonathan 812
88 jonathan 877 for name, clazz in self.genpanels:
89     self.genChoice.Append(name, [clazz, None])
90 jonathan 812
91     self.genChoice.SetSelection(0)
92    
93 frank 978 for i in range(self.genChoice.GetCount()):
94     clazz, obj = self.genChoice.GetClientData(i)
95 jonathan 812
96 frank 978 if obj is None:
97     obj = clazz(self, self.layer, self.fieldName, self.fieldType)
98     obj.Hide()
99     self.genChoice.SetClientData(i, [clazz, obj])
100 jonathan 812
101    
102 jonathan 629 #############
103 jonathan 607
104 jonathan 629 sizer = wxBoxSizer(wxVERTICAL)
105    
106     sizer.Add(wxStaticText(self, -1, _("Field: %s") % fieldName),
107     0, wxALL, 4)
108     sizer.Add(wxStaticText(
109     self, -1,
110 jonathan 649 _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
111 jonathan 629 0, wxALL, 4)
112    
113     psizer = wxBoxSizer(wxHORIZONTAL)
114 jonathan 635 psizer.Add(wxStaticText(self, -1, _("Generate:")),
115 jonathan 629 0, wxALIGN_CENTER_VERTICAL, 0)
116 jonathan 728 psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
117 jonathan 629
118     sizer.Add(psizer, 0, wxALL | wxGROW, 4)
119    
120 jonathan 877 self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
121     sizer.Add(self.sizer_genPanel, 1, wxGROW | wxALL, 4)
122 jonathan 629
123 jonathan 635 psizer = wxBoxSizer(wxHORIZONTAL)
124 jonathan 660 psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
125 jonathan 635 0, wxALIGN_CENTER_VERTICAL, 0)
126 frank 978
127     # Properties (Ramp) ComboBox
128     self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
129    
130     self.propPanel = None
131     custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
132    
133     self.propCombo.Append(PROPCOMBOSTR_GREY, GreyRamp())
134     self.propCombo.Append(PROPCOMBOSTR_RED, RedRamp())
135     self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
136     self.propCombo.Append(PROPCOMBOSTR_BLUE, BlueRamp())
137     self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())
138     self.propCombo.Append(PROPCOMBOSTR_HOT2COLD, HotToColdRamp())
139     self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
140    
141     self.propCombo.SetSelection(0)
142    
143 jonathan 635 psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
144     sizer.Add(psizer, 0, wxALL | wxGROW, 4)
145 jonathan 629
146 jonathan 812 sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
147     sizer.Show(custom_ramp_panel, False)
148 jonathan 629
149 frank 978 # Finally place the main buttons
150 jonathan 812 buttonSizer = wxBoxSizer(wxHORIZONTAL)
151 frank 978 buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
152     buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
153     sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
154 jonathan 607
155     self.SetSizer(sizer)
156     self.SetAutoLayout(True)
157     sizer.SetSizeHints(self)
158    
159 jonathan 877 self.topBox = sizer
160 jonathan 629
161 jonathan 877 self.__DoOnGenTypeSelect()
162    
163 jonathan 812 EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
164     EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
165     EVT_BUTTON(self, wxID_OK, self.OnOK)
166     EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
167 jonathan 607
168 jonathan 877 self.__DoOnGenTypeSelect()
169 jonathan 812
170     self.genChoice.SetFocus()
171    
172 jonathan 607 def GetClassification(self):
173     return self.clazz
174    
175     def AllowGenerate(self, on):
176 jonathan 629 pass #self.genButton.Enable(on)
177 jonathan 607
178 jonathan 812 def OnOK(self, event):
179     """This is really the generate button, but we want to override
180     the wxDialog class.
181     """
182 jonathan 607
183 jonathan 728 index = self.genChoice.GetSelection()
184 jonathan 607
185 jonathan 877 assert index != -1, "button should be disabled!"
186    
187 jonathan 728 genSel = self.genChoice.GetString(index)
188 jonathan 877 clazz, genPanel = self.genChoice.GetClientData(index)
189 jonathan 635
190 jonathan 629 propPanel = self.propPanel
191 jonathan 607
192 jonathan 877 if genSel in (GENCOMBOSTR_UNIFORM, \
193     GENCOMBOSTR_UNIQUE, \
194     GENCOMBOSTR_QUANTILES):
195    
196 jonathan 629 numGroups = genPanel.GetNumGroups()
197 jonathan 607
198 jonathan 635 index = self.propCombo.GetSelection()
199 jonathan 629
200 jonathan 635 propSel = self.propCombo.GetString(index)
201     propPanel = self.propCombo.GetClientData(index)
202 jonathan 629
203 jonathan 635 ramp = propPanel.GetRamp()
204 jonathan 629
205 jonathan 635 if genSel == GENCOMBOSTR_UNIFORM:
206 jonathan 629
207 jonathan 635 min = genPanel.GetMin()
208     max = genPanel.GetMax()
209 jonathan 629
210 jonathan 635 if min is not None \
211     and max is not None \
212     and numGroups is not None:
213 jonathan 629
214 jonathan 1163 self.clazz = generate_uniform_distribution(
215 jonathan 635 min, max, numGroups, ramp,
216     self.type == FIELDTYPE_INT)
217 jonathan 629
218 jonathan 635 self.parent._SetClassification(self.clazz)
219 jonathan 629
220 jonathan 635 elif genSel == GENCOMBOSTR_UNIQUE:
221 jonathan 629
222 jonathan 635 list = genPanel.GetValueList()
223    
224     if len(list) > 0 \
225     and numGroups is not None:
226    
227 jonathan 1163 self.clazz = generate_singletons(
228 jonathan 635 list, numGroups, ramp)
229    
230     self.parent._SetClassification(self.clazz)
231    
232 jonathan 877 elif genSel == GENCOMBOSTR_QUANTILES:
233    
234     _range = genPanel.GetRange()
235     _list = genPanel.GetList()
236     _list.sort()
237    
238     delta = 1 / float(numGroups)
239     percents = [delta * i for i in range(1, numGroups + 1)]
240     adjusted, self.clazz = \
241 jonathan 1163 generate_quantiles(_list, percents, ramp, _range)
242 jonathan 877
243     if adjusted:
244     dlg = wxMessageDialog(self,
245     _("Based on the data from the table and the input\n" +
246     "values, the exact quantiles could not be generated.\n\n" +
247     "Accept a close estimate?"),
248     _("Problem with Quantiles"),
249    
250     wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
251     if dlg.ShowModal() == wxID_YES:
252     self.parent._SetClassification(self.clazz)
253     else:
254     self.parent._SetClassification(self.clazz)
255    
256 jonathan 812 def OnCancel(self, event):
257 jonathan 629 self.Close()
258    
259     def _OnGenTypeSelect(self, event):
260 jonathan 877 self.__DoOnGenTypeSelect()
261     return
262 jonathan 629
263     combo = event.GetEventObject()
264    
265     selIndex = combo.GetSelection()
266    
267     if self.genPanel is not None:
268 jonathan 877 self.topBox.Show(self.genPanel, False)
269 jonathan 629
270     self.genPanel = combo.GetClientData(selIndex)
271     if self.genPanel is not None:
272 jonathan 877 self.topBox.Show(self.genPanel, True)
273 jonathan 629
274 jonathan 877 self.topBox.SetSizeHints(self)
275     self.topBox.Layout()
276 jonathan 629
277 jonathan 635 def _OnPropTypeSelect(self, event):
278     combo = event.GetEventObject()
279 jonathan 629
280 jonathan 635 selIndex = combo.GetSelection()
281     sel = combo.GetString(selIndex)
282    
283     if isinstance(self.propPanel, wxPanel):
284 jonathan 877 self.topBox.Show(self.propPanel, False)
285 jonathan 635
286     self.propPanel = combo.GetClientData(selIndex)
287    
288     if isinstance(self.propPanel, wxPanel):
289 jonathan 877 self.topBox.Show(self.propPanel, True)
290 jonathan 635
291 jonathan 877 self.topBox.SetSizeHints(self)
292     self.topBox.Layout()
293 jonathan 635
294 jonathan 877 def __DoOnGenTypeSelect(self):
295     choice = self.genChoice
296 jonathan 635
297 jonathan 877 sel = choice.GetSelection()
298     if sel == -1: return
299    
300     clazz, obj = choice.GetClientData(sel)
301    
302     if self.curGenPanel is not None:
303     self.curGenPanel.Hide()
304     self.sizer_genPanel.Remove(self.curGenPanel)
305    
306     self.curGenPanel = obj
307     self.curGenPanel.Show()
308    
309     self.sizer_genPanel.Add(self.curGenPanel, 1,
310     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
311     self.sizer_genPanel.Layout()
312     self.Layout()
313     self.topBox.SetSizeHints(self)
314    
315 jonathan 629 ID_UNIFORM_MIN = 4001
316     ID_UNIFORM_MAX = 4002
317     ID_UNIFORM_NGROUPS = 4003
318     ID_UNIFORM_STEP = 4004
319     ID_UNIFORM_RETRIEVE = 4005
320    
321     class GenUniformPanel(wxPanel):
322    
323     def __init__(self, parent, layer, fieldName, fieldType):
324 jonathan 607 wxPanel.__init__(self, parent, -1)
325    
326     self.parent = parent
327 jonathan 629 self.layer = layer
328     self.fieldName = fieldName
329 jonathan 607 self.fieldType = fieldType
330    
331 jonathan 629 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
332 jonathan 607 wxVERTICAL)
333    
334 jonathan 629 #############
335    
336 jonathan 607 sizer = wxBoxSizer(wxHORIZONTAL)
337    
338     sizer.Add(wxStaticText(self, -1, _("Min:")), 0, wxALL, 4)
339 jonathan 629 self.minCtrl = wxTextCtrl(self, ID_UNIFORM_MIN, style=wxTE_RIGHT)
340     sizer.Add(self.minCtrl, 1, wxALL, 4)
341     EVT_TEXT(self, ID_UNIFORM_MIN, self._OnRangeChanged)
342 jonathan 607
343     sizer.Add(wxStaticText(self, -1, _("Max:")), 0, wxALL, 4)
344 jonathan 629 self.maxCtrl = wxTextCtrl(self, ID_UNIFORM_MAX, style=wxTE_RIGHT)
345     sizer.Add(self.maxCtrl, 1, wxALL, 4)
346     EVT_TEXT(self, ID_UNIFORM_MAX, self._OnRangeChanged)
347 jonathan 607
348 jonathan 629 sizer.Add(wxButton(self, ID_UNIFORM_RETRIEVE, _("Retrieve From Table")),
349     0, wxALL, 4)
350     EVT_BUTTON(self, ID_UNIFORM_RETRIEVE, self._OnRetrieve)
351    
352     topSizer.Add(sizer, 1, wxGROW, 0)
353    
354     #############
355    
356 jonathan 607 sizer = wxBoxSizer(wxHORIZONTAL)
357 jonathan 629
358 jonathan 607 sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
359 jonathan 660 self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
360     style=wxTE_RIGHT)
361 jonathan 629 EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
362     EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
363     sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
364 jonathan 607
365     sizer.Add(wxStaticText(self, -1, _("Stepping:")), 0, wxALL, 4)
366 jonathan 629 self.stepCtrl = wxTextCtrl(self, ID_UNIFORM_STEP, style=wxTE_RIGHT)
367     EVT_TEXT(self, ID_UNIFORM_STEP, self._OnSteppingChanged)
368     sizer.Add(self.stepCtrl , 1, wxALL, 4)
369 jonathan 607
370 jonathan 629 topSizer.Add(sizer, 1, wxGROW, 0)
371    
372     #############
373    
374 jonathan 607 self.SetSizer(topSizer)
375     self.SetAutoLayout(True)
376     topSizer.SetSizeHints(self)
377    
378     self.numGroupsChanging = False
379     self.steppingChanging = False
380    
381 jonathan 677 self.numGroupsCtrl.SetRange(1, sys.maxint)
382 jonathan 607
383     self.numGroupsCtrl.SetValue(1)
384     self.stepCtrl.SetValue("1")
385     self.maxCtrl.SetValue("0")
386     self.minCtrl.SetValue("0")
387     self.minCtrl.SetFocus()
388    
389     def GetNumGroups(self):
390     value = self.numGroupsCtrl.GetValue()
391     return self.__GetValidatedTypeEntry(self.numGroupsCtrl,
392     value,
393     FIELDTYPE_INT,
394     None)
395    
396     def GetStepping(self):
397     step = self.stepCtrl.GetValue()
398     return self.__GetValidatedTypeEntry(self.stepCtrl,
399     step,
400     self.fieldType,
401     0)
402    
403     def GetMin(self):
404     min = self.minCtrl.GetValue()
405     max = self.maxCtrl.GetValue()
406     return self.__GetValidatedTypeEntry(self.minCtrl,
407     min,
408     self.fieldType,
409     max)
410    
411     def GetMax(self):
412     min = self.minCtrl.GetValue()
413     max = self.maxCtrl.GetValue()
414     return self.__GetValidatedTypeEntry(self.maxCtrl,
415     max,
416     self.fieldType,
417     min)
418    
419     def _OnRangeChanged(self, event):
420    
421     hasFocus = wxWindow_FindFocus() == event.GetEventObject()
422     min = self.GetMin()
423     max = self.GetMax()
424    
425     on = min is not None \
426     and max is not None
427    
428     self.numGroupsCtrl.Enable(on)
429     self.stepCtrl.Enable(on)
430    
431     ngroups = self.GetNumGroups()
432    
433     if ngroups is not None \
434     and min is not None \
435     and max is not None \
436     and ngroups != 0:
437    
438 jonathan 629 #self.stepCtrl.SetValue(str((max - min) / ngroups))
439     self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
440     #self.numGroupsCtrl.SetValue(ngroups)
441 jonathan 607
442     self.parent.AllowGenerate(self.GetStepping() is not None)
443     else:
444     self.parent.AllowGenerate(False)
445    
446    
447     if hasFocus:
448     event.GetEventObject().SetFocus()
449    
450     def _OnNumGroupsChanged(self, event):
451     if self.steppingChanging:
452     self.steppingChanging = False
453     return
454    
455    
456     obj = event.GetEventObject()
457     ngroups = self.GetNumGroups()
458     min = self.GetMin()
459     max = self.GetMax()
460    
461     if ngroups is not None \
462     and min is not None \
463     and max is not None \
464     and ngroups != 0:
465    
466     #
467     # changing the value in the stepCtrl sends an event
468     # that the control is changing, at which point
469     # we try to update the numGroupsCtrl. This causes
470     # an infinite recursion. This flag and the one
471     # called steppingChanging tries to prevent the recursion.
472     #
473     self.numGroupsChanging = True
474    
475 jonathan 629 self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
476    
477 jonathan 607 self.parent.AllowGenerate(self.GetStepping() is not None)
478     else:
479     self.parent.AllowGenerate(False)
480    
481    
482     def _OnSteppingChanged(self, event):
483     if self.numGroupsChanging:
484     self.numGroupsChanging = False
485     return
486    
487     step = self.GetStepping()
488     min = self.GetMin()
489     max = self.GetMax()
490    
491     if step is not None \
492     and min is not None \
493     and max is not None \
494     and step != 0:
495    
496     #
497     # see note in _OnNumGroupsChanged
498     #
499     self.steppingChanging = True
500 jonathan 629 self.numGroupsCtrl.SetValue(self.__CalcNumGroups(min, max, step))
501 jonathan 607
502     self.parent.AllowGenerate(self.GetNumGroups() is not None)
503     else:
504     self.parent.AllowGenerate(False)
505    
506 jonathan 629 def _OnRetrieve(self, event):
507    
508     if self.layer.table is not None:
509 jonathan 812 wxBeginBusyCursor()
510 jonathan 1100 try:
511     min, max = self.layer.table.ValueRange(self.fieldName)
512     self.minCtrl.SetValue(str(min))
513     self.maxCtrl.SetValue(str(max))
514     finally:
515     wxEndBusyCursor()
516 jonathan 629
517 jonathan 607 def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
518    
519     if type == FIELDTYPE_INT:
520     func = int
521     elif type == FIELDTYPE_DOUBLE:
522     func = float
523     elif type == FIELDTYPE_STRING:
524     func = str
525     else:
526     assert False, "Unsupported FIELDTYPE"
527     pass
528    
529     if self.__ValidateEntry(win, value, func, badValue):
530     return func(value)
531    
532     return None
533    
534     def __ValidateEntry(self, win, value, test, badValue = None):
535    
536     valid = value != ""
537    
538     try:
539     if valid:
540     value = test(value)
541    
542     if badValue is not None:
543     valid = value != test(badValue)
544     except ValueError:
545     valid = False
546    
547     if valid:
548     win.SetForegroundColour(wxBLACK)
549     else:
550     win.SetForegroundColour(wxRED)
551    
552 jonathan 620 win.Refresh()
553    
554 jonathan 607 return valid
555 jonathan 629
556     def __CalcStepping(self, min, max, ngroups):
557     if self.fieldType == FIELDTYPE_INT:
558 jonathan 1163 step = int((max - min + 1) / float(ngroups))
559     else:
560     step = (max - min) / float(ngroups)
561 jonathan 629
562     return step
563    
564     def __CalcNumGroups(self, min, max, step):
565     n = int((max - min) / step)
566     if n == 0:
567     n = 1
568    
569     if self.fieldType == FIELDTYPE_INT and step == 1:
570     n += 1
571    
572     return n
573    
574    
575     ID_UNIQUE_RETRIEVE = 4001
576     ID_UNIQUE_USEALL = 4002
577     ID_UNIQUE_USE = 4003
578     ID_UNIQUE_DONTUSE = 4004
579     ID_UNIQUE_USENONE = 4005
580     ID_UNIQUE_SORTAVAIL = 4006
581     ID_UNIQUE_SORTUSE = 4007
582 jonathan 649 ID_UNIQUE_REVAVAIL = 4008
583     ID_UNIQUE_REVUSE = 4009
584 jonathan 629
585     class GenUniquePanel(wxPanel):
586    
587     def __init__(self, parent, layer, fieldName, fieldType):
588     wxPanel.__init__(self, parent, -1)
589    
590     self.parent = parent
591     self.layer = layer
592     self.fieldName = fieldName
593     self.fieldType = fieldType
594    
595     topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
596     wxVERTICAL)
597    
598    
599 jonathan 649 #bsizer = wxBoxSizer(wxVERTICAL)
600     topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
601     _("Retrieve From Table")),
602     0, wxALL | wxALIGN_RIGHT, 4)
603    
604     EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
605    
606     #topSizer.Add(bsizer, 0, wxALL, 4)
607    
608 jonathan 629 sizer = wxBoxSizer(wxHORIZONTAL)
609    
610     self.dataList = []
611    
612     psizer = wxBoxSizer(wxVERTICAL)
613     self.list_avail = wxListCtrl(self, -1,
614     style=wxLC_REPORT | wxLC_SINGLE_SEL)
615     self.list_avail.InsertColumn(0, "Available")
616     self.list_avail_data = []
617     psizer.Add(self.list_avail, 1, wxGROW, 0)
618    
619 jonathan 649 bsizer = wxBoxSizer(wxHORIZONTAL)
620     bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
621     EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
622 jonathan 629
623 jonathan 649 bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
624     EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
625 jonathan 629
626 jonathan 649 psizer.Add(bsizer, 0, wxGROW, 0)
627 jonathan 629 sizer.Add(psizer, 1, wxGROW, 0)
628    
629 jonathan 607
630 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
631 jonathan 649
632     bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
633     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
634 jonathan 629 0, wxGROW | wxALL, 4)
635 jonathan 649 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
636     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
637 jonathan 629 0, wxGROW | wxALL, 4)
638 jonathan 649 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
639     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
640 jonathan 629 0, wxGROW | wxALL, 4)
641 jonathan 649 bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
642     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
643 jonathan 629 0, wxGROW | wxALL, 4)
644 jonathan 607
645 jonathan 629 EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
646     EVT_BUTTON(self, ID_UNIQUE_USE, self._OnUse)
647     EVT_BUTTON(self, ID_UNIQUE_DONTUSE, self._OnDontUse)
648     EVT_BUTTON(self, ID_UNIQUE_USENONE, self._OnUseNone)
649 jonathan 607
650 jonathan 629 sizer.Add(bsizer, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
651    
652     psizer = wxBoxSizer(wxVERTICAL)
653     self.list_use = wxListCtrl(self, -1,
654     style=wxLC_REPORT | wxLC_SINGLE_SEL)
655     self.list_use.InsertColumn(0, "Use")
656     self.list_use_data = []
657     psizer.Add(self.list_use, 1, wxGROW, 0)
658    
659 jonathan 649 bsizer = wxBoxSizer(wxHORIZONTAL)
660     bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
661     EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
662 jonathan 629
663 jonathan 649 bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
664     EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
665 jonathan 629
666 jonathan 649 psizer.Add(bsizer, 0, wxGROW, 0)
667    
668 jonathan 629 sizer.Add(psizer, 1, wxGROW, 0)
669    
670    
671     topSizer.Add(sizer, 1, wxGROW, 0)
672    
673     self.SetSizer(topSizer)
674     self.SetAutoLayout(True)
675     topSizer.SetSizeHints(self)
676    
677 frank 978 width, height = self.list_avail.GetSizeTuple()
678     self.list_avail.SetColumnWidth(0,width)
679     width, height = self.list_use.GetSizeTuple()
680     self.list_use.SetColumnWidth(0,width)
681    
682 jonathan 629 self.parent.AllowGenerate(False)
683    
684     def GetNumGroups(self):
685     return self.list_use.GetItemCount()
686    
687     def GetValueList(self):
688     list = []
689     for i in range(self.list_use.GetItemCount()):
690     list.append(self.dataList[self.list_use.GetItemData(i)])
691     return list
692    
693 jonathan 649 def _OnSortList(self, event):
694     id = event.GetId()
695 jonathan 629
696 jonathan 649 if id == ID_UNIQUE_SORTUSE:
697     list = self.list_use
698     else:
699     list = self.list_avail
700 jonathan 629
701 jonathan 649 list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
702     self.dataList[i2]))
703    
704     def _OnReverseList(self, event):
705     id = event.GetId()
706    
707     if id == ID_UNIQUE_REVUSE:
708     list = self.list_use
709     else:
710     list = self.list_avail
711    
712     #
713     # always returning 1 reverses the list
714     #
715     list.SortItems(lambda i1, i2: 1)
716    
717 jonathan 629 def _OnRetrieve(self, event):
718     self.list_use.DeleteAllItems()
719     self.list_use_data = []
720     self.list_avail.DeleteAllItems()
721     self.list_avail_data = []
722    
723 bh 834 list = self.layer.table.UniqueValues(self.fieldName)
724 jonathan 629 index = 0
725     for v in list:
726     self.dataList.append(v)
727     i = self.list_avail.InsertStringItem(index, str(v))
728     self.list_avail.SetItemData(index, i)
729    
730     self.list_avail_data.append(v)
731     index += 1
732    
733     def _OnUseAll(self, event):
734     for i in range(self.list_avail.GetItemCount()):
735     self.__MoveListItem(0, self.list_avail, self.list_use)
736    
737     def _OnUse(self, event):
738     self.__MoveSelectedItems(self.list_avail, self.list_use)
739    
740     def _OnDontUse(self, event):
741     self.__MoveSelectedItems(self.list_use, self.list_avail)
742    
743     def _OnUseNone(self, event):
744    
745     for i in range(self.list_use.GetItemCount()):
746     self.__MoveListItem(0, self.list_use, self.list_avail)
747    
748     def __MoveSelectedItems(self, list_src, list_dest):
749     while True:
750     index = list_src.GetNextItem(-1,
751     wxLIST_NEXT_ALL,
752     wxLIST_STATE_SELECTED)
753    
754     if index == -1:
755     break
756    
757     self.__MoveListItem(index, list_src, list_dest)
758    
759    
760     def __MoveListItem(self, index, list_src, list_dest):
761    
762     item = list_src.GetItem(index)
763    
764     x = list_dest.InsertStringItem(
765     list_dest.GetItemCount(),
766     str(self.dataList[item.GetData()]))
767    
768     list_dest.SetItemData(x, item.GetData())
769    
770     list_src.DeleteItem(index)
771    
772     # def _OnListSize(self, event):
773     # list = event.GetEventObject()
774    
775     # list.SetColumnWidth(0, event.GetSize().GetWidth())
776     #
777    
778 jonathan 877 ID_QUANTILES_RANGE = 4001
779     ID_QUANTILES_RETRIEVE = 4002
780    
781     class GenQuantilesPanel(wxPanel):
782    
783     def __init__(self, parent, layer, fieldName, fieldType):
784     wxPanel.__init__(self, parent, -1)
785    
786     self.parent = parent
787     self.layer = layer
788     self.fieldName = fieldName
789     self.fieldType = fieldType
790    
791     topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
792     wxVERTICAL)
793    
794     self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
795     self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
796     _("Retrieve from Table"))
797    
798     self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
799     self.spin_numClasses.SetRange(1, sys.maxint)
800     self.spin_numClasses.SetValue(1)
801    
802    
803     sizer = wxBoxSizer(wxHORIZONTAL)
804     sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
805     sizer.Add(self.text_range, 1, wxALL, 4)
806     sizer.Add(self.button_retrieve, 0, wxALL, 4)
807    
808     topBox.Add(sizer, 0, wxEXPAND, 0)
809    
810     sizer = wxBoxSizer(wxHORIZONTAL)
811     sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
812     sizer.Add(self.spin_numClasses, 1, wxALL, 4)
813    
814     topBox.Add(sizer, 0, wxEXPAND, 0)
815    
816     self.SetSizer(topBox)
817     self.SetAutoLayout(True)
818     topBox.Fit(self)
819     topBox.SetSizeHints(self)
820    
821     EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
822     EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
823    
824     self.__range = None
825    
826     def GetNumGroups(self):
827     return self.spin_numClasses.GetValue()
828    
829     def GetRange(self):
830     assert self.__range is not None
831    
832     return self.__range
833    
834     def GetList(self):
835    
836 jonathan 898 _list = []
837    
838 jonathan 877 if self.layer.table is not None:
839 bh 1122 wxBeginBusyCursor()
840 jonathan 1100 try:
841     #
842     # FIXME: Replace with a call to table when the method
843     # has been written to get all the values
844     #
845     table = self.layer.table
846     for i in range(table.NumRows()):
847     _list.append(table.ReadValue(i, self.fieldName))
848     finally:
849     wxEndBusyCursor()
850 jonathan 898
851     return _list
852 jonathan 877
853     def OnRangeText(self, event):
854    
855     try:
856     self.__range = Range(self.text_range.GetValue())
857     except ValueError:
858     self.__range = None
859    
860     if self.__range is not None:
861     self.text_range.SetForegroundColour(wxBLACK)
862     else:
863     self.text_range.SetForegroundColour(wxRED)
864    
865     def OnRetrieve(self, event):
866    
867     if self.layer.table is not None:
868     wxBeginBusyCursor()
869 jonathan 1100 try:
870     min, max = self.layer.table.ValueRange(self.fieldName)
871     self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
872     finally:
873     wxEndBusyCursor()
874 jonathan 877
875 jonathan 629 ID_CUSTOMRAMP_COPYSTART = 4001
876     ID_CUSTOMRAMP_COPYEND = 4002
877     ID_CUSTOMRAMP_EDITSTART = 4003
878     ID_CUSTOMRAMP_EDITEND = 4004
879     ID_CUSTOMRAMP_SPROP = 4005
880     ID_CUSTOMRAMP_EPROP = 4006
881    
882     class CustomRampPanel(wxPanel):
883    
884     def __init__(self, parent, shapeType):
885 jonathan 607 wxPanel.__init__(self, parent, -1)
886    
887 jonathan 629 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""), wxHORIZONTAL)
888 jonathan 607
889 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
890     bsizer.Add(wxStaticText(self, -1, _("Start:")), 0, wxALL | wxCENTER, 4)
891     self.startPropCtrl = classifier.ClassGroupPropertiesCtrl(
892     self, ID_CUSTOMRAMP_SPROP,
893     ClassGroupProperties(), shapeType,
894     style=wxSIMPLE_BORDER, size=(40, 20))
895     bsizer.Add(self.startPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
896     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITSTART, _("Change")),
897     0, wxGROW | wxALL | wxCENTER, 4)
898    
899     topSizer.Add(bsizer,
900     1, wxALL \
901     | wxSHAPED \
902     | wxALIGN_CENTER_HORIZONTAL \
903     | wxALIGN_CENTER_VERTICAL, \
904     4)
905    
906 jonathan 649 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
907 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
908 jonathan 649 bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
909 jonathan 629 0, wxGROW | wxALL, 4)
910 jonathan 649 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
911     bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
912 jonathan 629 0, wxGROW | wxALL, 4)
913    
914     topSizer.Add(bsizer,
915     0, wxALL \
916     | wxALIGN_CENTER_HORIZONTAL \
917     | wxALIGN_CENTER_VERTICAL,
918     4)
919    
920     bsizer = wxBoxSizer(wxVERTICAL)
921     bsizer.Add(wxStaticText(self, -1, _("End:")), 0, wxALL | wxCENTER, 4)
922     self.endPropCtrl = classifier.ClassGroupPropertiesCtrl(
923     self, ID_CUSTOMRAMP_EPROP,
924     ClassGroupProperties(), shapeType,
925     style=wxSIMPLE_BORDER, size=(40, 20))
926     bsizer.Add(self.endPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
927     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITEND, _("Change")),
928     0, wxGROW | wxALL | wxCENTER, 4)
929    
930     topSizer.Add(bsizer,
931     1, wxALL \
932     | wxSHAPED \
933     | wxALIGN_RIGHT \
934     | wxALIGN_CENTER_HORIZONTAL \
935     | wxALIGN_CENTER_VERTICAL,
936     4)
937    
938     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYSTART, self._OnCopyStart)
939     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYEND, self._OnCopyEnd)
940     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITSTART, self._OnEditStart)
941     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITEND, self._OnEditEnd)
942    
943     self.SetSizer(topSizer)
944     self.SetAutoLayout(True)
945     topSizer.SetSizeHints(self)
946    
947 jonathan 635 def GetRamp(self):
948     return CustomRamp(self.startPropCtrl.GetProperties(),
949     self.endPropCtrl.GetProperties())
950 jonathan 629
951     def _OnCopyStart(self, event):
952     self.endPropCtrl.SetProperties(self.startPropCtrl.GetProperties())
953    
954     def _OnCopyEnd(self, event):
955     self.startPropCtrl.SetProperties(self.endPropCtrl.GetProperties())
956    
957     def _OnEditStart(self, event):
958     self.startPropCtrl.DoEdit()
959    
960     def _OnEditEnd(self, event):
961     self.endPropCtrl.DoEdit()
962    
963 jonathan 877

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26