/[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 730 - (show annotations)
Thu Apr 24 16:07:41 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: 33812 byte(s)
Large changes to how the dialog is laid out. Use three panels instead of one.
        One for the list of projections, one for the edit controls, and one for
        the buttons.  Fixed resizing problems so that the dialog resizes
        correctly when the projection panel changes. Added import/export,
        save, and new buttons/functionality.

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