1 |
bh |
6 |
# Copyright (c) 2001 by Intevation GmbH |
2 |
|
|
# Authors: |
3 |
|
|
# Frank Koormann <[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 |
|
|
""" |
9 |
jan |
112 |
Dialogs to the geographic projection library PROJ |
10 |
bh |
6 |
""" |
11 |
|
|
|
12 |
|
|
__version__ = "$Revision$" |
13 |
|
|
|
14 |
|
|
from wxPython.wx import * |
15 |
|
|
from string import split |
16 |
|
|
|
17 |
jan |
374 |
from Thuban import _ |
18 |
|
|
|
19 |
bh |
6 |
ID_PROJECTION_EDIT = 4010 |
20 |
|
|
ID_PROJECTION_SELECT = 4011 |
21 |
|
|
ID_PROJECTION_OK = 4001 |
22 |
|
|
ID_PROJECTION_CANCEL = 4002 |
23 |
|
|
|
24 |
jan |
112 |
ID_UTM_DIALOG_OK = 4101 |
25 |
|
|
ID_UTM_DIALOG_CANCEL = 4102 |
26 |
|
|
ID_UTM_DIALOG_PROPOSE_ZONE = 4103 |
27 |
bh |
6 |
|
28 |
jan |
112 |
ID_UTM_PROPOSE_ZONE_DIALOG_TAKE = 4201 |
29 |
|
|
ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4202 |
30 |
|
|
|
31 |
bh |
6 |
projectionDict = {'None' : 'None', 'UTM' : 'utm'} |
32 |
|
|
projectionMapping = {'None' : 'None', 'utm' : 'UTM'} |
33 |
|
|
|
34 |
|
|
class Proj4Dialog(wxDialog): |
35 |
|
|
|
36 |
|
|
"""Let the user select a projection and specify related parameters""" |
37 |
|
|
|
38 |
jan |
112 |
def __init__(self, parent, projectionParamsList, map_bounding_box): |
39 |
jan |
374 |
wxDialog.__init__(self, parent, -1, _("Projection"), |
40 |
jonathan |
508 |
style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) |
41 |
bh |
6 |
|
42 |
jan |
112 |
self.map_bounding_box = map_bounding_box |
43 |
bh |
6 |
self.dialogLayout() |
44 |
|
|
self.projectionParams={} |
45 |
bh |
65 |
combo = self.projection |
46 |
bh |
6 |
if projectionParamsList is not None: |
47 |
|
|
for element in projectionParamsList: |
48 |
|
|
key, val = split(element,'=') |
49 |
|
|
self.projectionParams[key] = val |
50 |
|
|
if self.projectionParams.has_key('proj'): |
51 |
bh |
65 |
proj = projectionMapping[self.projectionParams['proj']] |
52 |
|
|
combo.SetSelection(combo.FindString(proj)) |
53 |
bh |
6 |
else: |
54 |
bh |
65 |
combo.SetSelection(combo.FindString('None')) |
55 |
bh |
6 |
self.UpdateProjectionInfo() |
56 |
|
|
else: |
57 |
|
|
self.projection.SetValue('None') |
58 |
|
|
self.UpdateProjectionInfo() |
59 |
|
|
|
60 |
|
|
|
61 |
|
|
def dialogLayout(self): |
62 |
|
|
topBox = wxBoxSizer(wxVERTICAL) |
63 |
|
|
|
64 |
|
|
# Projection selection: |
65 |
|
|
projectionBox = wxBoxSizer(wxHORIZONTAL) |
66 |
jan |
374 |
projectionBox.Add(wxStaticText(self, -1, _("Projection")), |
67 |
bh |
6 |
0, wxALIGN_CENTER|wxALL, 4) |
68 |
|
|
|
69 |
|
|
self.projection = wxComboBox(self, ID_PROJECTION_SELECT, "", |
70 |
|
|
style = wxCB_READONLY) |
71 |
|
|
for projection in projectionDict.keys(): |
72 |
|
|
self.projection.Append(projection) |
73 |
|
|
projectionBox.Add(self.projection, 0, wxALL, 4) |
74 |
jan |
374 |
projectionBox.Add(wxButton(self, ID_PROJECTION_EDIT, _("Edit")), |
75 |
bh |
6 |
0, wxALL, 4) |
76 |
|
|
EVT_COMBOBOX(self, ID_PROJECTION_SELECT, self.OnProj4Select) |
77 |
|
|
EVT_BUTTON(self, ID_PROJECTION_EDIT, self.OnEdit) |
78 |
|
|
|
79 |
|
|
topBox.Add(projectionBox, 0, 0) |
80 |
|
|
|
81 |
|
|
# Info about current projection: |
82 |
|
|
self.projectionInfo = wxTextCtrl(self, -1, "", |
83 |
bh |
47 |
style = wxTE_MULTILINE|wxTE_READONLY, |
84 |
|
|
size = (-1, 60)) |
85 |
bh |
6 |
topBox.Add(self.projectionInfo,1,wxEXPAND|wxALL, 4) |
86 |
|
|
|
87 |
|
|
# Control buttons: |
88 |
|
|
buttonBox = wxBoxSizer( wxHORIZONTAL ) |
89 |
jan |
374 |
buttonBox.Add(wxButton(self, ID_PROJECTION_OK, _("OK")), |
90 |
bh |
6 |
0, wxALL, 4) |
91 |
jan |
374 |
buttonBox.Add(wxButton(self, ID_PROJECTION_CANCEL, _("Cancel")), |
92 |
bh |
6 |
0, wxALL, 4) |
93 |
|
|
topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10) |
94 |
|
|
|
95 |
|
|
EVT_BUTTON(self, ID_PROJECTION_OK, self.OnProj4OK) |
96 |
|
|
EVT_BUTTON(self, ID_PROJECTION_CANCEL, self.OnProj4Cancel) |
97 |
|
|
|
98 |
jan |
1035 |
self.SetAutoLayout(True) |
99 |
bh |
6 |
self.SetSizer(topBox) |
100 |
bh |
47 |
topBox.Fit(self) |
101 |
|
|
topBox.SetSizeHints(self) |
102 |
bh |
6 |
|
103 |
|
|
def OnProj4Select(self, event): |
104 |
|
|
projection = self.projection.GetStringSelection() |
105 |
|
|
if projection == 'None': |
106 |
|
|
self.projectionParams = {} |
107 |
|
|
self.UpdateProjectionInfo() |
108 |
|
|
|
109 |
|
|
def OnEdit(self, event): |
110 |
|
|
projection = self.projection.GetStringSelection() |
111 |
|
|
if projection is not 'None': |
112 |
|
|
dialogname = getattr(self, 'launch' + projection + 'Dialog', None) |
113 |
|
|
if dialogname is not None: |
114 |
|
|
if dialogname(self): |
115 |
|
|
self.UpdateProjectionInfo() |
116 |
|
|
else: |
117 |
|
|
pass |
118 |
|
|
else: |
119 |
|
|
self.projectionParams = {} |
120 |
|
|
|
121 |
|
|
def UpdateProjectionInfo(self): |
122 |
|
|
self.projectionInfo.Clear() |
123 |
|
|
for key in self.projectionParams.keys(): |
124 |
|
|
self.projectionInfo.AppendText(key+": " |
125 |
|
|
+str(self.projectionParams[key])+"\n") |
126 |
|
|
|
127 |
|
|
|
128 |
|
|
def OnProj4OK(self, event): |
129 |
|
|
self.EndModal(wxID_OK) |
130 |
|
|
|
131 |
|
|
def OnProj4Cancel(self, event): |
132 |
|
|
self.EndModal(wxID_CANCEL) |
133 |
|
|
|
134 |
|
|
def launchUTMDialog(self, parent): |
135 |
|
|
dlg = UTMDialog(parent, parent.projectionInfo ) |
136 |
|
|
if dlg.ShowModal(): |
137 |
jan |
1035 |
return True |
138 |
bh |
6 |
else: |
139 |
jan |
1035 |
return False |
140 |
bh |
6 |
|
141 |
|
|
def GetParams(self): |
142 |
|
|
if len(self.projectionParams.keys()) > 0: |
143 |
|
|
projection = [] |
144 |
|
|
for key in self.projectionParams.keys(): |
145 |
|
|
projection.append(key+"="+str(self.projectionParams[key])) |
146 |
|
|
else: |
147 |
|
|
projection=None |
148 |
|
|
|
149 |
|
|
return projection |
150 |
|
|
|
151 |
|
|
|
152 |
|
|
|
153 |
|
|
class UTMDialog(wxDialog): |
154 |
|
|
|
155 |
|
|
"""Let the user specify parameters for UTM projection (Zone, Spheroid)""" |
156 |
|
|
|
157 |
|
|
def __init__(self, parent, projection): |
158 |
jan |
374 |
wxDialog.__init__(self, parent, -1, _("Projection: UTM Parameters"), |
159 |
bh |
6 |
wxDefaultPosition, wxSize(200, 100)) |
160 |
|
|
self.parent = parent |
161 |
|
|
self.dialogLayout() |
162 |
|
|
if self.parent.projectionParams.has_key('zone'): |
163 |
bh |
65 |
text = str(self.parent.projectionParams['zone']) |
164 |
|
|
self.zone.SetSelection(self.zone.FindString(text)) |
165 |
bh |
6 |
if self.parent.projectionParams.has_key('ellps'): |
166 |
bh |
65 |
text = str(self.parent.projectionParams['ellps']) |
167 |
|
|
self.ellps.SetSelection(self.ellps.FindString(text)) |
168 |
bh |
6 |
|
169 |
|
|
def dialogLayout(self): |
170 |
|
|
topBox = wxBoxSizer(wxVERTICAL) |
171 |
|
|
|
172 |
|
|
zoneBox = wxBoxSizer(wxHORIZONTAL) |
173 |
jan |
374 |
zoneBox.Add(wxStaticText(self, -1, _("UTM Zone")), |
174 |
bh |
6 |
0, wxALIGN_CENTER|wxALL, 4) |
175 |
|
|
self.zone = wxComboBox(self, -1, "", style = wxCB_READONLY) |
176 |
|
|
for zone in range(1,61): |
177 |
|
|
self.zone.Append(str(zone)) |
178 |
|
|
zoneBox.Add(self.zone, 0, wxALIGN_CENTER|wxALL, 4) |
179 |
jan |
374 |
zoneBox.Add(wxButton(self, ID_UTM_DIALOG_PROPOSE_ZONE, _("Propose")), |
180 |
jan |
112 |
0, wxALL, 4) |
181 |
|
|
EVT_BUTTON(self, ID_UTM_DIALOG_PROPOSE_ZONE, self.OnProposeZone) |
182 |
bh |
6 |
|
183 |
|
|
topBox.Add(zoneBox, 1, wxEXPAND|wxALL, 4) |
184 |
|
|
|
185 |
|
|
ellipsoidBox = wxBoxSizer(wxHORIZONTAL) |
186 |
jan |
374 |
ellipsoidBox.Add(wxStaticText(self, -1, _("Ellipsoid")), |
187 |
bh |
6 |
0, wxALIGN_CENTER|wxALL, 4) |
188 |
|
|
self.ellps = wxComboBox(self, -1, "", style = wxCB_READONLY) |
189 |
|
|
for ellps in ["clrk66", "GRS80"]: |
190 |
|
|
self.ellps.Append(ellps) |
191 |
|
|
ellipsoidBox.Add(self.ellps, 0, wxALIGN_CENTER|wxALL, 4) |
192 |
|
|
|
193 |
|
|
topBox.Add(ellipsoidBox, 1, wxEXPAND|wxALL, 4) |
194 |
|
|
|
195 |
|
|
buttonBox = wxBoxSizer(wxHORIZONTAL) |
196 |
jan |
374 |
buttonBox.Add(wxButton(self, ID_UTM_DIALOG_OK, _("OK")), |
197 |
bh |
6 |
0, wxALL, 4) |
198 |
jan |
374 |
buttonBox.Add(wxButton(self, ID_UTM_DIALOG_CANCEL, _("Cancel")), |
199 |
bh |
6 |
0, wxALL, 4) |
200 |
|
|
topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10) |
201 |
|
|
EVT_BUTTON(self, ID_UTM_DIALOG_OK, self.OnOK) |
202 |
|
|
EVT_BUTTON(self, ID_UTM_DIALOG_CANCEL, self.OnCancel) |
203 |
|
|
|
204 |
jan |
1035 |
self.SetAutoLayout(True) |
205 |
bh |
6 |
self.SetSizer(topBox) |
206 |
|
|
topBox.Fit(self) |
207 |
|
|
topBox.SetSizeHints(self) |
208 |
|
|
|
209 |
jan |
112 |
def OnProposeZone(self, event): |
210 |
|
|
dlg = UTMProposeZoneDialog(self) |
211 |
|
|
if dlg.ShowModal(): |
212 |
jan |
1035 |
return True |
213 |
jan |
112 |
else: |
214 |
jan |
1035 |
return False |
215 |
jan |
112 |
|
216 |
bh |
6 |
def OnOK(self, event): |
217 |
|
|
self.parent.projectionParams = {} |
218 |
|
|
self.parent.projectionParams['zone'] = self.zone.GetStringSelection() |
219 |
|
|
self.parent.projectionParams['ellps'] = self.ellps.GetStringSelection() |
220 |
|
|
self.parent.projectionParams['proj'] = "utm" |
221 |
jan |
1035 |
self.Close(True) |
222 |
bh |
6 |
|
223 |
|
|
def OnCancel(self, event): |
224 |
jan |
1035 |
self.Close(False) |
225 |
bh |
6 |
|
226 |
jan |
112 |
class UTMProposeZoneDialog(wxDialog): |
227 |
|
|
|
228 |
|
|
"""Propose a sensible Zone considering the current map extent.""" |
229 |
|
|
|
230 |
|
|
def __init__(self, parent): |
231 |
jan |
374 |
wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"), |
232 |
jan |
112 |
wxDefaultPosition, wxSize(200, 100)) |
233 |
|
|
self.parent = parent |
234 |
|
|
x, y, x2, y2 = self.parent.parent.map_bounding_box |
235 |
|
|
x = x + 180 |
236 |
|
|
x2 = x2 + 180 |
237 |
|
|
center = (x2 - x) / 2 + x |
238 |
|
|
self.proposedZone = str(int(center / 6 + 1)) |
239 |
|
|
self.dialogLayout() |
240 |
|
|
|
241 |
|
|
def dialogLayout(self): |
242 |
|
|
topBox = wxBoxSizer(wxVERTICAL) |
243 |
|
|
|
244 |
|
|
textBox = wxBoxSizer(wxVERTICAL) |
245 |
jan |
374 |
textBox.Add(wxStaticText(self, -1, _("The current map extent center " + |
246 |
|
|
"lies in UTM Zone")), |
247 |
jan |
112 |
0, wxALIGN_CENTER|wxALL, 4) |
248 |
|
|
textBox.Add(wxStaticText(self, -1, self.proposedZone), |
249 |
|
|
0, wxALIGN_CENTER|wxALL, 4) |
250 |
|
|
|
251 |
|
|
topBox.Add(textBox, 1, wxEXPAND|wxALL, 4) |
252 |
|
|
|
253 |
|
|
buttonBox = wxBoxSizer(wxHORIZONTAL) |
254 |
jan |
374 |
buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, |
255 |
|
|
_("Take")), 0, wxALL, 4) |
256 |
jan |
112 |
buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, |
257 |
jan |
374 |
_("Cancel")), 0, wxALL, 4) |
258 |
jan |
112 |
topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10) |
259 |
|
|
EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake) |
260 |
|
|
EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel) |
261 |
|
|
|
262 |
jan |
1035 |
self.SetAutoLayout(True) |
263 |
jan |
112 |
self.SetSizer(topBox) |
264 |
|
|
topBox.Fit(self) |
265 |
|
|
topBox.SetSizeHints(self) |
266 |
|
|
|
267 |
|
|
def OnTake(self, event): |
268 |
|
|
self.parent.zone.SetSelection(self.parent.zone.FindString(self.proposedZone)) |
269 |
jan |
1035 |
self.Close(True) |
270 |
jan |
112 |
|
271 |
|
|
def OnCancel(self, event): |
272 |
jan |
1035 |
self.Close(False) |