/[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 751 - (show 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 # 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 import os, sys
9 from wxPython.wx import *
10
11 from Thuban import _
12
13 from Thuban.Model.proj import Projection, ProjFile
14
15 from Thuban.Model.resource import GetUserProjFiles, GetSystemProjFiles, \
16 ReadProjFile, WriteProjFile
17 from Thuban.UI.dialogs import NonModalDialog
18
19
20 ID_PROJ_ADVANCED = 4001
21 ID_PROJ_PROJCHOICE = 4002
22 ID_PROJ_ADDTOLIST = 4003
23 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 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
35 CLIENT_PROJ = 0
36 CLIENT_PROJFILE = 1
37
38 class ProjFrame(NonModalDialog):
39
40 def __init__(self, parent, name, title, receiver):
41 """Initialize the projection dialog.
42
43 receiver -- An object that implements the following methods:
44 SetProjection(projection)
45 GetProjection()
46 """
47
48 self.receiver = receiver
49 self.haveTried = False
50 self.curProjPanel = None
51
52 self.projPanels = []
53 self.projPanels.append(
54 ("tmerc", _("Transverse Mercator"), TMPanel))
55 self.projPanels.append(
56 ("utm", _("Universal Transverse Mercator"), UTMPanel))
57 self.projPanels.append(
58 ("lcc", _("Lambert Conic Conformal"), LCCPanel))
59 self.projPanels.append(
60 ("latlong", _("Geographic"), GeoPanel))
61
62 NonModalDialog.__init__(self, parent, name, title)
63 # originally generate by wxGlade
64 self.panel_1 = wxPanel(self, -1)
65 self.panel_edit = wxPanel(self, -1)
66 self.panel_buttons = wxPanel(self, -1)
67 self.label_5 = wxStaticText(self.panel_1, -1, _("Available Projections:"))
68 self.availprojs = wxListBox(self.panel_1, ID_PROJ_AVAIL, style=wxLB_EXTENDED|wxLB_SORT)
69 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 self.button_add = wxButton(self.panel_edit, ID_PROJ_ADDTOLIST,
80 _("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
86 self.__set_properties()
87 self.__do_layout()
88 # wxGlade
89
90 self.originalProjection = self.receiver.GetProjection()
91
92 self.__DoOnProjAvail()
93
94 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 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
104 EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)
105 EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)
106 EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)
107
108 EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)
109
110 def _OnTry(self, event):
111 self.__SetProjection()
112 self.haveTried = True
113
114 def _OnRevert(self, event):
115 if self.haveTried:
116 self.receiver.SetProjection(self.originalProjection)
117 self.haveTried = False
118
119 def _OnOK(self, event):
120 self.__SetProjection()
121 self.Close()
122
123 def _OnClose(self, event):
124 self.Close()
125
126 def _OnNew(self, event):
127
128 # 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 def _OnSave(self, event):
143
144 sel = self.availprojs.GetSelections()
145 assert len(sel) == 1, "button shouldn't be enabled"
146
147 proj, projfile = self.availprojs.GetClientData(sel[0])
148
149 assert proj is not None and projfile is not None
150
151 newproj = self.__GetProjection()
152
153 if newproj is not None:
154 proj.SetProjection(newproj)
155 try:
156 WriteProjFile(projfile)
157 except IOError, (errno, errstr):
158 self.__ShowError(projfile.GetFilename(), errstr)
159
160 def _OnAddToList(self, event):
161
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 self.__ShowError(self.__userProjFile.GetFilename(), errstr)
169
170 self.__FillAvailList()
171
172 def _OnProjAvail(self, event):
173 self.__DoOnProjAvail()
174
175 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 self.__ShowError(dlg.GetPath(), errstr)
189
190 self.__FillAvailList()
191
192 dlg.Destroy()
193
194 def _OnExport(self, event):
195
196 sel = self.availprojs.GetSelections()
197 assert len(sel) != 0, "button should be disabled"
198
199 dlg = wxFileDialog(self, _("Export"),
200 style = wxSAVE|wxOVERWRITE_PROMPT)
201
202 if dlg.ShowModal() == wxID_OK:
203 path = dlg.GetPath()
204
205 projFile = ProjFile(path)
206
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 try:
213 WriteProjFile(projFile)
214 except IOError, (errno, errstr):
215 self.__ShowError(dlg.GetPath(), errstr)
216
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 self.__ShowError(projfile.GetFilename(), errstr)
251
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 self.__VerifyButtons()
263
264 def _OnProjName(self, event):
265 self.__VerifyButtons()
266
267 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 def __VerifyButtons(self):
274 """Enable or disable the appropriate buttons based on the
275 current state of the dialog.
276 """
277
278 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 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 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 # <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 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 def __DoOnProjAvail(self):
335
336 sel = self.availprojs.GetSelections()
337 if len(sel) == 1:
338
339 proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]
340 projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]
341
342 if proj is None:
343 # user selected <None>
344 self.projname.Clear()
345
346 else:
347
348 if projfile is not None:
349 self.projfilepath.SetLabel(projfile.GetFilename())
350 else:
351 # only None if the currently used projection is selected
352 self.projfilepath.SetLabel("")
353
354 self.projname.SetValue(proj.GetName())
355
356 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
363 #
364 # self.curProjPanel should not be null
365 # after a call to __DoOnProjChoice
366 #
367 assert self.curProjPanel is not None
368
369 self.curProjPanel.SetProjection(proj)
370 i += 1
371
372 self.__VerifyButtons()
373
374 def _OnProjChoice(self, event):
375 self.__DoOnProjChoice()
376
377 def __DoOnProjChoice(self):
378 """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 choice = self.projchoice
389
390 sel = choice.GetSelection()
391 if sel != -1:
392
393 clazz, obj = choice.GetClientData(sel)
394
395 if obj is None:
396 obj = clazz(self.panel_edit, self.receiver)
397 choice.SetClientData(sel, [clazz, obj])
398
399 if self.curProjPanel is not None:
400 self.curProjPanel.Hide()
401 self.sizer_projctrls.Remove(self.curProjPanel)
402
403 self.curProjPanel = obj
404 self.curProjPanel.Show()
405
406 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
412 def __SetProjection(self):
413 """Set the receiver's projection."""
414
415 #
416 # save the original projection only once in case
417 # we try to apply several different projections
418 #
419 self.receiver.SetProjection(self.__GetProjection())
420
421 def __GetProjection(self):
422 """Return a suitable Projection object based on the current
423 state of the dialog box selections.
424
425 Could be None.
426 """
427
428 sel = self.availprojs.GetSelections()
429 assert len(sel) < 2, "button should be disabled"
430
431
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 if self.curProjPanel is not None:
443 return Projection(self.curProjPanel.GetParameters(),
444 self.projname.GetValue())
445
446 return None
447
448 def __FillAvailList(self, selectCurrent = False):
449 """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 self.availprojs.Clear()
456
457 #
458 # 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 # 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 # 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
483 projfile = GetSystemProjFiles()
484 projfile = projfile[0]
485 for proj in projfile.GetProjections():
486 self.availprojs.Append(proj.GetName(), [proj, projfile])
487 self.__sysProjFile = projfile
488
489 projfile = GetUserProjFiles()
490 projfile = projfile[0]
491 for proj in projfile.GetProjections():
492 self.availprojs.Append(proj.GetName(), [proj, projfile])
493 self.__usrProjFile = projfile
494
495 for proj, name, clazz in self.projPanels:
496 self.projchoice.Append(name, [clazz, None])
497
498 def __set_properties(self):
499
500 self.availprojs.SetSelection(0)
501 self.projchoice.SetSelection(0)
502
503 self.__FillAvailList(selectCurrent = True)
504
505 self.projname.SetMaxLength(32)
506
507 def __do_layout(self):
508 # originally generated by wxGlade
509
510 self.topBox = wxBoxSizer(wxVERTICAL)
511 self.sizer_panel = wxBoxSizer(wxVERTICAL)
512 sizer_6 = wxBoxSizer(wxHORIZONTAL)
513 self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)
514 self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)
515 sizer_11 = wxBoxSizer(wxVERTICAL)
516 self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
517 sizer_14 = wxBoxSizer(wxHORIZONTAL)
518 sizer_13 = wxBoxSizer(wxHORIZONTAL)
519 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 grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)
528 grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)
529 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 grid_sizer_1.AddGrowableRow(1)
533 grid_sizer_1.AddGrowableCol(0)
534
535 # edit controls
536 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 sizer_14.Add(self.projchoice, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
541 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 sizer_11.Add(self.button_save, 0, wxALL|wxEXPAND, 4)
545 sizer_11.Add(self.button_add, 0, wxALL|wxEXPAND, 4)
546 self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)
547
548 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
558 self.panel_1.SetAutoLayout(1)
559 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 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 sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
619 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 def __init__(self, parent, receiver):
655 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 """Projection panel for Transverse Mercator."""
680
681 def __init__(self, parent, receiver):
682 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 return _("Transverse Mercator")
710
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 """Projection Panel for Universal Transverse Mercator."""
747
748 def __init__(self, parent, receiver):
749 ProjPanel.__init__(self, parent)
750
751 self.receiver = receiver
752
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 return _("Universal Transverse Mercator")
776
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 dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
798 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 def __init__(self, parent, receiver):
805 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 def __init__(self, parent, receiver):
875 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