/[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 1190 - (hide annotations)
Thu Jun 12 17:01:37 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 35029 byte(s)
(ProjFrame.__DoOnProjAvail): Clear
        the projfilepath if no projection is selected.

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