/[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 781 - (hide annotations)
Tue Apr 29 16:53:38 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 33215 byte(s)
Remove all uses of Str2Num.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26