/[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 1167 - (hide annotations)
Thu Jun 12 12:42:34 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: 34885 byte(s)
Use renamed projection resource functions.

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