/[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 834 - (hide annotations)
Tue May 6 15:52:36 2003 UTC (21 years, 10 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 33238 byte(s)
(ClassGenDialog.__init__)
(GenUniformPanel._OnRetrieve, GenUniquePanel._OnRetrieve): Adapt
to new table interface

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26