1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                    Lectures_Shapes                    //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                   Exercise_14.cpp                     //
14 //                                                       //
15 //                 Copyright (C) 2003 by                 //
16 //                      Olaf Conrad                      //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    e-mail:     oconrad@saga-gis.org                   //
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Goettingen               //
44 //                Goldschmidtstr. 5                      //
45 //                37077 Goettingen                       //
46 //                Germany                                //
47 //                                                       //
48 ///////////////////////////////////////////////////////////
49 
50 //---------------------------------------------------------
51 #include "Exercise_14.h"
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
61 #define NOCHANNEL	0
62 #define SPRING		1
63 #define CHANNEL		2
64 #define MOUTH		3
65 
66 
67 ///////////////////////////////////////////////////////////
68 //														 //
69 //														 //
70 //														 //
71 ///////////////////////////////////////////////////////////
72 
73 //---------------------------------------------------------
CExercise_14(void)74 CExercise_14::CExercise_14(void)
75 {
76 	Set_Name		(_TL("14: Vectorising channel lines"));
77 
78 	Set_Author		("O.Conrad (c) 2006");
79 
80 	Set_Description	(_TW(
81 		"Vectorising channel lines."
82 	));
83 
84 	Add_Reference("Conrad, O.", "2007",
85 		"SAGA - Entwurf, Funktionsumfang und Anwendung eines Systems f�r Automatisierte Geowissenschaftliche Analysen",
86 		"ediss.uni-goettingen.de.", SG_T("http://hdl.handle.net/11858/00-1735-0000-0006-B26C-6"), SG_T("Online")
87 	);
88 
89 
90 	//-----------------------------------------------------
91 	Parameters.Add_Grid("",
92 		"ELEVATION"	, _TL("Elevation grid"),
93 		_TL(""),
94 		PARAMETER_INPUT
95 	);
96 
97 	Parameters.Add_Grid("",
98 		"CHANNELS"	, _TL("Channels (Raster)"),
99 		_TL(""),
100 		PARAMETER_OUTPUT
101 	);
102 
103 	Parameters.Add_Shapes("",
104 		"SHAPES"	, _TL("Channels (Vector)"),
105 		_TL(""),
106 		PARAMETER_OUTPUT
107 	);
108 
109 	Parameters.Add_Double("",
110 		"THRESHOLD"	, _TL("Threshold"),
111 		_TL(""),
112 		4, 0., true, 8., true
113 	);
114 }
115 
116 
117 ///////////////////////////////////////////////////////////
118 //														 //
119 ///////////////////////////////////////////////////////////
120 
121 //---------------------------------------------------------
On_Execute(void)122 bool CExercise_14::On_Execute(void)
123 {
124 	//-----------------------------------------------------
125 	m_pDTM    = Parameters("ELEVATION")->asGrid();
126 	m_pChnl   = Parameters("CHANNELS" )->asGrid();
127 	m_pShapes = Parameters("SHAPES"   )->asShapes();
128 
129 	//-----------------------------------------------------
130 	m_pDir    = NULL;
131 
132 	if( Initialise(Parameters("THRESHOLD")->asInt()) )
133 	{
134 		Find_Channels();
135 
136 		Vectorise();
137 	}
138 
139 	//-----------------------------------------------------
140 	if( m_pDir )
141 	{
142 		delete(m_pDir);
143 	}
144 
145 	return( true );
146 }
147 
148 
149 ///////////////////////////////////////////////////////////
150 //														 //
151 ///////////////////////////////////////////////////////////
152 
153 //---------------------------------------------------------
Initialise(int Threshold)154 bool CExercise_14::Initialise(int Threshold)
155 {
156 	int		x, y, i, ix, iy, Dir;
157 	double	z, dz, dzMax;
158 	CSG_Colors	Colors;
159 
160 	//-----------------------------------------------------
161 	m_pDir	= new CSG_Grid(m_pDTM, SG_DATATYPE_Char);
162 
163 	m_pChnl->Assign();
164 
165 	Colors.Set_Count(4);
166 	Colors.Set_Color(0, 192, 192, 192);	// NOCHANNEL
167 	Colors.Set_Color(1,   0, 255,   0);	// SPRING
168 	Colors.Set_Color(2,   0,   0, 255);	// CHANNEL
169 	Colors.Set_Color(3, 255,   0,   0);	// MOUTH
170 	DataObject_Set_Colors(m_pChnl, Colors);
171 
172 	//-----------------------------------------------------
173 	for(y=0; y<Get_NY() && Set_Progress(y); y++)
174 	{
175 		for(x=0; x<Get_NX(); x++)
176 		{
177 			Dir		= -1;
178 
179 			if( is_InGrid(x, y) && !m_pDTM->is_NoData(x, y) )
180 			{
181 				z		= m_pDTM->asDouble(x, y);
182 				dzMax	= 0.0;
183 
184 				for(i=0; i<8; i++)
185 				{
186 					ix		= Get_xTo(i, x);
187 					iy		= Get_yTo(i, y);
188 
189 					if( is_InGrid(ix, iy) && !m_pDTM->is_NoData(ix, iy) )
190 					{
191 						dz		= (z - m_pDTM->asDouble(ix, iy)) / Get_Length(i);
192 
193 						if( dz > dzMax )
194 						{
195 							dzMax	= dz;
196 							Dir		= i;
197 						}
198 					}
199 				}
200 			}
201 
202 			//---------------------------------------------
203 			m_pDir->Set_Value(x, y, Dir);
204 
205 			if( Dir >= 0 )
206 			{
207 				m_pChnl->Add_Value(Get_xTo(Dir, x), Get_yTo(Dir, y), 1);
208 			}
209 		}
210 	}
211 
212 	//-----------------------------------------------------
213 	for(y=0; y<Get_NY() && Set_Progress(y); y++)
214 	{
215 		for(x=0; x<Get_NX(); x++)
216 		{
217 			m_pChnl->Set_Value(x, y, m_pChnl->asInt(x, y) >= Threshold ? SPRING : NOCHANNEL);
218 		}
219 	}
220 
221 	return( true );
222 }
223 
224 
225 ///////////////////////////////////////////////////////////
226 //														 //
227 ///////////////////////////////////////////////////////////
228 
229 //---------------------------------------------------------
Find_Channels(void)230 void CExercise_14::Find_Channels(void)
231 {
232 	int		x, y;
233 
234 	for(sLong n=0; n<Get_NCells() && Set_Progress_NCells(n); n++)
235 	{
236 		if( m_pDTM->Get_Sorted(n, x, y, true) && m_pChnl->asInt(x, y) == SPRING )
237 		{
238 			m_pChnl	->Set_Value(x, y, SPRING);
239 
240 			Find_Channels(x, y);
241 		}
242 	}
243 }
244 
245 //---------------------------------------------------------
Find_Channels(int x,int y)246 void CExercise_14::Find_Channels(int x, int y)
247 {
248 	int		Dir, ix, iy;
249 
250 	if( (Dir = m_pDir->asInt(x, y)) >= 0 )
251 	{
252 		ix	= Get_xTo(Dir, x);
253 		iy	= Get_yTo(Dir, y);
254 
255 		switch( m_pChnl->asInt(ix, iy) )
256 		{
257 		case NOCHANNEL: case SPRING:
258 			m_pChnl	->Set_Value(ix, iy, CHANNEL);
259 			Find_Channels(ix, iy);	// recursive function call...
260 			break;
261 
262 		case CHANNEL:
263 			m_pChnl	->Set_Value(ix, iy, MOUTH);
264 			break;
265 		}
266 	}
267 }
268 
269 
270 ///////////////////////////////////////////////////////////
271 //														 //
272 ///////////////////////////////////////////////////////////
273 
274 //---------------------------------------------------------
Vectorise(void)275 void CExercise_14::Vectorise(void)
276 {
277 	int			x, y, Segment_ID;
278 	double		Length;
279 	CSG_Shape	*pSegment;
280 
281 	m_pShapes->Create(SHAPE_TYPE_Line, _TL("Channels"));
282 
283 	m_pShapes->Add_Field("SEGMENT_ID"	, SG_DATATYPE_Int);
284 	m_pShapes->Add_Field("LENGTH"		, SG_DATATYPE_Double);
285 
286 	//-----------------------------------------------------
287 	for(y=0, Segment_ID=0; y<Get_NY() && Set_Progress(y); y++)
288 	{
289 		for(x=0; x<Get_NX(); x++)
290 		{
291 			switch( m_pChnl->asInt(x, y) )
292 			{
293 			case SPRING: case MOUTH:
294 				pSegment	= m_pShapes->Add_Shape();
295 
296 				Length		= Vectorise(x, y, pSegment);
297 
298 				if( Length > 0.0 )
299 				{
300 					pSegment->Set_Value(0, ++Segment_ID);
301 					pSegment->Set_Value(1, Length);
302 				}
303 				else
304 				{
305 					m_pShapes->Del_Shape(pSegment);
306 				}
307 
308 				break;
309 			}
310 		}
311 	}
312 }
313 
314 //---------------------------------------------------------
Vectorise(int x,int y,CSG_Shape * pSegment)315 double CExercise_14::Vectorise(int x, int y, CSG_Shape *pSegment)
316 {
317 	int		Dir, ix, iy;
318 	double	Length;
319 
320 	Length	= 0.0;
321 
322 	pSegment->Add_Point(Get_XMin() + x * Get_Cellsize(), Get_YMin() + y * Get_Cellsize());
323 
324 	if( (Dir = m_pDir->asInt(x, y)) >= 0 )
325 	{
326 		Length	= Get_Length(Dir);
327 
328 		ix		= Get_xTo(Dir, x);
329 		iy		= Get_yTo(Dir, y);
330 
331 		switch( m_pChnl->asInt(ix, iy) )
332 		{
333 		case CHANNEL:
334 			Length	+= Vectorise(ix, iy, pSegment);	// recursive function call...
335 			break;
336 
337 		case MOUTH:
338 			Length	+= Get_Length(Dir);
339 			pSegment->Add_Point(Get_XMin() + ix * Get_Cellsize(), Get_YMin() + iy * Get_Cellsize());
340 			break;
341 		}
342 	}
343 
344 	return( Length );
345 }
346 
347 
348 ///////////////////////////////////////////////////////////
349 //														 //
350 //														 //
351 //														 //
352 ///////////////////////////////////////////////////////////
353 
354 //---------------------------------------------------------
355