/[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 816 - (hide annotations)
Mon May 5 15:05:16 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 34180 byte(s)
(ProjFrame.__init__): Rearrange the
        order that the controls are created so that tabbing works correctly.
(ProjFrame.OnApply): Renamed from _OnTry() to use wxDialog behaviour.
(ProjFrame.OnOK): Renamed from _OnOK() to use wxDialog behaviour.
(ProjFrame.OnCancel): Renamed from _OnClose() to use wxDialog behaviour.        (ProjPanel.__init__): Add "Airy" to the list of ellipsoids so we
        can provide the "UK National Grid" as a default projection.
(UTMPanel.__init__): Rearrange the order that the controls are
        created so that tabbing works correctly.

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