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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 880 - (hide annotations)
Fri May 9 16:33:30 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 34223 byte(s)
(ProjFrame.__VerifyButtons): Save button should be disabled if no projection
        is selected in the available list.

1 jonathan 751 # 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 797 import os, sys, math
9 jonathan 717 from wxPython.wx import *
10    
11     from Thuban import _
12    
13 jonathan 730 from Thuban.Model.proj import Projection, ProjFile
14 jonathan 717
15 jonathan 730 from Thuban.Model.resource import GetUserProjFiles, GetSystemProjFiles, \
16     ReadProjFile, WriteProjFile
17 jonathan 717 from Thuban.UI.dialogs import NonModalDialog
18    
19 jonathan 730
20 jonathan 717 ID_PROJ_ADVANCED = 4001
21     ID_PROJ_PROJCHOICE = 4002
22 jonathan 741 ID_PROJ_ADDTOLIST = 4003
23 jonathan 717 ID_PROJ_NEW = 4004
24     ID_PROJ_REVERT = 4006
25     ID_PROJ_AVAIL = 4009
26 jonathan 730 ID_PROJ_SAVE = 4010
27     ID_PROJ_IMPORT = 4011
28     ID_PROJ_EXPORT = 4012
29     ID_PROJ_REMOVE = 4013
30     ID_PROJ_PROJNAME = 4014
31 jonathan 717
32 jonathan 730 CLIENT_PROJ = 0
33     CLIENT_PROJFILE = 1
34 jonathan 717
35     class ProjFrame(NonModalDialog):
36    
37 jonathan 751 def __init__(self, parent, name, title, receiver):
38 jonathan 730 """Initialize the projection dialog.
39 jonathan 717
40 jonathan 730 receiver -- An object that implements the following methods:
41     SetProjection(projection)
42     GetProjection()
43     """
44    
45 jonathan 717 self.receiver = receiver
46 jonathan 751 self.haveTried = False
47 jonathan 717 self.curProjPanel = None
48    
49     self.projPanels = []
50     self.projPanels.append(
51 jonathan 730 ("tmerc", _("Transverse Mercator"), TMPanel))
52 jonathan 717 self.projPanels.append(
53 jonathan 730 ("utm", _("Universal Transverse Mercator"), UTMPanel))
54 jonathan 717 self.projPanels.append(
55     ("lcc", _("Lambert Conic Conformal"), LCCPanel))
56     self.projPanels.append(
57     ("latlong", _("Geographic"), GeoPanel))
58    
59 jonathan 751 NonModalDialog.__init__(self, parent, name, title)
60 jonathan 730 # originally generate by wxGlade
61 jonathan 717 self.panel_1 = wxPanel(self, -1)
62 jonathan 730 self.panel_edit = wxPanel(self, -1)
63     self.panel_buttons = wxPanel(self, -1)
64 jonathan 816 self.label_5 = wxStaticText(self.panel_1, -1,
65     _("Available Projections:"))
66     self.availprojs = wxListBox(self.panel_1, ID_PROJ_AVAIL,
67     style=wxLB_EXTENDED|wxLB_SORT)
68 jonathan 730 self.projfilepath = wxStaticText(self.panel_1, -1, "")
69     self.label_2 = wxStaticText(self.panel_edit, -1, _("Name:"))
70     self.projname = wxTextCtrl(self.panel_edit, ID_PROJ_PROJNAME, "")
71     self.label_3 = wxStaticText(self.panel_edit, -1, _("Projection:"))
72     self.projchoice = wxChoice(self.panel_edit, ID_PROJ_PROJCHOICE)
73 jonathan 816 self.button_import = wxButton(self.panel_1, ID_PROJ_IMPORT,
74     _("Import..."))
75     self.button_export = wxButton(self.panel_1, ID_PROJ_EXPORT,
76     _("Export..."))
77 jonathan 730 self.button_remove = wxButton(self.panel_1, ID_PROJ_REMOVE, _("Remove"))
78     self.button_new = wxButton(self.panel_edit, ID_PROJ_NEW, _("New"))
79     self.button_save = wxButton(self.panel_edit, ID_PROJ_SAVE,_("Save"))
80 jonathan 741 self.button_add = wxButton(self.panel_edit, ID_PROJ_ADDTOLIST,
81 jonathan 730 _("Add to List"))
82 jonathan 816 self.button_try = wxButton(self.panel_buttons, wxID_APPLY, _("Try"))
83     self.button_revert = wxButton(self.panel_buttons, ID_PROJ_REVERT,
84     _("Revert"))
85     self.button_ok = wxButton(self.panel_buttons, wxID_OK, _("OK"))
86     self.button_ok.SetDefault()
87     self.button_close = wxButton(self.panel_buttons, wxID_CANCEL,
88     _("Close"))
89 jonathan 717
90     self.__set_properties()
91     self.__do_layout()
92 jonathan 730 # wxGlade
93 jonathan 717
94 jonathan 751 self.originalProjection = self.receiver.GetProjection()
95    
96 jonathan 730 self.__DoOnProjAvail()
97 jonathan 816 self.button_ok.SetFocus()
98     self.availprojs.SetFocus()
99 jonathan 730
100 jonathan 816 EVT_BUTTON(self, wxID_APPLY, self.OnApply)
101 jonathan 717 EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)
102 jonathan 816 EVT_BUTTON(self, wxID_OK, self.OnOK)
103     EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
104 jonathan 717 EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)
105     EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)
106 jonathan 730 EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)
107     EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)
108     EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)
109 jonathan 717
110     EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)
111 jonathan 730 EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)
112 jonathan 741 EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)
113 jonathan 717
114 jonathan 730 EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)
115    
116 jonathan 816
117     def OnApply(self, event):
118 jonathan 717 self.__SetProjection()
119 jonathan 751 self.haveTried = True
120 jonathan 717
121 jonathan 816 def OnOK(self, event):
122     self.__SetProjection()
123     self.Close()
124    
125     def OnCancel(self, event):
126     """Cancel just closes the dialog, but we call it cancel so we
127     can overload the functionality of wxDialog.
128     """
129     self.Close()
130    
131 jonathan 717 def _OnRevert(self, event):
132 jonathan 751 if self.haveTried:
133 jonathan 717 self.receiver.SetProjection(self.originalProjection)
134 jonathan 751 self.haveTried = False
135 jonathan 717
136    
137 jonathan 730 def _OnNew(self, event):
138 jonathan 717
139 jonathan 751 # clear all selections
140     sel = self.availprojs.GetSelections()
141     for index in sel:
142     self.availprojs.SetSelection(index, False)
143    
144     self.projname.Clear()
145    
146     # supply a projection panel if there wasn't one
147     if self.curProjPanel is None:
148     self.projchoice.SetSelection(0)
149     self.__DoOnProjChoice()
150    
151     self.curProjPanel.Clear()
152    
153 jonathan 730 def _OnSave(self, event):
154 jonathan 717
155 jonathan 730 sel = self.availprojs.GetSelections()
156     assert len(sel) == 1, "button shouldn't be enabled"
157 jonathan 717
158 jonathan 730 proj, projfile = self.availprojs.GetClientData(sel[0])
159 jonathan 717
160 jonathan 730 assert proj is not None and projfile is not None
161 jonathan 717
162 jonathan 730 newproj = self.__GetProjection()
163 jonathan 717
164 jonathan 730 if newproj is not None:
165 jonathan 760 projfile.Replace(proj, newproj)
166 jonathan 730 try:
167     WriteProjFile(projfile)
168     except IOError, (errno, errstr):
169 jonathan 751 self.__ShowError(projfile.GetFilename(), errstr)
170 jonathan 797 self.availprojs.SetClientData(sel[0], [newproj, projfile])
171 jonathan 730
172 jonathan 741 def _OnAddToList(self, event):
173 jonathan 730
174     proj = self.__GetProjection()
175     if proj is not None:
176     self.__usrProjFile.Add(proj)
177     try:
178     WriteProjFile(self.__usrProjFile)
179     except IOError, (errno, errstr):
180 jonathan 751 self.__ShowError(self.__userProjFile.GetFilename(), errstr)
181    
182 jonathan 730 self.__FillAvailList()
183    
184 jonathan 717 def _OnProjAvail(self, event):
185     self.__DoOnProjAvail()
186    
187 jonathan 730 def _OnImport(self, event):
188    
189     dlg = wxFileDialog(self, _("Import"), style = wxOPEN)
190    
191     if dlg.ShowModal() == wxID_OK:
192     path = dlg.GetPath()
193    
194     try:
195     projFile = ReadProjFile(path)
196     for proj in projFile.GetProjections():
197     self.__usrProjFile.Add(proj)
198     WriteProjFile(self.__usrProjFile)
199     except IOError, (errno, errstr):
200 jonathan 751 self.__ShowError(dlg.GetPath(), errstr)
201 jonathan 730
202     self.__FillAvailList()
203    
204     dlg.Destroy()
205    
206     def _OnExport(self, event):
207    
208 jonathan 741 sel = self.availprojs.GetSelections()
209     assert len(sel) != 0, "button should be disabled"
210 jonathan 730
211     dlg = wxFileDialog(self, _("Export"),
212 jonathan 741 style = wxSAVE|wxOVERWRITE_PROMPT)
213 jonathan 730
214     if dlg.ShowModal() == wxID_OK:
215     path = dlg.GetPath()
216    
217     projFile = ProjFile(path)
218 jonathan 741
219     for i in sel:
220     proj = self.availprojs.GetClientData(i)[CLIENT_PROJ]
221     if proj is not None:
222     projFile.Add(proj)
223    
224 jonathan 730 try:
225     WriteProjFile(projFile)
226     except IOError, (errno, errstr):
227 jonathan 751 self.__ShowError(dlg.GetPath(), errstr)
228 jonathan 730
229     dlg.Destroy()
230    
231     def _OnRemove(self, event):
232    
233     sel = self.availprojs.GetSelections()
234     assert len(sel) != 0, "button should be disabled!"
235    
236     #
237     # remove the items backwards so the indices don't change
238     #
239     sel = list(sel)
240     sel.sort()
241     sel.reverse()
242    
243     newselection = -1
244     if len(sel) == 1:
245     newselection = sel[0] - 1
246     if newselection < 0:
247     newselection = 0
248    
249     for i in sel:
250     proj, projfile = self.availprojs.GetClientData(i)
251    
252     #
253     # this could be the case if they selected <None> or
254     # the currently used projection
255     #
256     if proj is not None and projfile is not None:
257     projfile.Remove(proj)
258    
259     try:
260     WriteProjFile(projfile)
261     except IOError, (errno, errstr):
262 jonathan 751 self.__ShowError(projfile.GetFilename(), errstr)
263 jonathan 730
264     self.__FillAvailList()
265    
266     #
267     # this *could* produce incorrect results if the .proj files
268     # change between the last list update and this selection
269     # because the list has been repopulated.
270     #
271     if newselection != -1 and self.availprojs.GetCount() > 0:
272     self.availprojs.SetSelection(newselection)
273    
274 jonathan 751 self.__VerifyButtons()
275    
276 jonathan 730 def _OnProjName(self, event):
277     self.__VerifyButtons()
278    
279 jonathan 751 def __ShowError(self, filename, errstr):
280     wxMessageDialog(self,
281     _("The following error occured:\n") +
282     filename + "\n" + errstr,
283     _("Error"), wxOK | wxICON_ERROR).ShowModal()
284    
285 jonathan 730 def __VerifyButtons(self):
286 jonathan 751 """Enable or disable the appropriate buttons based on the
287     current state of the dialog.
288     """
289    
290 jonathan 730 sel = self.availprojs.GetSelections()
291    
292     self.button_import.Enable(True)
293     self.button_export.Enable(True)
294     self.button_save.Enable(True)
295     self.button_remove.Enable(True)
296    
297     self.panel_edit.Enable(True)
298    
299 jonathan 751 for ctrl in [self.button_import,
300     self.button_export,
301     self.button_remove,
302     self.button_save,
303     self.button_add,
304     self.projchoice,
305     self.projname,
306     self.panel_edit]:
307     ctrl.Enable(True)
308    
309     if self.curProjPanel is not None:
310     self.curProjPanel.Enable(True)
311    
312 jonathan 730 if len(sel) == 0:
313     self.button_import.Enable(True)
314     self.button_export.Enable(False)
315     self.button_remove.Enable(False)
316 jonathan 880 self.button_save.Enable(False)
317 jonathan 730
318     elif len(sel) == 1:
319    
320     proj, projFile = self.availprojs.GetClientData(sel[0])
321    
322     self.button_save.Enable(len(self.projname.GetValue()) > 0)
323     self.button_add.Enable(len(self.projname.GetValue()) > 0)
324    
325     if proj is None:
326 jonathan 751 # <None> is selected
327     for ctrl in [self.button_export,
328     self.button_remove,
329     self.button_save,
330     self.button_add,
331     self.projchoice,
332     self.projname]:
333     ctrl.Enable(False)
334    
335     if self.curProjPanel is not None:
336     self.curProjPanel.Enable(False)
337    
338     elif proj is self.originalProjection:
339 jonathan 730 self.button_remove.Enable(False)
340    
341     if projFile is None:
342     self.button_save.Enable(False)
343    
344     else:
345     self.panel_edit.Enable(False)
346    
347 jonathan 717 def __DoOnProjAvail(self):
348    
349 jonathan 730 sel = self.availprojs.GetSelections()
350     if len(sel) == 1:
351 jonathan 717
352 jonathan 730 proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]
353     projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]
354 jonathan 717
355 jonathan 730 if proj is None:
356     # user selected <None>
357     self.projname.Clear()
358 jonathan 751
359 jonathan 730 else:
360    
361     if projfile is not None:
362 jonathan 741 self.projfilepath.SetLabel(projfile.GetFilename())
363 jonathan 730 else:
364     # only None if the currently used projection is selected
365     self.projfilepath.SetLabel("")
366 jonathan 717
367 jonathan 730 self.projname.SetValue(proj.GetName())
368 jonathan 717
369 jonathan 730 myProjType = proj.GetParameter("proj")
370     i = 0
371     for projType, name, clazz in self.projPanels:
372     if myProjType == projType:
373     self.projchoice.SetSelection(i)
374     self.__DoOnProjChoice()
375 jonathan 751
376     #
377     # self.curProjPanel should not be null
378     # after a call to __DoOnProjChoice
379     #
380     assert self.curProjPanel is not None
381    
382 jonathan 730 self.curProjPanel.SetProjection(proj)
383     i += 1
384 jonathan 717
385 jonathan 730 self.__VerifyButtons()
386    
387 jonathan 717 def _OnProjChoice(self, event):
388     self.__DoOnProjChoice()
389    
390     def __DoOnProjChoice(self):
391 jonathan 751 """Create and layout a projection panel based on the selected
392     projection type.
393    
394     This is necessary to have in seperate method since calls to
395     wxChoice.SetSelection() do not trigger an event.
396    
397     At the end of this method self.curProjPanel will not be None
398     if there was a item selected.
399     """
400    
401 jonathan 717 choice = self.projchoice
402    
403     sel = choice.GetSelection()
404 jonathan 730 if sel != -1:
405 jonathan 717
406 jonathan 730 clazz, obj = choice.GetClientData(sel)
407 jonathan 717
408 jonathan 730 if obj is None:
409     obj = clazz(self.panel_edit, self.receiver)
410     choice.SetClientData(sel, [clazz, obj])
411 jonathan 717
412 jonathan 730 if self.curProjPanel is not None:
413     self.curProjPanel.Hide()
414     self.sizer_projctrls.Remove(self.curProjPanel)
415 jonathan 717
416 jonathan 730 self.curProjPanel = obj
417     self.curProjPanel.Show()
418 jonathan 717
419 jonathan 730 self.sizer_projctrls.Add(self.curProjPanel, 1,
420     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
421     self.sizer_projctrls.Layout()
422     self.Layout()
423     self.topBox.SetSizeHints(self)
424 jonathan 717
425     def __SetProjection(self):
426 jonathan 751 """Set the receiver's projection."""
427 jonathan 717
428     #
429     # save the original projection only once in case
430     # we try to apply several different projections
431     #
432 jonathan 730 self.receiver.SetProjection(self.__GetProjection())
433 jonathan 717
434 jonathan 730 def __GetProjection(self):
435 jonathan 751 """Return a suitable Projection object based on the current
436     state of the dialog box selections.
437 jonathan 717
438 jonathan 730 Could be None.
439     """
440 jonathan 717
441 jonathan 751 sel = self.availprojs.GetSelections()
442     assert len(sel) < 2, "button should be disabled"
443 jonathan 717
444 jonathan 751
445     if len(sel) == 1:
446     proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]
447     if proj is None:
448     # <None> is selected
449     return None
450    
451     #
452     # self.curProjPanel should always contain the most
453     # relevant data for a projection
454     #
455 jonathan 730 if self.curProjPanel is not None:
456 jonathan 751 return Projection(self.curProjPanel.GetParameters(),
457     self.projname.GetValue())
458 jonathan 717
459 jonathan 751 return None
460 jonathan 730
461 jonathan 747 def __FillAvailList(self, selectCurrent = False):
462 jonathan 751 """Populate the list of available projections.
463    
464     selectCurrent -- if True, select the projection used by
465     the receiver, otherwise select nothing.
466     """
467    
468 jonathan 730 self.availprojs.Clear()
469    
470     #
471 jonathan 747 # We add the current projection to the list first so that
472     # we are sure that it's at index 0. That way we can
473     # set the selection with confidence. The problem is the
474     # the list is automatically sorted when an item is appended
475     # and the index of where it was inserted is not returned.
476     #
477     proj = self.receiver.GetProjection()
478     if proj is not None:
479     self.availprojs.Append(_("%s (current)") % proj.GetName(),
480     [proj, None])
481     if selectCurrent:
482     self.availprojs.SetSelection(0)
483     self.availprojs.SetFirstItem(0)
484    
485     #
486 jonathan 730 # the list can never be empty. there will always be
487     # at least this one item
488     #
489     self.availprojs.Append("<None>", (None, None))
490    
491 jonathan 751 # proj is only None when <None> should be selected
492     if proj is None and selectCurrent:
493     self.availprojs.SetSelection(0)
494     self.availprojs.SetFirstItem(0)
495 jonathan 730
496     projfile = GetSystemProjFiles()
497 jonathan 751 projfile = projfile[0]
498     for proj in projfile.GetProjections():
499     self.availprojs.Append(proj.GetName(), [proj, projfile])
500     self.__sysProjFile = projfile
501 jonathan 717
502 jonathan 730 projfile = GetUserProjFiles()
503 jonathan 751 projfile = projfile[0]
504     for proj in projfile.GetProjections():
505     self.availprojs.Append(proj.GetName(), [proj, projfile])
506     self.__usrProjFile = projfile
507 jonathan 717
508     for proj, name, clazz in self.projPanels:
509     self.projchoice.Append(name, [clazz, None])
510    
511 jonathan 730 def __set_properties(self):
512    
513 jonathan 757 #self.availprojs.SetSelection(0)
514 jonathan 717 self.projchoice.SetSelection(0)
515    
516 jonathan 747 self.__FillAvailList(selectCurrent = True)
517    
518 jonathan 730 self.projname.SetMaxLength(32)
519    
520 jonathan 717 def __do_layout(self):
521 jonathan 730 # originally generated by wxGlade
522    
523 jonathan 717 self.topBox = wxBoxSizer(wxVERTICAL)
524     self.sizer_panel = wxBoxSizer(wxVERTICAL)
525     sizer_6 = wxBoxSizer(wxHORIZONTAL)
526     self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)
527 jonathan 730 self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)
528 jonathan 717 sizer_11 = wxBoxSizer(wxVERTICAL)
529     self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
530     sizer_14 = wxBoxSizer(wxHORIZONTAL)
531     sizer_13 = wxBoxSizer(wxHORIZONTAL)
532 jonathan 730 sizer_15 = wxBoxSizer(wxVERTICAL)
533     sizer_15.Add(self.button_import, 0, wxALL, 4)
534     sizer_15.Add(self.button_export, 0, wxALL, 4)
535     sizer_15.Add(20, 20, 0, wxEXPAND, 0)
536     sizer_15.Add(self.button_remove, 0, wxALL|wxALIGN_BOTTOM, 4)
537    
538     # list controls
539     grid_sizer_1 = wxFlexGridSizer(3, 2, 0, 0)
540 jonathan 717 grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)
541     grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)
542 jonathan 730 grid_sizer_1.Add(self.availprojs, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
543     grid_sizer_1.Add(sizer_15, 0, wxALL|wxEXPAND, 4)
544     grid_sizer_1.Add(self.projfilepath, 0, wxALL|wxADJUST_MINSIZE, 4)
545 jonathan 717 grid_sizer_1.AddGrowableRow(1)
546     grid_sizer_1.AddGrowableCol(0)
547 jonathan 730
548     # edit controls
549 jonathan 717 sizer_13.Add(self.label_2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
550     sizer_13.Add(self.projname, 1, wxALL, 4)
551     self.sizer_projctrls.Add(sizer_13, 0, wxEXPAND, 0)
552     sizer_14.Add(self.label_3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
553 jonathan 730 sizer_14.Add(self.projchoice, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
554 jonathan 717 self.sizer_projctrls.Add(sizer_14, 0, wxEXPAND, 0)
555     self.sizer_edit.Add(self.sizer_projctrls, 1, wxEXPAND, 0)
556     sizer_11.Add(self.button_new, 0, wxALL|wxEXPAND, 4)
557 jonathan 730 sizer_11.Add(self.button_save, 0, wxALL|wxEXPAND, 4)
558     sizer_11.Add(self.button_add, 0, wxALL|wxEXPAND, 4)
559 jonathan 717 self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)
560 jonathan 730
561 jonathan 717 sizer_6.Add(20, 20, 1, wxEXPAND, 0)
562     sizer_6.Add(self.button_try, 0, wxALL, 4)
563     sizer_6.Add(20, 20, 1, 0, 0)
564     sizer_6.Add(self.button_revert, 0, wxALL, 4)
565     sizer_6.Add(20, 20, 1, 0, 0)
566     sizer_6.Add(self.button_ok, 0, wxALL, 4)
567     sizer_6.Add(20, 20, 1, 0, 0)
568     sizer_6.Add(self.button_close, 0, wxALL, 4)
569     sizer_6.Add(20, 20, 1, wxEXPAND, 0)
570 jonathan 730
571 jonathan 717 self.panel_1.SetAutoLayout(1)
572 jonathan 730 self.panel_1.SetSizer(grid_sizer_1)
573     grid_sizer_1.Fit(self.panel_1)
574     grid_sizer_1.SetSizeHints(self.panel_1)
575    
576     self.panel_edit.SetAutoLayout(1)
577     self.panel_edit.SetSizer(self.sizer_edit)
578     self.sizer_edit.Fit(self.panel_edit)
579     self.sizer_edit.SetSizeHints(self.panel_edit)
580    
581     self.panel_buttons.SetAutoLayout(1)
582     self.panel_buttons.SetSizer(sizer_6)
583     sizer_6.Fit(self.panel_buttons)
584     sizer_6.SetSizeHints(self.panel_buttons)
585    
586     self.sizer_mainctrls.Add(self.panel_1, 0,
587     wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)
588     self.sizer_mainctrls.Add(self.panel_edit, 1,
589     wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)
590    
591     self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)
592     self.topBox.Add(self.panel_buttons, 0, wxEXPAND, 0)
593    
594 jonathan 717 self.SetAutoLayout(1)
595     self.SetSizer(self.topBox)
596     self.topBox.Fit(self)
597     self.topBox.SetSizeHints(self)
598     self.Layout()
599    
600     # end of class ProjFrame
601    
602    
603     class ProjPanel(wxPanel):
604     """Base class for all projection panels."""
605    
606     def __init__(self, parent):
607     wxPanel.__init__(self, parent, -1)
608    
609     self.__ellps = wxChoice(self, -1)
610 jonathan 816 self.ellpsData = [("airy" , _("Airy")),
611     ("bessel", _("Bessel 1841")),
612 jonathan 717 ("clrk66", _("Clarke 1866")),
613     ("clrk80", _("Clarke 1880")),
614     ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
615     ("intl" , _("International 1909 (Hayford)")),
616     ("WGS84" , _("WGS 84"))]
617    
618     for tag, name in self.ellpsData:
619     self.__ellps.Append(name, tag)
620    
621     self.__ellps.SetSelection(0)
622    
623     def _DoLayout(self, childPanel = None):
624    
625     panelSizer = wxBoxSizer(wxVERTICAL)
626    
627     if childPanel is not None:
628 jonathan 797 panelSizer.Add(childPanel, 0, wxEXPAND, 0)
629 jonathan 717
630     sizer = wxBoxSizer(wxHORIZONTAL)
631     sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)
632 jonathan 730 sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
633 jonathan 717 panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
634    
635     self.SetAutoLayout(1)
636     self.SetSizer(panelSizer)
637     panelSizer.Fit(self)
638     panelSizer.SetSizeHints(self)
639     self.Layout()
640    
641     def SetProjection(self, proj):
642     if proj is not None:
643     param = proj.GetParameter("ellps")
644     i = 0
645     for tag, name in self.ellpsData:
646     if param == tag:
647     self.__ellps.SetSelection(i)
648     return # returning early!
649     i += 1
650    
651     #
652     # if proj is none, or the parameter couldn't be found...
653     #
654     self.__ellps.SetSelection(0)
655    
656     def GetParameters(self):
657     return ["ellps=" + self.__ellps.GetClientData(
658     self.__ellps.GetSelection())]
659    
660    
661     ID_TMPANEL_LAT = 4001
662     ID_TMPANEL_LONG = 4002
663     ID_TMPANEL_FASLE_EAST = 4003
664     ID_TMPANEL_FALSE_NORTH = 4004
665     ID_TMPANEL_SCALE = 4005
666    
667     class UnknownProjPanel(ProjPanel):
668 jonathan 730 def __init__(self, parent, receiver):
669 jonathan 717 ProjPanel.__init__(self, parent)
670    
671     self._DoLayout()
672    
673     def _DoLayout(self):
674     sizer = wxBoxSizer(wxVERTICAL)
675    
676     sizer.Add(wxStaticText(self, -1,
677     _("Thuban does not know the parameters for the " +
678     "current projection and cannot display a " +
679     "configuration panel.")))
680    
681     ProjPanel._DoLayout(self, sizer)
682    
683     def GetProjName(self):
684     return "Unknown"
685    
686     def SetProjection(self, proj):
687     pass
688    
689     def GetParameters(self):
690     return None
691    
692     class TMPanel(ProjPanel):
693 jonathan 730 """Projection panel for Transverse Mercator."""
694 jonathan 717
695 jonathan 730 def __init__(self, parent, receiver):
696 jonathan 717 ProjPanel.__init__(self, parent)
697    
698     self.__latitude = wxTextCtrl(self, ID_TMPANEL_LAT)
699     self.__longitude = wxTextCtrl(self, ID_TMPANEL_LONG)
700     self.__falseEast = wxTextCtrl(self, ID_TMPANEL_FASLE_EAST)
701     self.__falseNorth = wxTextCtrl(self, ID_TMPANEL_FALSE_NORTH)
702     self.__scale = wxTextCtrl(self, ID_TMPANEL_SCALE)
703    
704     self._DoLayout()
705    
706     def _DoLayout(self):
707    
708     sizer = wxFlexGridSizer(4, 4, 0, 0)
709     sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
710     sizer.Add(self.__latitude, 0, wxALL, 4)
711     sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
712     sizer.Add(self.__falseEast, 0, wxALL, 4)
713     sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
714     sizer.Add(self.__longitude, 0, wxALL, 4)
715     sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
716     sizer.Add(self.__falseNorth, 0, wxALL, 4)
717     sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)
718     sizer.Add(self.__scale, 0, wxALL, 4)
719    
720     ProjPanel._DoLayout(self, sizer)
721    
722     def GetProjName(self):
723 jonathan 730 return _("Transverse Mercator")
724 jonathan 717
725     def SetProjection(self, proj):
726     ProjPanel.SetProjection(self, proj)
727    
728     self.__latitude.SetValue(proj.GetParameter("lat_0"))
729     self.__longitude.SetValue(proj.GetParameter("lon_0"))
730     self.__falseEast.SetValue(proj.GetParameter("x_0"))
731     self.__falseNorth.SetValue(proj.GetParameter("y_0"))
732     self.__scale.SetValue(proj.GetParameter("k"))
733    
734     ProjPanel.SetProjection(self, proj)
735    
736     def GetParameters(self):
737     params = ["proj=tmerc",
738     "lat_0=" + self.__latitude.GetValue(),
739     "lon_0=" + self.__longitude.GetValue(),
740     "x_0=" + self.__falseEast.GetValue(),
741     "y_0=" + self.__falseNorth.GetValue(),
742     "k=" + self.__scale.GetValue()]
743     params.extend(ProjPanel.GetParameters(self))
744     return params
745    
746     def Clear(self):
747     self.__latitude.Clear()
748     self.__longitude.Clear()
749     self.__falseEast.Clear()
750     self.__falseNorth.Clear()
751     self.__scale.Clear()
752    
753     ProjPanel.Clear(self)
754    
755     ID_UTMPANEL_ZONE = 4001
756     ID_UTMPANEL_SOUTH = 4002
757     ID_UTMPANEL_PROP = 4003
758    
759     class UTMPanel(ProjPanel):
760 jonathan 730 """Projection Panel for Universal Transverse Mercator."""
761 jonathan 717
762 jonathan 730 def __init__(self, parent, receiver):
763 jonathan 717 ProjPanel.__init__(self, parent)
764    
765 jonathan 730 self.receiver = receiver
766 jonathan 717
767     self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
768 jonathan 816 self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))
769 jonathan 717 self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,
770     _("Southern Hemisphere"))
771    
772     self._DoLayout()
773    
774     EVT_BUTTON(self, ID_UTMPANEL_PROP, self._OnPropose)
775    
776     def _DoLayout(self):
777    
778     sizer = wxBoxSizer(wxVERTICAL)
779     psizer = wxBoxSizer(wxHORIZONTAL)
780     psizer.Add(wxStaticText(self, -1, _("Zone:")), 0, wxALL, 4)
781     psizer.Add(self.__zone, 0, wxALL, 4)
782     psizer.Add(self.__propButton, 0, wxALL, 4)
783     sizer.Add(psizer, 0, wxALL, 4)
784     sizer.Add(self.__south, 0, wxALL, 4)
785    
786     ProjPanel._DoLayout(self, sizer)
787    
788     def GetProjName(self):
789 jonathan 730 return _("Universal Transverse Mercator")
790 jonathan 717
791     def SetProjection(self, proj):
792     self.__zone.SetValue(int(proj.GetParameter("zone")))
793     self.__south.SetValue(proj.GetParameter("south") != "")
794     ProjPanel.SetProjection(self, proj)
795    
796     def GetParameters(self):
797     params = ["proj=utm", "zone=" + str(self.__zone.GetValue())]
798     if self.__south.IsChecked():
799     params.append("south")
800    
801     params.extend(ProjPanel.GetParameters(self))
802     return params
803    
804     def Clear(self):
805     self.__zone.SetValue(1)
806     self.__south.SetValue(False)
807     ProjPanel.Clear(self)
808    
809     def _OnPropose(self, event):
810     UTMProposeZoneDialog
811 jonathan 730 dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
812 jonathan 717 if dlg.ShowModal() == wxID_OK:
813     self.__zone.SetValue(dlg.GetProposedZone())
814    
815     class LCCPanel(ProjPanel):
816     """Projection Panel for Lambert Conic Conformal."""
817    
818 jonathan 730 def __init__(self, parent, receiver):
819 jonathan 717 ProjPanel.__init__(self, parent)
820    
821     self.__fspLatitude = wxTextCtrl(self, -1)
822     self.__sspLatitude = wxTextCtrl(self, -1)
823     self.__originLat = wxTextCtrl(self, -1)
824     self.__meridian = wxTextCtrl(self, -1)
825     self.__falseEast = wxTextCtrl(self, -1)
826     self.__falseNorth = wxTextCtrl(self, -1)
827    
828     self._DoLayout()
829    
830     def _DoLayout(self):
831    
832     sizer = wxFlexGridSizer(6, 2, 0, 0)
833     sizer.Add(wxStaticText(self, -1,
834     _("Latitude of first standard parallel:")))
835     sizer.Add(self.__fspLatitude, 0, wxALL, 4)
836     sizer.Add(wxStaticText(self, -1,
837     _("Latitude of second standard parallel:")))
838     sizer.Add(self.__sspLatitude, 0, wxALL, 4)
839     sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
840     sizer.Add(self.__originLat, 0, wxALL, 4)
841     sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
842     sizer.Add(self.__meridian, 0, wxALL, 4)
843     sizer.Add(wxStaticText(self, -1, _("False Easting:")))
844     sizer.Add(self.__falseEast, 0, wxALL, 4)
845     sizer.Add(wxStaticText(self, -1, _("False Northing:")))
846     sizer.Add(self.__falseNorth, 0, wxALL, 4)
847    
848     ProjPanel._DoLayout(self, sizer)
849    
850     def GetProjName(self):
851     return _("Lambert Conic Conformal")
852    
853     def SetProjection(self, proj):
854     self.__fspLatitude.SetValue(proj.GetParameter("lat_1"))
855     self.__sspLatitude.SetValue(proj.GetParameter("lat_2"))
856     self.__originLat.SetValue(proj.GetParameter("lat_0"))
857     self.__meridian.SetValue(proj.GetParameter("lon_0"))
858     self.__falseEast.SetValue(proj.GetParameter("x_0"))
859     self.__falseNorth.SetValue(proj.GetParameter("y_0"))
860    
861     ProjPanel.SetProjection(self, proj)
862    
863     def GetParameters(self):
864     params = ["proj=lcc",
865     "lat_1=" + self.__fspLatitude.GetValue(),
866     "lat_2=" + self.__sspLatitude.GetValue(),
867     "lat_0=" + self.__originLat.GetValue(),
868     "lon_0=" + self.__meridian.GetValue(),
869     "x_0=" + self.__falseEast.GetValue(),
870     "y_0=" + self.__falseNorth.GetValue()]
871    
872     params.extend(ProjPanel.GetParameters(self))
873     return params
874    
875     def Clear(self):
876     self.__fspLatitude.Clear()
877     self.__sspLatitude.Clear()
878     self.__originLat.Clear()
879     self.__meridian.Clear()
880     self.__falseEast.Clear()
881     self.__falseNorth.Clear()
882    
883     ProjPanel.Clear(self)
884    
885     class GeoPanel(ProjPanel):
886     """Projection Panel for a Geographic Projection."""
887    
888 jonathan 730 def __init__(self, parent, receiver):
889 jonathan 717 ProjPanel.__init__(self, parent)
890    
891 jonathan 797 self.__choices = [(_("Radians"), "1"),
892     (_("Degrees"), "0.017453")]
893    
894     self.__scale = wxChoice(self, -1)
895     for choice, value in self.__choices:
896     self.__scale.Append(choice, value)
897    
898     self._DoLayout()
899    
900 jonathan 717 def GetProjName(self):
901     return _("Geographic")
902    
903     def SetProjection(self, proj):
904 jonathan 797 value = proj.GetParameter("to_meter")
905     for i in range(len(self.__choices)):
906     choice, data = self.__choices[i]
907     if value == data:
908     self.__scale.SetSelection(i)
909 jonathan 717 ProjPanel.SetProjection(self, proj)
910    
911     def GetParameters(self):
912 jonathan 797 params = ["proj=latlong",
913     "to_meter=%s" % self.__scale.GetClientData(
914     self.__scale.GetSelection())]
915    
916 jonathan 717 params.extend(ProjPanel.GetParameters(self))
917     return params
918    
919     def Clear(self):
920     ProjPanel.Clear(self)
921    
922 jonathan 797 def _DoLayout(self):
923     sizer = wxBoxSizer(wxHORIZONTAL)
924 jonathan 717
925 jonathan 797 sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
926     0, wxALL, 4)
927     sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
928    
929     self.__scale.SetSelection(0)
930    
931     ProjPanel._DoLayout(self, sizer)
932    
933    
934 jonathan 717 ID_UTM_PROPOSE_ZONE_DIALOG_TAKE = 4001
935     ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
936     class UTMProposeZoneDialog(wxDialog):
937    
938     """Propose a sensible Zone considering the current map extent."""
939    
940     def __init__(self, parent, (x, y, x2, y2)):
941     wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
942     wxDefaultPosition, wxSize(200, 100))
943     self.parent = parent
944     #x, y, x2, y2 = elf.parent.parent.map_bounding_box
945     x = x + 180
946     x2 = x2 + 180
947     center = (x2 - x) / 2 + x
948     self.proposedZone = int(center / 6 + 1)
949     self.dialogLayout()
950    
951     def dialogLayout(self):
952     topBox = wxBoxSizer(wxVERTICAL)
953    
954     textBox = wxBoxSizer(wxVERTICAL)
955     textBox.Add(wxStaticText(self, -1, _("The current map extent center " +
956     "lies in UTM Zone")),
957     0, wxALIGN_CENTER|wxALL, 4)
958     textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
959     0, wxALIGN_CENTER|wxALL, 4)
960    
961     topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
962    
963     buttonBox = wxBoxSizer(wxHORIZONTAL)
964     buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
965     _("Take")), 0, wxALL, 4)
966     buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL,
967     _("Cancel")), 0, wxALL, 4)
968     topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
969     EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
970     EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
971    
972     self.SetAutoLayout(True)
973     self.SetSizer(topBox)
974     topBox.Fit(self)
975     topBox.SetSizeHints(self)
976    
977     def OnTake(self, event):
978     self.EndModal(wxID_OK)
979    
980     def OnCancel(self, event):
981     self.EndModal(wxID_CANCEL)
982    
983     def GetProposedZone(self):
984     return self.proposedZone

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26