/[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 760 - (show annotations)
Tue Apr 29 09:01:52 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: 32888 byte(s)
(ProjFrame._OnSave): Use the new
        ProjFile.Replace() method instead of the mutator
        Projection.SetProjection(). Also requires that we reassign the
        client data to the new projection.

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 projfile.Replace(proj, newproj)
155 try:
156 WriteProjFile(projfile)
157 except IOError, (errno, errstr):
158 self.__ShowError(projfile.GetFilename(), errstr)
159 self.availprojs.SetClientData([newproj, projfile])
160
161 def _OnAddToList(self, event):
162
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 self.__ShowError(self.__userProjFile.GetFilename(), errstr)
170
171 self.__FillAvailList()
172
173 def _OnProjAvail(self, event):
174 self.__DoOnProjAvail()
175
176 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 self.__ShowError(dlg.GetPath(), errstr)
190
191 self.__FillAvailList()
192
193 dlg.Destroy()
194
195 def _OnExport(self, event):
196
197 sel = self.availprojs.GetSelections()
198 assert len(sel) != 0, "button should be disabled"
199
200 dlg = wxFileDialog(self, _("Export"),
201 style = wxSAVE|wxOVERWRITE_PROMPT)
202
203 if dlg.ShowModal() == wxID_OK:
204 path = dlg.GetPath()
205
206 projFile = ProjFile(path)
207
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 try:
214 WriteProjFile(projFile)
215 except IOError, (errno, errstr):
216 self.__ShowError(dlg.GetPath(), errstr)
217
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 self.__ShowError(projfile.GetFilename(), errstr)
252
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 self.__VerifyButtons()
264
265 def _OnProjName(self, event):
266 self.__VerifyButtons()
267
268 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 def __VerifyButtons(self):
275 """Enable or disable the appropriate buttons based on the
276 current state of the dialog.
277 """
278
279 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 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 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 # <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 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 def __DoOnProjAvail(self):
336
337 sel = self.availprojs.GetSelections()
338 if len(sel) == 1:
339
340 proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]
341 projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]
342
343 if proj is None:
344 # user selected <None>
345 self.projname.Clear()
346
347 else:
348
349 if projfile is not None:
350 self.projfilepath.SetLabel(projfile.GetFilename())
351 else:
352 # only None if the currently used projection is selected
353 self.projfilepath.SetLabel("")
354
355 self.projname.SetValue(proj.GetName())
356
357 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
364 #
365 # self.curProjPanel should not be null
366 # after a call to __DoOnProjChoice
367 #
368 assert self.curProjPanel is not None
369
370 self.curProjPanel.SetProjection(proj)
371 i += 1
372
373 self.__VerifyButtons()
374
375 def _OnProjChoice(self, event):
376 self.__DoOnProjChoice()
377
378 def __DoOnProjChoice(self):
379 """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 choice = self.projchoice
390
391 sel = choice.GetSelection()
392 if sel != -1:
393
394 clazz, obj = choice.GetClientData(sel)
395
396 if obj is None:
397 obj = clazz(self.panel_edit, self.receiver)
398 choice.SetClientData(sel, [clazz, obj])
399
400 if self.curProjPanel is not None:
401 self.curProjPanel.Hide()
402 self.sizer_projctrls.Remove(self.curProjPanel)
403
404 self.curProjPanel = obj
405 self.curProjPanel.Show()
406
407 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
413 def __SetProjection(self):
414 """Set the receiver's projection."""
415
416 #
417 # save the original projection only once in case
418 # we try to apply several different projections
419 #
420 self.receiver.SetProjection(self.__GetProjection())
421
422 def __GetProjection(self):
423 """Return a suitable Projection object based on the current
424 state of the dialog box selections.
425
426 Could be None.
427 """
428
429 sel = self.availprojs.GetSelections()
430 assert len(sel) < 2, "button should be disabled"
431
432
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 if self.curProjPanel is not None:
444 return Projection(self.curProjPanel.GetParameters(),
445 self.projname.GetValue())
446
447 return None
448
449 def __FillAvailList(self, selectCurrent = False):
450 """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 self.availprojs.Clear()
457
458 #
459 # 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 # 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 # 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
484 projfile = GetSystemProjFiles()
485 projfile = projfile[0]
486 for proj in projfile.GetProjections():
487 self.availprojs.Append(proj.GetName(), [proj, projfile])
488 self.__sysProjFile = projfile
489
490 projfile = GetUserProjFiles()
491 projfile = projfile[0]
492 for proj in projfile.GetProjections():
493 self.availprojs.Append(proj.GetName(), [proj, projfile])
494 self.__usrProjFile = projfile
495
496 for proj, name, clazz in self.projPanels:
497 self.projchoice.Append(name, [clazz, None])
498
499 def __set_properties(self):
500
501 #self.availprojs.SetSelection(0)
502 self.projchoice.SetSelection(0)
503
504 self.__FillAvailList(selectCurrent = True)
505
506 self.projname.SetMaxLength(32)
507
508 def __do_layout(self):
509 # originally generated by wxGlade
510
511 self.topBox = wxBoxSizer(wxVERTICAL)
512 self.sizer_panel = wxBoxSizer(wxVERTICAL)
513 sizer_6 = wxBoxSizer(wxHORIZONTAL)
514 self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)
515 self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)
516 sizer_11 = wxBoxSizer(wxVERTICAL)
517 self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
518 sizer_14 = wxBoxSizer(wxHORIZONTAL)
519 sizer_13 = wxBoxSizer(wxHORIZONTAL)
520 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 grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)
529 grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)
530 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 grid_sizer_1.AddGrowableRow(1)
534 grid_sizer_1.AddGrowableCol(0)
535
536 # edit controls
537 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 sizer_14.Add(self.projchoice, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
542 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 sizer_11.Add(self.button_save, 0, wxALL|wxEXPAND, 4)
546 sizer_11.Add(self.button_add, 0, wxALL|wxEXPAND, 4)
547 self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)
548
549 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
559 self.panel_1.SetAutoLayout(1)
560 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 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 panelSizer.Add(childPanel, 0, wxALL|wxEXPAND, 4)
616
617 sizer = wxBoxSizer(wxHORIZONTAL)
618 sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)
619 sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
620 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 def __init__(self, parent, receiver):
656 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 """Projection panel for Transverse Mercator."""
681
682 def __init__(self, parent, receiver):
683 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 return _("Transverse Mercator")
711
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 """Projection Panel for Universal Transverse Mercator."""
748
749 def __init__(self, parent, receiver):
750 ProjPanel.__init__(self, parent)
751
752 self.receiver = receiver
753
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 return _("Universal Transverse Mercator")
777
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 dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
799 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 def __init__(self, parent, receiver):
806 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 def __init__(self, parent, receiver):
876 ProjPanel.__init__(self, parent)
877 ProjPanel._DoLayout(self, None)
878
879 def GetProjName(self):
880 return _("Geographic")
881
882 def SetProjection(self, proj):
883 ProjPanel.SetProjection(self, proj)
884
885 def GetParameters(self):
886 params = ["proj=latlong"]
887 params.extend(ProjPanel.GetParameters(self))
888 return params
889
890 def Clear(self):
891 ProjPanel.Clear(self)
892
893
894 ID_UTM_PROPOSE_ZONE_DIALOG_TAKE = 4001
895 ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
896 class UTMProposeZoneDialog(wxDialog):
897
898 """Propose a sensible Zone considering the current map extent."""
899
900 def __init__(self, parent, (x, y, x2, y2)):
901 wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
902 wxDefaultPosition, wxSize(200, 100))
903 self.parent = parent
904 #x, y, x2, y2 = elf.parent.parent.map_bounding_box
905 x = x + 180
906 x2 = x2 + 180
907 center = (x2 - x) / 2 + x
908 self.proposedZone = int(center / 6 + 1)
909 self.dialogLayout()
910
911 def dialogLayout(self):
912 topBox = wxBoxSizer(wxVERTICAL)
913
914 textBox = wxBoxSizer(wxVERTICAL)
915 textBox.Add(wxStaticText(self, -1, _("The current map extent center " +
916 "lies in UTM Zone")),
917 0, wxALIGN_CENTER|wxALL, 4)
918 textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
919 0, wxALIGN_CENTER|wxALL, 4)
920
921 topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
922
923 buttonBox = wxBoxSizer(wxHORIZONTAL)
924 buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
925 _("Take")), 0, wxALL, 4)
926 buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL,
927 _("Cancel")), 0, wxALL, 4)
928 topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
929 EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
930 EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
931
932 self.SetAutoLayout(True)
933 self.SetSizer(topBox)
934 topBox.Fit(self)
935 topBox.SetSizeHints(self)
936
937 def OnTake(self, event):
938 self.EndModal(wxID_OK)
939
940 def OnCancel(self, event):
941 self.EndModal(wxID_CANCEL)
942
943 def GetProposedZone(self):
944 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