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