/[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 797 - (hide annotations)
Wed Apr 30 17:01:48 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: 33760 byte(s)
(ProjFrame._OnSave): Add missing parameter in call to SetClientData.
(GeoPanel): Add support for selecting the units that the
        source data is in (Radians or Degrees).

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