/[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 1542 - (hide annotations)
Fri Aug 1 16:13:49 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 35020 byte(s)
Insert cvs keywords and doc-strings.

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