/[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 1795 - (hide annotations)
Wed Oct 8 17:35:52 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: 35788 byte(s)
(ProjFrame.__set_properties): Remove the
length limit on the projname text control

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 717 def __do_layout(self):
566 jonathan 730 # originally generated by wxGlade
567    
568 jonathan 717 self.topBox = wxBoxSizer(wxVERTICAL)
569     self.sizer_panel = wxBoxSizer(wxVERTICAL)
570     sizer_6 = wxBoxSizer(wxHORIZONTAL)
571 frank 976 self.sizer_mainbttns = wxBoxSizer(wxHORIZONTAL)
572 jonathan 717 self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)
573 jonathan 730 self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)
574 jonathan 717 sizer_11 = wxBoxSizer(wxVERTICAL)
575     self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
576     sizer_14 = wxBoxSizer(wxHORIZONTAL)
577     sizer_13 = wxBoxSizer(wxHORIZONTAL)
578 jonathan 730 sizer_15 = wxBoxSizer(wxVERTICAL)
579     sizer_15.Add(self.button_import, 0, wxALL, 4)
580     sizer_15.Add(self.button_export, 0, wxALL, 4)
581     sizer_15.Add(20, 20, 0, wxEXPAND, 0)
582     sizer_15.Add(self.button_remove, 0, wxALL|wxALIGN_BOTTOM, 4)
583    
584     # list controls
585     grid_sizer_1 = wxFlexGridSizer(3, 2, 0, 0)
586 jonathan 717 grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)
587     grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)
588 jonathan 730 grid_sizer_1.Add(self.availprojs, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
589     grid_sizer_1.Add(sizer_15, 0, wxALL|wxEXPAND, 4)
590 jonathan 1181 grid_sizer_1.Add(self.projfilepath, 0, wxEXPAND|wxALL|wxADJUST_MINSIZE, 4)
591 jonathan 717 grid_sizer_1.AddGrowableRow(1)
592     grid_sizer_1.AddGrowableCol(0)
593 jonathan 730
594     # edit controls
595 jonathan 717 sizer_13.Add(self.label_2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
596     sizer_13.Add(self.projname, 1, wxALL, 4)
597     self.sizer_projctrls.Add(sizer_13, 0, wxEXPAND, 0)
598 frank 976 sizer_14.Add(self.label_3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
599 frank 1034 sizer_14.Add(self.projchoice, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
600 jonathan 717 self.sizer_projctrls.Add(sizer_14, 0, wxEXPAND, 0)
601     self.sizer_edit.Add(self.sizer_projctrls, 1, wxEXPAND, 0)
602 jonathan 1167 sizer_11.Add(self.button_new, 0, wxEXPAND|wxALL, 4)
603     sizer_11.Add(self.button_add, 0, wxEXPAND|wxALL, 4)
604 frank 976 sizer_11.Add(20, 20, 0, wxEXPAND, 0)
605 jonathan 1167 sizer_11.Add(self.button_save, 0, wxEXPAND|wxALL|wxALIGN_BOTTOM, 4)
606 jonathan 717 self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)
607 jonathan 730
608 frank 976 sizer_6.Add(self.button_try, 0, wxRIGHT| wxEXPAND, 10)
609     sizer_6.Add(self.button_revert, 0, wxRIGHT| wxEXPAND, 10)
610     sizer_6.Add(self.button_ok, 0, wxRIGHT| wxEXPAND, 10)
611     sizer_6.Add(self.button_close, 0, wxRIGHT| wxEXPAND, 10)
612 jonathan 730
613 jonathan 717 self.panel_1.SetAutoLayout(1)
614 jonathan 730 self.panel_1.SetSizer(grid_sizer_1)
615     grid_sizer_1.Fit(self.panel_1)
616     grid_sizer_1.SetSizeHints(self.panel_1)
617    
618     self.panel_edit.SetAutoLayout(1)
619     self.panel_edit.SetSizer(self.sizer_edit)
620     self.sizer_edit.Fit(self.panel_edit)
621     self.sizer_edit.SetSizeHints(self.panel_edit)
622    
623     self.sizer_mainctrls.Add(self.panel_1, 0,
624     wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)
625     self.sizer_mainctrls.Add(self.panel_edit, 1,
626     wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)
627    
628 frank 976 self.sizer_mainbttns.Add(sizer_6, 0,
629     wxALL|wxEXPAND|wxADJUST_MINSIZE, 10)
630    
631 jonathan 730 self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)
632 frank 976 self.topBox.Add(self.sizer_mainbttns, 0, wxALIGN_RIGHT|wxBOTTOM, 0)
633 jonathan 730
634 jonathan 717 self.SetAutoLayout(1)
635     self.SetSizer(self.topBox)
636     self.topBox.Fit(self)
637     self.topBox.SetSizeHints(self)
638     self.Layout()
639    
640     # end of class ProjFrame
641    
642    
643     class ProjPanel(wxPanel):
644     """Base class for all projection panels."""
645    
646     def __init__(self, parent):
647     wxPanel.__init__(self, parent, -1)
648    
649     self.__ellps = wxChoice(self, -1)
650 jonathan 816 self.ellpsData = [("airy" , _("Airy")),
651     ("bessel", _("Bessel 1841")),
652 jonathan 717 ("clrk66", _("Clarke 1866")),
653     ("clrk80", _("Clarke 1880")),
654     ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
655     ("intl" , _("International 1909 (Hayford)")),
656     ("WGS84" , _("WGS 84"))]
657    
658     for tag, name in self.ellpsData:
659     self.__ellps.Append(name, tag)
660    
661     self.__ellps.SetSelection(0)
662    
663     def _DoLayout(self, childPanel = None):
664    
665     panelSizer = wxBoxSizer(wxVERTICAL)
666    
667     sizer = wxBoxSizer(wxHORIZONTAL)
668 frank 976 sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,
669     wxALL|wxALIGN_CENTER_VERTICAL, 4)
670 frank 1034 sizer.Add(self.__ellps, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
671 jonathan 717 panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
672    
673 frank 976 if childPanel is not None:
674     panelSizer.Add(childPanel, 0, wxEXPAND, 0)
675    
676 jonathan 717 self.SetAutoLayout(1)
677     self.SetSizer(panelSizer)
678     panelSizer.Fit(self)
679     panelSizer.SetSizeHints(self)
680     self.Layout()
681    
682     def SetProjection(self, proj):
683     if proj is not None:
684     param = proj.GetParameter("ellps")
685     i = 0
686     for tag, name in self.ellpsData:
687     if param == tag:
688     self.__ellps.SetSelection(i)
689     return # returning early!
690     i += 1
691    
692     #
693     # if proj is none, or the parameter couldn't be found...
694     #
695     self.__ellps.SetSelection(0)
696    
697     def GetParameters(self):
698     return ["ellps=" + self.__ellps.GetClientData(
699     self.__ellps.GetSelection())]
700    
701    
702     ID_TMPANEL_LAT = 4001
703     ID_TMPANEL_LONG = 4002
704     ID_TMPANEL_FASLE_EAST = 4003
705     ID_TMPANEL_FALSE_NORTH = 4004
706     ID_TMPANEL_SCALE = 4005
707    
708     class UnknownProjPanel(ProjPanel):
709 bh 1789
710     """Panel for unknown projection types"""
711    
712 jonathan 730 def __init__(self, parent, receiver):
713 jonathan 717 ProjPanel.__init__(self, parent)
714    
715     self._DoLayout()
716    
717     def _DoLayout(self):
718     sizer = wxBoxSizer(wxVERTICAL)
719    
720 bh 1579 sizer.Add(wxStaticText(self, -1,
721     _("Thuban does not know the parameters for the"
722 bh 1789 " current projection\n"
723     "and cannot display a configuration panel.")))
724 jonathan 717
725     ProjPanel._DoLayout(self, sizer)
726    
727     def GetProjName(self):
728     return "Unknown"
729    
730     def SetProjection(self, proj):
731     pass
732    
733     def GetParameters(self):
734     return None
735    
736     class TMPanel(ProjPanel):
737 jonathan 730 """Projection panel for Transverse Mercator."""
738 jonathan 717
739 jonathan 730 def __init__(self, parent, receiver):
740 jonathan 717 ProjPanel.__init__(self, parent)
741    
742     self.__latitude = wxTextCtrl(self, ID_TMPANEL_LAT)
743     self.__longitude = wxTextCtrl(self, ID_TMPANEL_LONG)
744 frank 976 self.__scale = wxTextCtrl(self, ID_TMPANEL_SCALE)
745 jonathan 717 self.__falseEast = wxTextCtrl(self, ID_TMPANEL_FASLE_EAST)
746     self.__falseNorth = wxTextCtrl(self, ID_TMPANEL_FALSE_NORTH)
747    
748     self._DoLayout()
749    
750     def _DoLayout(self):
751    
752     sizer = wxFlexGridSizer(4, 4, 0, 0)
753     sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
754     sizer.Add(self.__latitude, 0, wxALL, 4)
755     sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
756     sizer.Add(self.__falseEast, 0, wxALL, 4)
757     sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
758     sizer.Add(self.__longitude, 0, wxALL, 4)
759     sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
760     sizer.Add(self.__falseNorth, 0, wxALL, 4)
761     sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)
762     sizer.Add(self.__scale, 0, wxALL, 4)
763    
764     ProjPanel._DoLayout(self, sizer)
765    
766     def GetProjName(self):
767 jonathan 730 return _("Transverse Mercator")
768 jonathan 717
769     def SetProjection(self, proj):
770     ProjPanel.SetProjection(self, proj)
771    
772     self.__latitude.SetValue(proj.GetParameter("lat_0"))
773     self.__longitude.SetValue(proj.GetParameter("lon_0"))
774     self.__falseEast.SetValue(proj.GetParameter("x_0"))
775     self.__falseNorth.SetValue(proj.GetParameter("y_0"))
776     self.__scale.SetValue(proj.GetParameter("k"))
777    
778     ProjPanel.SetProjection(self, proj)
779    
780     def GetParameters(self):
781     params = ["proj=tmerc",
782     "lat_0=" + self.__latitude.GetValue(),
783     "lon_0=" + self.__longitude.GetValue(),
784     "x_0=" + self.__falseEast.GetValue(),
785     "y_0=" + self.__falseNorth.GetValue(),
786     "k=" + self.__scale.GetValue()]
787     params.extend(ProjPanel.GetParameters(self))
788     return params
789    
790     def Clear(self):
791     self.__latitude.Clear()
792     self.__longitude.Clear()
793     self.__falseEast.Clear()
794     self.__falseNorth.Clear()
795     self.__scale.Clear()
796    
797     ProjPanel.Clear(self)
798    
799     ID_UTMPANEL_ZONE = 4001
800     ID_UTMPANEL_SOUTH = 4002
801     ID_UTMPANEL_PROP = 4003
802    
803     class UTMPanel(ProjPanel):
804 jonathan 730 """Projection Panel for Universal Transverse Mercator."""
805 jonathan 717
806 jonathan 730 def __init__(self, parent, receiver):
807 jonathan 717 ProjPanel.__init__(self, parent)
808    
809 jonathan 730 self.receiver = receiver
810 jonathan 717
811     self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
812 jonathan 816 self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))
813 jonathan 717 self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,
814     _("Southern Hemisphere"))
815    
816     self._DoLayout()
817    
818     EVT_BUTTON(self, ID_UTMPANEL_PROP, self._OnPropose)
819    
820     def _DoLayout(self):
821    
822     sizer = wxBoxSizer(wxVERTICAL)
823     psizer = wxBoxSizer(wxHORIZONTAL)
824     psizer.Add(wxStaticText(self, -1, _("Zone:")), 0, wxALL, 4)
825     psizer.Add(self.__zone, 0, wxALL, 4)
826     psizer.Add(self.__propButton, 0, wxALL, 4)
827     sizer.Add(psizer, 0, wxALL, 4)
828     sizer.Add(self.__south, 0, wxALL, 4)
829    
830     ProjPanel._DoLayout(self, sizer)
831    
832     def GetProjName(self):
833 jonathan 730 return _("Universal Transverse Mercator")
834 jonathan 717
835     def SetProjection(self, proj):
836     self.__zone.SetValue(int(proj.GetParameter("zone")))
837     self.__south.SetValue(proj.GetParameter("south") != "")
838     ProjPanel.SetProjection(self, proj)
839    
840     def GetParameters(self):
841     params = ["proj=utm", "zone=" + str(self.__zone.GetValue())]
842     if self.__south.IsChecked():
843     params.append("south")
844    
845     params.extend(ProjPanel.GetParameters(self))
846     return params
847    
848     def Clear(self):
849     self.__zone.SetValue(1)
850     self.__south.SetValue(False)
851     ProjPanel.Clear(self)
852    
853     def _OnPropose(self, event):
854 jan 1549 """Call the propose dialog.
855     If the receiver (e.g. the current map) has no bounding box,
856     inform the user accordingly.
857     """
858     bb = self.receiver.BoundingBox()
859     if bb is None:
860     dlg = wxMessageDialog(self,
861     _("Can not propose: No bounding box found."),
862     _("Projection: Propose UTM Zone"),
863     wxOK | wxICON_INFORMATION)
864     dlg.CenterOnParent()
865     result = dlg.ShowModal()
866     dlg.Destroy()
867     return
868    
869 jonathan 730 dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
870 jonathan 717 if dlg.ShowModal() == wxID_OK:
871     self.__zone.SetValue(dlg.GetProposedZone())
872    
873     class LCCPanel(ProjPanel):
874     """Projection Panel for Lambert Conic Conformal."""
875    
876 jonathan 730 def __init__(self, parent, receiver):
877 jonathan 717 ProjPanel.__init__(self, parent)
878    
879     self.__fspLatitude = wxTextCtrl(self, -1)
880     self.__sspLatitude = wxTextCtrl(self, -1)
881     self.__originLat = wxTextCtrl(self, -1)
882     self.__meridian = wxTextCtrl(self, -1)
883     self.__falseEast = wxTextCtrl(self, -1)
884     self.__falseNorth = wxTextCtrl(self, -1)
885    
886     self._DoLayout()
887    
888     def _DoLayout(self):
889    
890     sizer = wxFlexGridSizer(6, 2, 0, 0)
891     sizer.Add(wxStaticText(self, -1,
892     _("Latitude of first standard parallel:")))
893     sizer.Add(self.__fspLatitude, 0, wxALL, 4)
894     sizer.Add(wxStaticText(self, -1,
895     _("Latitude of second standard parallel:")))
896     sizer.Add(self.__sspLatitude, 0, wxALL, 4)
897 frank 1135 sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
898     sizer.Add(self.__meridian, 0, wxALL, 4)
899 jonathan 717 sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
900     sizer.Add(self.__originLat, 0, wxALL, 4)
901     sizer.Add(wxStaticText(self, -1, _("False Easting:")))
902     sizer.Add(self.__falseEast, 0, wxALL, 4)
903     sizer.Add(wxStaticText(self, -1, _("False Northing:")))
904     sizer.Add(self.__falseNorth, 0, wxALL, 4)
905    
906     ProjPanel._DoLayout(self, sizer)
907    
908     def GetProjName(self):
909     return _("Lambert Conic Conformal")
910    
911     def SetProjection(self, proj):
912     self.__fspLatitude.SetValue(proj.GetParameter("lat_1"))
913     self.__sspLatitude.SetValue(proj.GetParameter("lat_2"))
914     self.__originLat.SetValue(proj.GetParameter("lat_0"))
915     self.__meridian.SetValue(proj.GetParameter("lon_0"))
916     self.__falseEast.SetValue(proj.GetParameter("x_0"))
917     self.__falseNorth.SetValue(proj.GetParameter("y_0"))
918    
919     ProjPanel.SetProjection(self, proj)
920    
921     def GetParameters(self):
922     params = ["proj=lcc",
923     "lat_1=" + self.__fspLatitude.GetValue(),
924     "lat_2=" + self.__sspLatitude.GetValue(),
925     "lat_0=" + self.__originLat.GetValue(),
926     "lon_0=" + self.__meridian.GetValue(),
927     "x_0=" + self.__falseEast.GetValue(),
928     "y_0=" + self.__falseNorth.GetValue()]
929    
930     params.extend(ProjPanel.GetParameters(self))
931     return params
932    
933     def Clear(self):
934     self.__fspLatitude.Clear()
935     self.__sspLatitude.Clear()
936     self.__originLat.Clear()
937     self.__meridian.Clear()
938     self.__falseEast.Clear()
939     self.__falseNorth.Clear()
940    
941     ProjPanel.Clear(self)
942    
943     class GeoPanel(ProjPanel):
944     """Projection Panel for a Geographic Projection."""
945    
946 jonathan 730 def __init__(self, parent, receiver):
947 jonathan 717 ProjPanel.__init__(self, parent)
948    
949 jonathan 964 self.__choices = [(_("Degrees"), "0.017453"),
950     (_("Radians"), "1")]
951 jonathan 797
952     self.__scale = wxChoice(self, -1)
953     for choice, value in self.__choices:
954     self.__scale.Append(choice, value)
955    
956     self._DoLayout()
957    
958 jonathan 717 def GetProjName(self):
959     return _("Geographic")
960    
961     def SetProjection(self, proj):
962 jonathan 797 value = proj.GetParameter("to_meter")
963     for i in range(len(self.__choices)):
964     choice, data = self.__choices[i]
965     if value == data:
966     self.__scale.SetSelection(i)
967 jonathan 717 ProjPanel.SetProjection(self, proj)
968    
969     def GetParameters(self):
970 jonathan 797 params = ["proj=latlong",
971     "to_meter=%s" % self.__scale.GetClientData(
972     self.__scale.GetSelection())]
973    
974 jonathan 717 params.extend(ProjPanel.GetParameters(self))
975     return params
976    
977     def Clear(self):
978     ProjPanel.Clear(self)
979    
980 jonathan 797 def _DoLayout(self):
981     sizer = wxBoxSizer(wxHORIZONTAL)
982 jonathan 717
983 jonathan 797 sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
984 frank 976 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
985 jonathan 797 sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
986    
987     self.__scale.SetSelection(0)
988    
989     ProjPanel._DoLayout(self, sizer)
990    
991    
992 jonathan 717 ID_UTM_PROPOSE_ZONE_DIALOG_TAKE = 4001
993     ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
994     class UTMProposeZoneDialog(wxDialog):
995 bh 1566
996 jonathan 717 """Propose a sensible Zone considering the current map extent."""
997 bh 1566
998 jonathan 717 def __init__(self, parent, (x, y, x2, y2)):
999     wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
1000     wxDefaultPosition, wxSize(200, 100))
1001     self.parent = parent
1002     x = x + 180
1003     x2 = x2 + 180
1004     center = (x2 - x) / 2 + x
1005     self.proposedZone = int(center / 6 + 1)
1006     self.dialogLayout()
1007 bh 1566
1008 jonathan 717 def dialogLayout(self):
1009     topBox = wxBoxSizer(wxVERTICAL)
1010 bh 1566
1011 jonathan 717 textBox = wxBoxSizer(wxVERTICAL)
1012 bh 1566 textBox.Add(wxStaticText(self, -1, _("The current map extent center "
1013     "lies in UTM Zone")),
1014 jonathan 717 0, wxALIGN_CENTER|wxALL, 4)
1015     textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
1016     0, wxALIGN_CENTER|wxALL, 4)
1017 bh 1566
1018 jonathan 717 topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
1019 bh 1566
1020 jonathan 717 buttonBox = wxBoxSizer(wxHORIZONTAL)
1021     buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
1022     _("Take")), 0, wxALL, 4)
1023     buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL,
1024     _("Cancel")), 0, wxALL, 4)
1025     topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
1026     EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
1027     EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
1028 bh 1566
1029 jonathan 717 self.SetAutoLayout(True)
1030     self.SetSizer(topBox)
1031     topBox.Fit(self)
1032     topBox.SetSizeHints(self)
1033 bh 1566
1034 jonathan 717 def OnTake(self, event):
1035     self.EndModal(wxID_OK)
1036 bh 1566
1037 jonathan 717 def OnCancel(self, event):
1038     self.EndModal(wxID_CANCEL)
1039    
1040     def GetProposedZone(self):
1041     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