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