1 /**********************************************************
2 * Version $Id: view_map_3d_panel.cpp 2064 2014-03-21 13:20:57Z oconrad $
3 *********************************************************/
4
5 ///////////////////////////////////////////////////////////
6 // //
7 // SAGA //
8 // //
9 // System for Automated Geoscientific Analyses //
10 // //
11 // User Interface //
12 // //
13 // Program: SAGA //
14 // //
15 //-------------------------------------------------------//
16 // //
17 // view_map_3d_panel.cpp //
18 // //
19 // Copyright (C) 2014 by Olaf Conrad //
20 // //
21 //-------------------------------------------------------//
22 // //
23 // This file is part of 'SAGA - System for Automated //
24 // Geoscientific Analyses'. SAGA is free software; you //
25 // can redistribute it and/or modify it under the terms //
26 // of the GNU General Public License as published by the //
27 // Free Software Foundation, either version 2 of the //
28 // License, or (at your option) any later version. //
29 // //
30 // SAGA is distributed in the hope that it will be //
31 // useful, but WITHOUT ANY WARRANTY; without even the //
32 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
33 // PARTICULAR PURPOSE. See the GNU General Public //
34 // License for more details. //
35 // //
36 // You should have received a copy of the GNU General //
37 // Public License along with this program; if not, see //
38 // <http://www.gnu.org/licenses/>. //
39 // //
40 //-------------------------------------------------------//
41 // //
42 // contact: Olaf Conrad //
43 // Institute of Geography //
44 // University of Hamburg //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
48 ///////////////////////////////////////////////////////////
49
50 //---------------------------------------------------------
51
52
53 ///////////////////////////////////////////////////////////
54 // //
55 // //
56 // //
57 ///////////////////////////////////////////////////////////
58
59 //---------------------------------------------------------
60 #include "wksp_map.h"
61
62 #include "view_map_3d.h"
63 #include "view_map_3d_panel.h"
64
65
66 ///////////////////////////////////////////////////////////
67 // //
68 // //
69 // //
70 ///////////////////////////////////////////////////////////
71
72 //---------------------------------------------------------
BEGIN_EVENT_TABLE(CVIEW_Map_3DPanel,CSG_3DView_Panel)73 BEGIN_EVENT_TABLE(CVIEW_Map_3DPanel, CSG_3DView_Panel)
74 EVT_KEY_DOWN (CVIEW_Map_3DPanel::On_Key_Down)
75 END_EVENT_TABLE()
76
77
78 ///////////////////////////////////////////////////////////
79 // //
80 // //
81 // //
82 ///////////////////////////////////////////////////////////
83
84 //---------------------------------------------------------
85 CVIEW_Map_3DPanel::CVIEW_Map_3DPanel(wxWindow *pParent, class CWKSP_Map *pMap)
86 : CSG_3DView_Panel(pParent, &m_Map)
87 {
88 m_pDEM = NULL;
89 m_pMap = pMap;
90
91 m_DEM_Res = 100;
92 m_Map_Res = 400;
93
94 m_Parameters("DRAW_BOX")->Set_Value(false);
95 }
96
97
98 ///////////////////////////////////////////////////////////
99 // //
100 ///////////////////////////////////////////////////////////
101
102 //---------------------------------------------------------
Update_Statistics(void)103 void CVIEW_Map_3DPanel::Update_Statistics(void)
104 {
105 //-----------------------------------------------------
106 CSG_Rect r(m_pDEM->Get_Extent());
107
108 if( !m_pMap || !r.Intersect(m_pMap->Get_Extent()) )
109 {
110 m_DEM.Destroy();
111
112 return;
113 }
114
115 //-----------------------------------------------------
116 double Cellsize = (r.Get_XRange() > r.Get_YRange() ? r.Get_XRange() : r.Get_YRange()) / m_DEM_Res;
117
118 if( Cellsize < m_pDEM->Get_Cellsize() )
119 Cellsize = m_pDEM->Get_Cellsize();
120
121 m_DEM.Create(CSG_Grid_System(Cellsize, r), SG_DATATYPE_Float);
122 m_DEM.Set_NoData_Value(m_pDEM->Get_NoData_Value());
123
124 for(int y=0; y<m_DEM.Get_NY(); y++)
125 {
126 double wy = m_DEM.Get_YMin() + y * m_DEM.Get_Cellsize();
127
128 for(int x=0; x<m_DEM.Get_NX(); x++)
129 {
130 double z, wx = m_DEM.Get_XMin() + x * m_DEM.Get_Cellsize();
131
132 if( m_pDEM->Get_Value(wx, wy, z) )
133 {
134 m_DEM.Set_Value(x, y, z);
135 }
136 else
137 {
138 m_DEM.Set_NoData(x, y);
139 }
140 }
141 }
142
143 m_Data_Min.x = m_DEM.Get_XMin(); m_Data_Max.x = m_DEM.Get_XMax();
144 m_Data_Min.y = m_DEM.Get_YMin(); m_Data_Max.y = m_DEM.Get_YMax();
145 m_Data_Min.z = m_DEM.Get_Min (); m_Data_Max.z = m_DEM.Get_Max ();
146
147 m_pMap->SaveAs_Image_To_Grid(m_Map, m_Map_Res);
148
149 Update_View();
150 }
151
152 //---------------------------------------------------------
Update_Parent(void)153 void CVIEW_Map_3DPanel::Update_Parent(void)
154 {
155 ((CVIEW_Map_3D *)GetParent())->Update_StatusBar();
156 }
157
158
159 ///////////////////////////////////////////////////////////
160 // //
161 ///////////////////////////////////////////////////////////
162
163 //---------------------------------------------------------
Set_Options(CSG_Grid * pDEM,int DEM_Res,int Map_Res)164 bool CVIEW_Map_3DPanel::Set_Options(CSG_Grid *pDEM, int DEM_Res, int Map_Res)
165 {
166 if( m_pDEM == pDEM && m_DEM_Res == DEM_Res && m_Map_Res == Map_Res )
167 {
168 return( false ); // nothing to do
169 }
170
171 //-----------------------------------------------------
172 m_pDEM = pDEM;
173
174 if( DEM_Res >= 2 ) m_DEM_Res = DEM_Res;
175 if( Map_Res >= 2 ) m_Map_Res = Map_Res;
176
177 Update_Statistics();
178
179 return( true );
180 }
181
182 //---------------------------------------------------------
Inc_DEM_Res(int Step)183 bool CVIEW_Map_3DPanel::Inc_DEM_Res(int Step)
184 {
185 return( m_DEM_Res + Step >= 2 ? Set_Options(m_pDEM, m_DEM_Res + Step, m_Map_Res) : false );
186 }
187
188 //---------------------------------------------------------
Inc_Map_Res(int Step)189 bool CVIEW_Map_3DPanel::Inc_Map_Res(int Step)
190 {
191 return( m_Map_Res + Step >= 2 ? Set_Options(m_pDEM, m_DEM_Res, m_Map_Res + Step) : false );
192 }
193
194
195 ///////////////////////////////////////////////////////////
196 // //
197 ///////////////////////////////////////////////////////////
198
199 //---------------------------------------------------------
On_Key_Down(wxKeyEvent & event)200 void CVIEW_Map_3DPanel::On_Key_Down(wxKeyEvent &event)
201 {
202 switch( event.GetKeyCode() )
203 {
204 default : CSG_3DView_Panel::On_Key_Down(event); return;
205
206 case WXK_F1 : m_zScale -= 0.5; break;
207 case WXK_F2 : m_zScale += 0.5; break;
208
209 case WXK_F5 : Inc_DEM_Res(-25); break;
210 case WXK_F6 : Inc_DEM_Res( 25); break;
211
212 case WXK_F7 : Inc_Map_Res(-25); break;
213 case WXK_F8 : Inc_Map_Res( 25); break;
214
215 case WXK_F9 : m_Projector.Inc_Central_Distance( 50); break;
216 case WXK_F10: m_Projector.Inc_Central_Distance(-50); break;
217 }
218
219 //-----------------------------------------------------
220 Update_View();
221 Update_Parent();
222 }
223
224
225 ///////////////////////////////////////////////////////////
226 // //
227 ///////////////////////////////////////////////////////////
228
229 //---------------------------------------------------------
On_Before_Draw(void)230 bool CVIEW_Map_3DPanel::On_Before_Draw(void)
231 {
232 if( m_Play_State == SG_3DVIEW_PLAY_STOP )
233 {
234 m_Projector.Set_zScaling(m_Projector.Get_xScaling() * m_zScale);
235 }
236
237 return( true );
238 }
239
240
241 ///////////////////////////////////////////////////////////
242 // //
243 ///////////////////////////////////////////////////////////
244
245 //---------------------------------------------------------
Get_Node(int x,int y,TSG_Triangle_Node & Node)246 inline bool CVIEW_Map_3DPanel::Get_Node(int x, int y, TSG_Triangle_Node &Node)
247 {
248 if( m_DEM.is_InGrid(x, y) )
249 {
250 Node.x = Node.c = m_DEM.Get_System().Get_xGrid_to_World(x);
251 Node.y = Node.d = m_DEM.Get_System().Get_yGrid_to_World(y);
252 Node.z = m_DEM.asDouble(x, y);
253
254 m_Projector.Get_Projection(Node.x, Node.y, Node.z);
255
256 return( true );
257 }
258
259 return( false );
260 }
261
262
263 ///////////////////////////////////////////////////////////
264 // //
265 ///////////////////////////////////////////////////////////
266
267 //---------------------------------------------------------
On_Draw(void)268 bool CVIEW_Map_3DPanel::On_Draw(void)
269 {
270 if( !m_DEM.is_Valid() )
271 {
272 return( false );
273 }
274
275 //-----------------------------------------------------
276 #pragma omp parallel for
277 for(int y=1; y<m_DEM.Get_NY(); y++)
278 {
279 for(int x=1; x<m_DEM.Get_NX(); x++)
280 {
281 TSG_Triangle_Node p[3];
282
283 if( Get_Node(x - 1, y - 1, p[0])
284 && Get_Node(x , y , p[1]) )
285 {
286 if( Get_Node(x, y - 1, p[2]) )
287 {
288 Draw_Triangle(p, true);
289 }
290
291 if( Get_Node(x - 1, y, p[2]) )
292 {
293 Draw_Triangle(p, true);
294 }
295 }
296 }
297 }
298
299 //-----------------------------------------------------
300 return( true );
301 }
302
303
304 ///////////////////////////////////////////////////////////
305 // //
306 // //
307 // //
308 ///////////////////////////////////////////////////////////
309
310 //---------------------------------------------------------
311