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