1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                     ta_hydrology                      //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //                 Flow_AreaUpslope.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 "Flow_AreaUpslope.h"
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
CFlow_AreaUpslope(void)61 CFlow_AreaUpslope::CFlow_AreaUpslope(void)
62 {
63 	m_pDEM		= NULL;
64 	m_pRoute	= NULL;
65 	m_pFlow		= NULL;
66 }
67 
68 //---------------------------------------------------------
~CFlow_AreaUpslope(void)69 CFlow_AreaUpslope::~CFlow_AreaUpslope(void)
70 {
71 	Finalise();
72 }
73 
74 
75 ///////////////////////////////////////////////////////////
76 //														 //
77 ///////////////////////////////////////////////////////////
78 
79 //---------------------------------------------------------
Get_Description(void)80 CSG_String CFlow_AreaUpslope::Get_Description(void)
81 {
82 	return( _TW(
83 		"This tool allows you to specify target cells, for which the "
84 		"upslope contributing area shall be identified. The result will "
85 		"give for each cell the percentage of its flow that reaches the "
86 		"target cell(s)."
87 	));
88 }
89 
90 //---------------------------------------------------------
Get_Methods(void)91 CSG_String CFlow_AreaUpslope::Get_Methods(void)
92 {
93 	return( CSG_String::Format("%s|%s|%s|%s|%s",
94 		_TL("Deterministic 8"),
95 		_TL("Deterministic Infinity"),
96 		_TL("Multiple Flow Direction"),
97 		_TL("Multiple Triangular Flow Directon"),
98 		_TL("Multiple Maximum Downslope Gradient Based Flow Directon")
99 	));
100 }
101 
102 //---------------------------------------------------------
103 #define ADD_REFERENCES	{\
104 	Add_Reference("Freeman, G.T.", "1991",\
105 		"Calculating catchment area with divergent flow based on a regular grid",\
106 		"Computers and Geosciences, 17:413-22."\
107 	);\
108 \
109 	Add_Reference("O'Callaghan, J.F. & Mark, D.M.", "1984",\
110 		"The extraction of drainage networks from digital elevation data",\
111 		"Computer Vision, Graphics and Image Processing, 28:323-344."\
112 	);\
113 \
114 	Add_Reference("Qin, C. Z., Zhu, A. X., Pei, T., Li, B. L., Scholten, T., Behrens, T. & Zhou, C. H.", "2011",\
115 		"An approach to computing topographic wetness index based on maximum downslope gradient",\
116 		"Precision Agriculture, 12(1), 32-43.",\
117 		SG_T("https://www.researchgate.net/profile/Cheng-Zhi_Qin/publication/225309245_An_approach_to_computing_topographic_wetness_index_based_on_maximum_downslope_gradient/links/0912f5019cb8cd1521000000.pdf"),\
118 		SG_T("ResearchGate")\
119 	);\
120 \
121 	Add_Reference("Quinn, P.F., Beven, K.J., Chevallier, P. & Planchon, O.", "1991",\
122 		"The prediction of hillslope flow paths for distributed hydrological modelling using digital terrain models",\
123 		"Hydrological Processes, 5:59-79.",\
124 		SG_T("https://www.researchgate.net/profile/Olivier_Planchon/publication/32978462_The_Prediction_of_Hillslope_Flow_Paths_for_Distributed_Hydrological_Modeling_Using_Digital_Terrain_Model/links/0912f5130c356c86e6000000.pdf"),\
125 		SG_T("ResearchGate")\
126 	);\
127 \
128 	Add_Reference("Seibert, J. & McGlynn, B.", "2007",\
129 		"A new triangular multiple flow direction algorithm for computing upslope areas from gridded digital elevation models",\
130 		"Water Resources Research, Vol. 43, W04501,<br>"\
131 		"C++ implementation in SAGA by Thomas Grabs (c) 2007, contact: thomas.grabs@natgeo.su.se, jan.seibert@natgeo.su.se.",\
132 		SG_T("http://onlinelibrary.wiley.com/doi/10.1029/2006WR005128/full"), SG_T("Wiley")\
133 	);\
134 \
135 	Add_Reference("Tarboton, D.G.", "1997",\
136 		"A new method for the determination of flow directions and upslope areas in grid digital elevation models",\
137 		"Water Resources Research, Vol.33, No.2, p.309-319.",\
138 		SG_T("http://onlinelibrary.wiley.com/doi/10.1029/96WR03137/pdf"),\
139 		SG_T("Wiley")\
140 	);\
141 }
142 
143 
144 ///////////////////////////////////////////////////////////
145 //														 //
146 ///////////////////////////////////////////////////////////
147 
148 //---------------------------------------------------------
Initialise(int Method,CSG_Grid * pDTM,CSG_Grid * pRoute,CSG_Grid * pFlow,double MFD_Converge)149 bool CFlow_AreaUpslope::Initialise(int Method, CSG_Grid *pDTM, CSG_Grid *pRoute, CSG_Grid *pFlow, double MFD_Converge)
150 {
151 	Finalise();
152 
153 	if( pDTM && pDTM->is_Valid() && pFlow && pFlow->is_Valid() && pFlow->Get_System() == pDTM->Get_System() )
154 	{
155 		m_Method		= Method;
156 		m_MFD_Converge	= MFD_Converge;
157 		m_pDEM			= pDTM;
158 		m_pFlow			= pFlow;
159 		m_pFlow->Set_NoData_Value(0.);
160 
161 		if( pRoute && pRoute->is_Valid() && pRoute->Get_System() == pDTM->Get_System() )
162 		{
163 			m_pRoute	= pRoute;
164 		}
165 
166 		return( true );
167 	}
168 
169 	return( false );
170 }
171 
172 //---------------------------------------------------------
Finalise(void)173 bool CFlow_AreaUpslope::Finalise(void)
174 {
175 	m_pDEM		= NULL;
176 	m_pRoute	= NULL;
177 	m_pFlow		= NULL;
178 
179 	return( true );
180 }
181 
182 //---------------------------------------------------------
Add_Target(int x,int y)183 bool CFlow_AreaUpslope::Add_Target(int x, int y)
184 {
185 	if( m_pFlow && m_pFlow->is_InGrid(x, y, false) )
186 	{
187 		m_pFlow->Set_Value(x, y, 100.);
188 
189 		return( true );
190 	}
191 
192 	return( false );
193 }
194 
195 //---------------------------------------------------------
Clr_Target(void)196 bool CFlow_AreaUpslope::Clr_Target(void)
197 {
198 	if( m_pFlow )
199 	{
200 		m_pFlow->Assign(0.);
201 
202 		return( true );
203 	}
204 
205 	return( false );
206 }
207 
208 //---------------------------------------------------------
Get_Area(int x,int y)209 bool CFlow_AreaUpslope::Get_Area(int x, int y)
210 {
211 	return( Clr_Target() && Add_Target(x, y) && Get_Area() );
212 }
213 
214 //---------------------------------------------------------
Get_Area(void)215 bool CFlow_AreaUpslope::Get_Area(void)
216 {
217 	if( !m_pDEM || !m_pFlow || !m_pDEM->Set_Index() )
218 	{
219 		return( false );
220 	}
221 
222 	for(sLong i=0; i<m_pDEM->Get_NCells() && SG_UI_Process_Set_Progress((double)i, (double)m_pDEM->Get_NCells()); i++)
223 	{
224 		int	x, y;
225 
226 		if( m_pDEM->Get_Sorted(i, x, y, false) && m_pFlow->asDouble(x, y) <= 0. )
227 		{
228 			Set_Value(x, y);
229 		}
230 	}
231 
232 	return( true );
233 }
234 
235 
236 ///////////////////////////////////////////////////////////
237 //														 //
238 ///////////////////////////////////////////////////////////
239 
240 //---------------------------------------------------------
Set_Value(int x,int y)241 void CFlow_AreaUpslope::Set_Value(int x, int y)
242 {
243 	int	i	= m_pRoute ? m_pRoute->asChar(x, y) : -1;
244 
245 	if( i >= 0 )
246 	{
247 		int	ix	= CSG_Grid_System::Get_xTo(i, x);
248 		int	iy	= CSG_Grid_System::Get_yTo(i, y);
249 
250 		if( m_pDEM->is_InGrid(ix, iy, true) && m_pFlow->asDouble(ix, iy) > 0. )
251 		{
252 			m_pFlow->Set_Value(x, y, m_pFlow->asDouble(ix, iy));
253 		}
254 	}
255 	else if( !m_pDEM->is_NoData(x, y) )
256 	{
257 		switch( m_Method )
258 		{
259 		default: Set_D8    (x, y); break;
260 		case  1: Set_DInf  (x, y); break;
261 		case  2: Set_MFD   (x, y); break;
262 		case  3: Set_MDInf (x, y); break;
263 		case  4: Set_MMDGFD(x, y); break;
264 		}
265 	}
266 }
267 
268 //---------------------------------------------------------
Set_D8(int x,int y)269 void CFlow_AreaUpslope::Set_D8(int x, int y)
270 {
271 	int	i	= m_pDEM->Get_Gradient_NeighborDir(x, y);
272 
273 	if( i >= 0 )
274 	{
275 		int	ix	= CSG_Grid_System::Get_xTo(i, x);
276 		int	iy	= CSG_Grid_System::Get_yTo(i, y);
277 
278 		if( m_pDEM->is_InGrid(ix, iy) && m_pFlow->asDouble(ix, iy) > 0. )
279 		{
280 			m_pFlow->Set_Value(x, y, m_pFlow->asDouble(ix, iy));
281 		}
282 	}
283 }
284 
285 //---------------------------------------------------------
Set_DInf(int x,int y)286 void CFlow_AreaUpslope::Set_DInf(int x, int y)
287 {
288 	double	Slope, Aspect;
289 
290 	if( m_pDEM->Get_Gradient(x, y, Slope, Aspect) )	// && Aspect >= 0. )
291 	{
292 		int	i	= (int)(Aspect / M_PI_045);
293 
294 		int	ix	= CSG_Grid_System::Get_xTo(i    , x);
295 		int	iy	= CSG_Grid_System::Get_yTo(i    , y);
296 
297 		int	jx	= CSG_Grid_System::Get_xTo(i + 1, x);
298 		int	jy	= CSG_Grid_System::Get_yTo(i + 1, y);
299 
300 		if(	m_pDEM->is_InGrid(ix, iy) && m_pDEM->asDouble(ix, iy) < m_pDEM->asDouble(x, y)
301 		&&	m_pDEM->is_InGrid(jx, jy) && m_pDEM->asDouble(jx, jy) < m_pDEM->asDouble(x, y) )
302 		{
303 			Aspect	= fmod(Aspect,  M_PI_045) / M_PI_045;
304 
305 			double	Flow	=
306 				m_pFlow->asDouble(ix, iy) * (1. - Aspect) +
307 				m_pFlow->asDouble(jx, jy) * (     Aspect);
308 
309 			if( Flow > 0. )
310 			{
311 				m_pFlow->Set_Value(x, y, Flow);
312 			}
313 
314 			return;
315 		}
316 	}
317 
318 	Set_D8(x, y);
319 }
320 
321 //---------------------------------------------------------
Set_MFD(int x,int y)322 void CFlow_AreaUpslope::Set_MFD(int x, int y)
323 {
324 	double	dz[8], dzSum = 0., z = m_pDEM->asDouble(x, y);
325 
326 	for(int i=0; i<8; i++)
327 	{
328 		int	ix	= CSG_Grid_System::Get_xTo(i, x);
329 		int	iy	= CSG_Grid_System::Get_yTo(i, y);
330 
331 		dz[i]	= m_pDEM->is_InGrid(ix, iy) ? z - m_pDEM->asDouble(ix, iy) : 0.;
332 
333 		if( dz[i] > 0. )
334 		{
335 			dzSum	+= (dz[i] = pow(dz[i] / m_pDEM->Get_System().Get_Length(i), m_MFD_Converge));
336 
337 			if( m_pFlow->asDouble(ix, iy) > 0. )
338 			{
339 				dz[i] *= m_pFlow->asDouble(ix, iy);
340 			}
341 			else
342 			{
343 				dz[i]  = 0.;
344 			}
345 		}
346 	}
347 
348 	if( dzSum > 0. )
349 	{
350 		double	Flow	= 0.;
351 
352 		for(int i=0; i<8; i++)
353 		{
354 			if( dz[i] > 0. )
355 			{
356 				Flow	+= dz[i] / dzSum;
357 			}
358 		}
359 
360 		if( Flow > 0. )
361 		{
362 			m_pFlow->Set_Value(x, y, Flow);
363 		}
364 	}
365 }
366 
367 //---------------------------------------------------------
Set_MMDGFD(int x,int y)368 void CFlow_AreaUpslope::Set_MMDGFD(int x, int y)
369 {
370 	double	dz[8], dzMax = 0., z = m_pDEM->asDouble(x, y);
371 
372 	for(int i=0; i<8; i++)
373 	{
374 		int	ix	= CSG_Grid_System::Get_xTo(i, x);
375 		int	iy	= CSG_Grid_System::Get_yTo(i, y);
376 
377 		dz[i]	= m_pDEM->is_InGrid(ix, iy) ? z - m_pDEM->asDouble(ix, iy) : 0.;
378 
379 		if( dz[i] > 0. )
380 		{
381 			dz[i]	/= m_pDEM->Get_System().Get_Length(i);
382 
383 			if( dzMax < dz[i] )
384 			{
385 				dzMax	= dz[i];
386 			}
387 		}
388 	}
389 
390 	//-----------------------------------------------------
391 	if( dzMax > 0. )
392 	{
393 		dzMax	= dzMax < 1. ? 8.9 * dzMax + 1.1 : 10.;
394 
395 		double	dzSum	= 0.;
396 
397 		for(int i=0; i<8; i++)
398 		{
399 			if( dz[i] > 0. )
400 			{
401 				dzSum	+= (dz[i] = pow(dz[i], dzMax));
402 			}
403 		}
404 
405 		double	Flow	= 0.;
406 
407 		for(int i=0; i<8; i++)
408 		{
409 			int	ix	= CSG_Grid_System::Get_xTo(i, x);
410 			int	iy	= CSG_Grid_System::Get_yTo(i, y);
411 
412 			if( dz[i] > 0. && m_pFlow->asDouble(ix, iy) > 0. )
413 			{
414 				Flow	+= dz[i] / dzSum;
415 			}
416 		}
417 
418 		if( Flow > 0. )
419 		{
420 			m_pFlow->Set_Value(x, y, Flow);
421 		}
422 	}
423 }
424 
425 //---------------------------------------------------------
Set_MDInf(int x,int y)426 void CFlow_AreaUpslope::Set_MDInf(int x, int y)
427 {
428 	bool	bInGrid[8];
429 
430 	double	dz[8], s_facet[8], r_facet[8], valley[8], portion[8];
431 
432 	double	z	= m_pDEM->asDouble(x, y);
433 
434 	//-----------------------------------------------------
435 	for(int i=0; i<8; i++)
436 	{
437 		s_facet[i]	= r_facet[i]	= -999.;
438 
439 		int	ix	= CSG_Grid_System::Get_xTo(i, x);
440 		int	iy	= CSG_Grid_System::Get_yTo(i, y);
441 
442 		if( (bInGrid[i] = m_pDEM->is_InGrid(ix, iy)) )
443 		{
444 			dz[i]	= z - m_pDEM->asDouble(ix, iy);
445 		}
446 		else
447 		{
448 			dz[i]	= 0.;
449 		}
450 	}
451 
452 	//-----------------------------------------------------
453 	for(int i=0; i<8; i++)
454 	{
455 		double	hs	= -999.;
456 		double	hr	= -999.;
457 
458 		if( bInGrid[i] )
459 		{
460 			int	j	= i < 7 ? i + 1 : 0;
461 
462 			if( bInGrid[j] )
463 			{
464 				double	nx	= (dz[j] * CSG_Grid_System::Get_yTo(i) - dz[i] * CSG_Grid_System::Get_yTo(j)) * m_pDEM->Get_System().Get_Cellsize();			// vb-code:  nx = (z1 * yd(j) - z2 * yd(i)) * gridsize
465 				double	ny	= (dz[i] * CSG_Grid_System::Get_xTo(j) - dz[j] * CSG_Grid_System::Get_xTo(i)) * m_pDEM->Get_System().Get_Cellsize();			// vb-code:  ny = (z1 * xd(j) - z2 * xd(i)) * gridsize
466 				double	nz	= (CSG_Grid_System::Get_xTo(i) * CSG_Grid_System::Get_yTo(j) - CSG_Grid_System::Get_xTo(j) * CSG_Grid_System::Get_yTo(i)) * m_pDEM->Get_System().Get_Cellarea();	// vb-code:  nz = (xd(j) * yd(i) - xd(i) * yd(j)) * gridsize ^ 2
467 
468 				double	n_norm	= sqrt(nx*nx + ny*ny +nz*nz);
469 
470 				if( nx == 0. )
471 				{
472 					hr = (ny >= 0.)? 0. : M_PI;
473 				}
474 				else if( nx < 0. )
475 				{
476 					hr = M_PI_270 - atan(ny / nx);
477 				}
478 				else
479 				{
480 					hr = M_PI_090 - atan(ny / nx);
481 				}
482 
483 				hs	= -tan( acos( nz/n_norm ) );	// vb-code:  hs = -Tan(arccos(nz / betrag_n))
484 
485 				if( hr < i * M_PI_045 || hr > (i+1) * M_PI_045 )
486 				{
487 					if( dz[i] > dz[j] )
488 					{
489 						hr	= i * M_PI_045;
490 						hs	= dz[i] / m_pDEM->Get_System().Get_Length(i);
491 					}
492 					else
493 					{
494 						hr	= j * M_PI_045;
495 						hs	= dz[j] / m_pDEM->Get_System().Get_Length(j);
496 					}
497 				}
498 			}
499 			else if( dz[i] > 0. )
500 			{
501 				hr	= i * M_PI_045;
502 				hs	= dz[i] / m_pDEM->Get_System().Get_Length(i);
503 			}
504 
505 			s_facet[i]	= hs;
506 			r_facet[i]	= hr;
507 		}
508 	}
509 
510 	//-----------------------------------------------------
511 	double	dzSum	= 0.;
512 
513 	for(int i=0; i<8; i++)
514 	{
515 		valley[i]	= 0.;
516 
517 		int	j	= i < 7 ? i + 1 : 0;
518 
519 		if( s_facet[i] > 0. )
520 		{
521 			if( r_facet[i] > i * M_PI_045 && r_facet[i] < (i+1) * M_PI_045 )
522 			{
523 				valley[i] = s_facet[i];
524 			}
525 			else if( r_facet[i] == r_facet[j] )
526 			{
527 				valley[i] = s_facet[i];
528 			}
529 			else if( s_facet[j] == -999. && r_facet[i] == (i+1) * M_PI_045 )
530 			{
531 				valley[i] = s_facet[i];
532 			}
533 			else
534 			{
535 				j = i > 0 ? i - 1 : 7;
536 
537 				if( s_facet[j] == -999. && r_facet[i] == i * M_PI_045 )
538 				{
539 					valley[i] = s_facet[i];
540 				}
541 			}
542 
543 			valley[i] = pow(valley[i], this->m_MFD_Converge);
544 			dzSum += valley[i];
545 		}
546 
547 		portion[i] = 0.;
548 	}
549 
550 	//-----------------------------------------------------
551 	if( dzSum )
552 	{
553 		for(int i=0; i<8; i++)
554 		{
555 			int	j	= i < 7 ? i + 1 : 0;
556 
557 			if( i >= 7 && r_facet[i] == 0. )
558 			{
559 				r_facet[i]	= M_PI_360;
560 			}
561 
562 			if( valley[i] )
563 			{
564 				valley[i]	/= dzSum;
565 
566 				portion[i]	+= valley[i] * ((i+1) * M_PI_045 - r_facet[i]) / M_PI_045;	// vb-code: portion(i) = portion(i) + valley(i) * (i * PI / 4 - r_facet(i)) / (PI / 4)
567 				portion[j]	+= valley[i] * (r_facet[i] - (i  ) * M_PI_045) / M_PI_045;	// vb-code: portion(j) = portion(j) + valley(i) * (r_facet(i) - (i - 1) * PI / 4) / (PI / 4)
568 			}
569 		}
570 
571 		double	Flow	= 0.;
572 
573 		for(int i=0; i<8; i++)
574 		{
575 			if( portion[i] > 0. )
576 			{
577 				int	ix	= CSG_Grid_System::Get_xTo(i, x);
578 				int	iy	= CSG_Grid_System::Get_yTo(i, y);
579 
580 				if( m_pFlow->is_InGrid(ix, iy, false) && m_pFlow->asDouble(ix, iy) > 0. )
581 				{
582 					Flow	+= m_pFlow->asDouble(ix, iy) * portion[i];
583 				}
584 			}
585 		}
586 
587 		if( Flow > 0. )
588 		{
589 			m_pFlow->Set_Value(x, y, Flow);
590 		}
591 	}
592 }
593 
594 
595 ///////////////////////////////////////////////////////////
596 //														 //
597 //														 //
598 //														 //
599 ///////////////////////////////////////////////////////////
600 
601 //---------------------------------------------------------
CFlow_AreaUpslope_Interactive(void)602 CFlow_AreaUpslope_Interactive::CFlow_AreaUpslope_Interactive(void)
603 {
604 	Set_Name		(_TL("Upslope Area"));
605 
606 	Set_Author		("O.Conrad (c) 2001");
607 
608 	Set_Description	(CSG_String::Format("%s\n_______\n\n%s", m_Calculator.Get_Description().c_str(),
609 		_TL("Interactive version (left mouse clicks will trigger the calculation for the selected cell).")
610 	));
611 
612 	ADD_REFERENCES;
613 
614 	//-----------------------------------------------------
615 	Parameters.Add_Grid("",
616 		"ELEVATION"	, _TL("Elevation"),
617 		_TL(""),
618 		PARAMETER_INPUT
619 	);
620 
621 	Parameters.Add_Grid("",
622 		"SINKROUTE"	, _TL("Sink Routes"),
623 		_TL(""),
624 		PARAMETER_INPUT_OPTIONAL
625 	);
626 
627 	Parameters.Add_Grid("",
628 		"AREA"		, _TL("Upslope Area"),
629 		_TL(""),
630 		PARAMETER_OUTPUT
631 	);
632 
633 	Parameters.Add_Choice("",
634 		"METHOD"	, _TL("Method"),
635 		_TL(""),
636 		m_Calculator.Get_Methods(), 2
637 	);
638 
639 	Parameters.Add_Double("",
640 		"CONVERGE"	, _TL("Convergence"),
641 		_TL("Convergence factor for Multiple Flow Direction algorithm"),
642 		1.1, 0.001, true
643 	);
644 
645 	Set_Drag_Mode(TOOL_INTERACTIVE_DRAG_NONE);
646 }
647 
648 
649 ///////////////////////////////////////////////////////////
650 //														 //
651 ///////////////////////////////////////////////////////////
652 
653 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)654 int CFlow_AreaUpslope_Interactive::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
655 {
656 	if( pParameter->Cmp_Identifier("METHOD") )
657 	{
658 		pParameters->Set_Enabled("CONVERGE", pParameter->asInt() == 2 || pParameter->asInt() == 3);
659 	}
660 
661 	return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
662 }
663 
664 
665 ///////////////////////////////////////////////////////////
666 //														 //
667 ///////////////////////////////////////////////////////////
668 
669 //---------------------------------------------------------
On_Execute(void)670 bool CFlow_AreaUpslope_Interactive::On_Execute(void)
671 {
672 	if( m_Calculator.Initialise(
673 		Parameters("METHOD"   )->asInt   (),
674 		Parameters("ELEVATION")->asGrid  (),
675 		Parameters("SINKROUTE")->asGrid  (),
676 		Parameters("AREA"     )->asGrid  (),
677 		Parameters("CONVERGE" )->asDouble()) )
678 	{
679 		DataObject_Set_Colors(Parameters("AREA")->asGrid(), 11, SG_COLORS_WHITE_BLUE);
680 		DataObject_Update    (Parameters("AREA")->asGrid(), SG_UI_DATAOBJECT_SHOW);
681 
682 		return( true );
683 	}
684 
685 	return( false );
686 }
687 
688 //---------------------------------------------------------
On_Execute_Finish(void)689 bool CFlow_AreaUpslope_Interactive::On_Execute_Finish(void)
690 {
691 	return( m_Calculator.Finalise() );
692 }
693 
694 //---------------------------------------------------------
On_Execute_Position(CSG_Point ptWorld,TSG_Tool_Interactive_Mode Mode)695 bool CFlow_AreaUpslope_Interactive::On_Execute_Position(CSG_Point ptWorld, TSG_Tool_Interactive_Mode Mode)
696 {
697 	switch( Mode )
698 	{
699 	case TOOL_INTERACTIVE_LDOWN:
700 		m_Calculator.Clr_Target();
701 		m_Calculator.Add_Target(Get_xGrid(), Get_yGrid());
702 		break;
703 
704 	case TOOL_INTERACTIVE_MOVE_LDOWN:
705 		m_Calculator.Add_Target(Get_xGrid(), Get_yGrid());
706 		break;
707 
708 	case TOOL_INTERACTIVE_LUP:
709 		m_Calculator.Add_Target(Get_xGrid(), Get_yGrid());
710 		m_Calculator.Get_Area();
711 		DataObject_Update(Parameters("AREA")->asGrid(), 0., 100.);
712 		break;
713 	}
714 
715 	return( false );
716 }
717 
718 
719 ///////////////////////////////////////////////////////////
720 //														 //
721 //														 //
722 //														 //
723 ///////////////////////////////////////////////////////////
724 
725 //---------------------------------------------------------
CFlow_AreaUpslope_Area(void)726 CFlow_AreaUpslope_Area::CFlow_AreaUpslope_Area(void)
727 {
728 	Set_Name		(_TL("Upslope Area"));
729 
730 	Set_Author		("O.Conrad (c) 2001");
731 
732 	Set_Description	(CSG_String::Format("%s\n_______\n\n%s", m_Calculator.Get_Description().c_str(),
733 		_TW("This version uses all valid cells (not \'no data\' values) of a given target grid to determine the contributing area. "
734 			"In case no target grid is provided as input, the specified x/y coordinates are used as target point.")
735 	));
736 
737 	ADD_REFERENCES;
738 
739 	//-----------------------------------------------------
740 	Parameters.Add_Grid("",
741 		"TARGET"	, _TL("Target Area"),
742 		_TL(""),
743 		PARAMETER_INPUT_OPTIONAL
744 	);
745 
746 	Parameters.Add_Double("",
747 		"TARGET_PT_X", _TL("Target X coordinate"),
748 		_TL("The x-coordinate of the target point in world coordinates [map units]"),
749 		0.
750 	);
751 
752 	Parameters.Add_Double("",
753 		"TARGET_PT_Y", _TL("Target Y coordinate"),
754 		_TL("The y-coordinate of the target point in world coordinates [map units]"),
755 		0.
756 	);
757 
758 	Parameters.Add_Grid("",
759 		"ELEVATION"	, _TL("Elevation"),
760 		_TL(""),
761 		PARAMETER_INPUT
762 	);
763 
764 	Parameters.Add_Grid("",
765 		"SINKROUTE"	, _TL("Sink Routes"),
766 		_TL(""),
767 		PARAMETER_INPUT_OPTIONAL
768 	);
769 
770 	Parameters.Add_Grid("",
771 		"AREA"		, _TL("Upslope Area"),
772 		_TL(""),
773 		PARAMETER_OUTPUT
774 	);
775 
776 	Parameters.Add_Choice("",
777 		"METHOD"	, _TL("Method"),
778 		_TL(""),
779 		m_Calculator.Get_Methods(), 2
780 	);
781 
782 	Parameters.Add_Double("",
783 		"CONVERGE"	, _TL("Convergence"),
784 		_TL("Convergence factor for Multiple Flow Direction algorithm"),
785 		1.1, 0.001, true
786 	);
787 }
788 
789 
790 ///////////////////////////////////////////////////////////
791 //														 //
792 ///////////////////////////////////////////////////////////
793 
794 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)795 int CFlow_AreaUpslope_Area::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
796 {
797 	if( pParameter->Cmp_Identifier("METHOD") )
798 	{
799 		pParameters->Set_Enabled("CONVERGE", pParameter->asInt() == 2 || pParameter->asInt() == 3);
800 	}
801 
802 	return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
803 }
804 
805 //---------------------------------------------------------
On_Execute(void)806 bool CFlow_AreaUpslope_Area::On_Execute(void)
807 {
808 	bool	bResult	= false;
809 
810 	if( m_Calculator.Initialise(
811 		Parameters("METHOD"   )->asInt   (),
812 		Parameters("ELEVATION")->asGrid  (),
813 		Parameters("SINKROUTE")->asGrid  (),
814 		Parameters("AREA"     )->asGrid  (),
815 		Parameters("CONVERGE" )->asDouble()	) )
816 	{
817 		m_Calculator.Clr_Target();
818 
819 		CSG_Grid	*pTarget	= Parameters("TARGET")->asGrid();
820 
821 		if( pTarget != NULL )
822 		{
823 			for(int y=0; y<Get_NY() && Set_Progress(y); y++)
824 			{
825 				for(int x=0; x<Get_NX(); x++)
826 				{
827 					if( !pTarget->is_NoData(x, y) && m_Calculator.Add_Target(x, y) )
828 					{
829 						bResult	= true;
830 					}
831 				}
832 			}
833 		}
834 		else
835 		{
836 			int	x, y;
837 
838 			Parameters("ELEVATION")->asGrid()->Get_System().Get_World_to_Grid(x, y,
839 				Parameters("TARGET_PT_X")->asDouble(),
840 				Parameters("TARGET_PT_Y")->asDouble()
841 			);
842 
843 			if( m_Calculator.Add_Target(x, y) )
844 			{
845 				bResult	= true;
846 			}
847 			else
848 			{
849 				SG_UI_Msg_Add_Error(_TL("Coordinates of target point outside of DEM!"));
850 			}
851 		}
852 
853 		if( bResult )
854 		{
855 			m_Calculator.Get_Area();
856 
857 			DataObject_Set_Colors(Parameters("AREA")->asGrid(), 11, SG_COLORS_WHITE_BLUE);
858 		}
859 	}
860 
861 	//-----------------------------------------------------
862 	m_Calculator.Finalise();
863 
864 	return( bResult );
865 }
866 
867 
868 ///////////////////////////////////////////////////////////
869 //														 //
870 //														 //
871 //														 //
872 ///////////////////////////////////////////////////////////
873 
874 //---------------------------------------------------------
875