/[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 1058 - (hide annotations)
Tue May 27 11:30:29 2003 UTC (21 years, 9 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 34337 byte(s)
Dialog derived from NonModalNonParentDialog

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