/[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 751 - (hide annotations)
Fri Apr 25 14:23:19 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: 32820 byte(s)
(ProjFrame.__ShowError): Consolidate error dialogs into a single method call.
(ProjFrame.__VerifyButtons): Add more states to check.
(ProjFrame.__GetProjection): Return the current state of an
        edited projection or None.
(ProjFrame.__FillAvailList): Remove checks for states that shouldn't exist.
(ProjFrame._OnNew): Clear all selected items and supply
        a projection panel if necessary.

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