/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/projdialog.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/projdialog.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1167 - (show annotations)
Thu Jun 12 12:42:34 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/projdialog.py
File MIME type: text/x-python
File size: 34885 byte(s)
Use renamed projection resource functions.

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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26