/[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 1789 - (hide annotations)
Wed Oct 8 13:10:45 2003 UTC (21 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 35828 byte(s)
(ProjFrame.__DoOnProjAvail): When the
projection type of the currently selected projection is not known,
i.e. there's no panel for it, use the UnknownProjPanel
(ProjFrame.__DoOnProjChoice, ProjFrame._show_proj_panel): Split
the actual replacing of the proj panel into the new method
_show_proj_panel.
(UnknownProjPanel): Add doc-string.
(UnknownProjPanel._DoLayout): Insert a newline into the text so
that the panel is not so wide.

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