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