1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Tool Library //
9 // ta_morphometry //
10 // //
11 //-------------------------------------------------------//
12 // //
13 // tpi.cpp //
14 // //
15 // Copyright (C) 2011 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 Hamburg //
44 // Germany //
45 // //
46 ///////////////////////////////////////////////////////////
47
48 //---------------------------------------------------------
49 #include "tpi.h"
50
51
52 ///////////////////////////////////////////////////////////
53 // //
54 // //
55 // //
56 ///////////////////////////////////////////////////////////
57
58 //---------------------------------------------------------
CTPI(void)59 CTPI::CTPI(void)
60 {
61 //-----------------------------------------------------
62 Set_Name (_TL("Topographic Position Index (TPI)"));
63
64 Set_Author ("O.Conrad (c) 2011");
65
66 Set_Description (_TW(
67 "Topographic Position Index (TPI) calculation as proposed by Guisan et al. (1999). "
68 "This is literally the same as the difference to the mean calculation (residual analysis) "
69 "proposed by Wilson & Gallant (2000). "
70 "The bandwidth parameter for distance weighting is given as percentage of the (outer) radius."
71 ));
72
73 Add_Reference(
74 "Guisan, A., Weiss, S.B., Weiss, A.D.", "1999",
75 "GLM versus CCA spatial modeling of plant species distribution",
76 "Plant Ecology 143: 107-122."
77 );
78
79 Add_Reference(
80 "Weiss, A.D.", "2000",
81 "Topographic Position and Landforms Analysis",
82 "Poster", SG_T("http://www.jennessent.com/downloads/tpi-poster-tnc_18x22.pdf")
83 );
84
85 Add_Reference(
86 "Wilson, J.P. & Gallant, J.C.", "2000",
87 "Primary Topographic Attributes",
88 "In: Wilson, J.P. & Gallant, J.C. [Eds.]: Terrain Analysis: Principles and Applications, John Wiley & Sons, p.51-85."
89 );
90
91 //-----------------------------------------------------
92 Parameters.Add_Grid(
93 "", "DEM" , _TL("Elevation"),
94 _TL(""),
95 PARAMETER_INPUT
96 );
97
98 Parameters.Add_Grid(
99 "", "TPI" , _TL("Topographic Position Index"),
100 _TL(""),
101 PARAMETER_OUTPUT
102 );
103
104 Parameters.Add_Bool(
105 "", "STANDARD" , _TL("Standardize"),
106 _TL(""),
107 false
108 );
109
110 Parameters.Add_Range(
111 "", "RADIUS" , _TL("Scale"),
112 _TL("kernel radius in map units; defines an annulus if inner radius is greater than zero"),
113 0., 100., 0., true
114 );
115
116 m_Kernel.Get_Weighting().Set_BandWidth(75.); // 75%
117 m_Kernel.Get_Weighting().Create_Parameters(Parameters);
118 }
119
120
121 ///////////////////////////////////////////////////////////
122 // //
123 ///////////////////////////////////////////////////////////
124
125 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)126 int CTPI::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
127 {
128 m_Kernel.Get_Weighting().Enable_Parameters(*pParameters);
129
130 return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
131 }
132
133
134 ///////////////////////////////////////////////////////////
135 // //
136 ///////////////////////////////////////////////////////////
137
138 //---------------------------------------------------------
On_Execute(void)139 bool CTPI::On_Execute(void)
140 {
141 m_pDEM = Parameters("DEM")->asGrid();
142 m_pTPI = Parameters("TPI")->asGrid();
143
144 DataObject_Set_Colors(m_pTPI, 11, SG_COLORS_RED_GREY_BLUE, true);
145
146 //-----------------------------------------------------
147 double r_inner = Parameters("RADIUS")->asRange()->Get_Min() / Get_Cellsize();
148 double r_outer = Parameters("RADIUS")->asRange()->Get_Max() / Get_Cellsize();
149
150 m_Kernel.Get_Weighting().Set_Parameters(Parameters);
151 m_Kernel.Get_Weighting().Set_BandWidth(r_outer * m_Kernel.Get_Weighting().Get_BandWidth() / 100.);
152
153 if( !m_Kernel.Set_Annulus(r_inner, r_outer) )
154 {
155 return( false );
156 }
157
158 //-----------------------------------------------------
159 for(int y=0; y<Get_NY() && Set_Progress(y); y++)
160 {
161 #pragma omp parallel for
162 for(int x=0; x<Get_NX(); x++)
163 {
164 Get_Statistics(x, y);
165 }
166 }
167
168 //-----------------------------------------------------
169 m_Kernel.Destroy();
170
171 if( Parameters("STANDARD")->asBool() )
172 {
173 m_pTPI->Standardise();
174 }
175
176 return( true );
177 }
178
179
180 ///////////////////////////////////////////////////////////
181 // //
182 ///////////////////////////////////////////////////////////
183
184 //---------------------------------------------------------
Get_Statistics(int x,int y)185 bool CTPI::Get_Statistics(int x, int y)
186 {
187 if( m_pDEM->is_InGrid(x, y) )
188 {
189 int i, ix, iy;
190 double z, id, iw;
191
192 CSG_Simple_Statistics Statistics;
193
194 for(i=0, z=m_pDEM->asDouble(x, y); i<m_Kernel.Get_Count(); i++)
195 {
196 if( m_Kernel.Get_Values(i, ix = x, iy = y, id, iw, true) && id >= 0. && m_pDEM->is_InGrid(ix, iy) )
197 {
198 Statistics.Add_Value(m_pDEM->asDouble(ix, iy), iw);
199 }
200 }
201
202 //-------------------------------------------------
203 if( Statistics.Get_Weights() > 0. )
204 {
205 m_pTPI->Set_Value(x, y, z - Statistics.Get_Mean());
206
207 return( true );
208 }
209 }
210
211 //-----------------------------------------------------
212 m_pTPI->Set_NoData(x, y);
213
214 return( false );
215 }
216
217
218 ///////////////////////////////////////////////////////////
219 // //
220 // //
221 // //
222 ///////////////////////////////////////////////////////////
223
224 //---------------------------------------------------------
CTPI_Classification(void)225 CTPI_Classification::CTPI_Classification(void)
226 {
227 //-----------------------------------------------------
228 Set_Name (_TL("TPI Based Landform Classification"));
229
230 Set_Author ("O.Conrad (c) 2011");
231
232 Set_Description (_TW(
233 "Topographic Position Index (TPI) calculation as proposed by Guisan et al. (1999). "
234 "This is literally the same as the difference to the mean calculation (residual analysis) "
235 "proposed by Wilson & Gallant (2000). "
236 "The bandwidth parameter for distance weighting is given as percentage of the (outer) radius."
237 ));
238
239 Add_Reference(
240 "Guisan, A., Weiss, S.B., Weiss, A.D.", "1999",
241 "GLM versus CCA spatial modeling of plant species distribution",
242 "Plant Ecology 143: 107-122."
243 );
244
245 Add_Reference(
246 "Weiss, A.D.", "2000",
247 "Topographic Position and Landforms Analysis",
248 "Poster", SG_T("http://www.jennessent.com/downloads/tpi-poster-tnc_18x22.pdf")
249 );
250
251 Add_Reference(
252 "Wilson, J.P. & Gallant, J.C.", "2000",
253 "Primary Topographic Attributes",
254 "In: Wilson, J.P. & Gallant, J.C. [Eds.]: Terrain Analysis: Principles and Applications, John Wiley & Sons, p.51-85."
255 );
256
257 //-----------------------------------------------------
258 Parameters.Add_Grid(
259 "", "DEM" , _TL("Elevation"),
260 _TL(""),
261 PARAMETER_INPUT
262 );
263
264 Parameters.Add_Grid(
265 "", "LANDFORMS" , _TL("Landforms"),
266 _TL(""),
267 PARAMETER_OUTPUT, true, SG_DATATYPE_Byte
268 );
269
270 Parameters.Add_Range(
271 "", "RADIUS_A" , _TL("Small Scale"),
272 _TL("kernel radius in map units; defines an annulus if inner radius is greater than zero"),
273 0., 100., 0., true
274 );
275
276 Parameters.Add_Range(
277 "", "RADIUS_B" , _TL("Large Scale"),
278 _TL("kernel radius in map units; defines an annulus if inner radius is greater than zero"),
279 0., 1000., 0., true
280 );
281
282 m_Weighting.Set_BandWidth(75.); // 75%
283 m_Weighting.Create_Parameters(Parameters);
284 }
285
286
287 ///////////////////////////////////////////////////////////
288 // //
289 ///////////////////////////////////////////////////////////
290
291 //---------------------------------------------------------
292 enum
293 {
294 LF_CANYON = 1,
295 LF_MID_SLOPE,
296 LF_UPLAND,
297 LF_VALLEY,
298 LF_PLAIN,
299 LF_OPEN_SLOPE,
300 LF_UPPER_SLOPE,
301 LF_LOCAL_RIDGE,
302 LF_MIDSLOPE_RIDGE,
303 LF_HIGH_RIDGE,
304 LF_COUNT = LF_HIGH_RIDGE
305 };
306
307
308 ///////////////////////////////////////////////////////////
309 // //
310 ///////////////////////////////////////////////////////////
311
312 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)313 int CTPI_Classification::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
314 {
315 m_Weighting.Enable_Parameters(*pParameters);
316
317 return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
318 }
319
320
321 ///////////////////////////////////////////////////////////
322 // //
323 ///////////////////////////////////////////////////////////
324
325 //---------------------------------------------------------
On_Execute(void)326 bool CTPI_Classification::On_Execute(void)
327 {
328 //-----------------------------------------------------
329 CSG_Grid *pDEM = Parameters("DEM" )->asGrid();
330 CSG_Grid *pLandforms = Parameters("LANDFORMS")->asGrid();
331
332 pLandforms->Set_NoData_Value(0);
333
334 //-----------------------------------------------------
335 CSG_Parameter *pLUT = DataObject_Get_Parameter(pLandforms, "LUT");
336
337 if( pLUT )
338 {
339 const int LF_Colors[LF_COUNT] =
340 {
341 SG_GET_RGB( 0, 0, 127), // LF_CANYON
342 SG_GET_RGB(200, 200, 255), // LF_MID_SLOPE
343 SG_GET_RGB( 0, 200, 255), // LF_UPLAND
344 SG_GET_RGB(127, 127, 255), // LF_VALLEY
345 SG_GET_RGB(255, 255, 128), // LF_PLAIN
346 SG_GET_RGB(128, 255, 0), // LF_OPEN_SLOPE
347 SG_GET_RGB( 0, 255, 0), // LF_UPPER_SLOPE
348 SG_GET_RGB(255, 200, 127), // LF_LOCAL_RIDGE
349 SG_GET_RGB(255, 127, 0), // LF_MIDSLOPE_RIDGE
350 SG_GET_RGB(255, 0, 0) // LF_HIGH_RIDGE
351 };
352
353 //-------------------------------------------------
354 CSG_Strings Name, Desc;
355
356 Name += _TL("Streams" ); Desc += _TL("Canyons, Deeply Incised Streams" );
357 Name += _TL("Midslope Drainages"); Desc += _TL("Midslope Drainages, Shallow Valleys" );
358 Name += _TL("Upland Drainages" ); Desc += _TL("Upland Drainages, Headwaters" );
359 Name += _TL("Valleys" ); Desc += _TL("U-shaped Valleys" );
360 Name += _TL("Plains" ); Desc += _TL("Plains" );
361 Name += _TL("Open Slopes" ); Desc += _TL("Open Slopes" );
362 Name += _TL("Upper Slopes" ); Desc += _TL("Upper Slopes, Mesas" );
363 Name += _TL("Local Ridges" ); Desc += _TL("Local Ridges, Hills in Valleys" );
364 Name += _TL("Midslope Ridges" ); Desc += _TL("Midslope Ridges, Small Hills in Plains");
365 Name += _TL("High Ridges" ); Desc += _TL("Mountain Tops, High Ridges" );
366
367 //-------------------------------------------------
368 CSG_Table *pTable = pLUT->asTable();
369
370 pLUT->asTable()->Del_Records();
371
372 for(int i=0; i<LF_COUNT; i++)
373 {
374 CSG_Table_Record *pRecord = pLUT->asTable()->Add_Record();
375
376 pRecord->Set_Value(0, LF_Colors[i]);
377 pRecord->Set_Value(1, Name[i].c_str());
378 pRecord->Set_Value(2, Desc[i].c_str());
379 pRecord->Set_Value(3, i + 1);
380 pRecord->Set_Value(4, i + 1);
381 }
382
383 DataObject_Set_Parameter(pLandforms, pLUT);
384 DataObject_Set_Parameter(pLandforms, "COLORS_TYPE", 1); // Color Classification Type: Lookup Table
385 }
386
387 //-----------------------------------------------------
388 CTPI Calculator; Calculator.Set_Manager(NULL);
389
390 Calculator.Get_Parameters()->Assign_Values(&Parameters); // set DEM and Weighting scheme
391
392 Calculator.Set_Parameter("STANDARD", true);
393
394 //-----------------------------------------------------
395 CSG_Grid gA(Get_System());
396
397 Calculator.Set_Parameter("TPI" , &gA);
398 Calculator.Set_Parameter("RADIUS", Parameters("RADIUS_A"));
399
400 if( !Calculator.Execute() )
401 {
402 return( false );
403 }
404
405 //-----------------------------------------------------
406 CSG_Grid gB(Get_System());
407
408 Calculator.Set_Parameter("TPI" , &gB);
409 Calculator.Set_Parameter("RADIUS", Parameters("RADIUS_B"));
410
411 if( !Calculator.Execute() )
412 {
413 return( false );
414 }
415
416 //-----------------------------------------------------
417 for(int y=0; y<Get_NY() && Set_Progress(y); y++)
418 {
419 #pragma omp parallel for
420 for(int x=0; x<Get_NX(); x++)
421 {
422 if( pDEM->is_NoData(x, y) )
423 {
424 pLandforms->Set_Value(x, y, 0.);
425 }
426 else
427 {
428 double A = gA.asDouble(x, y);
429 double B = gB.asDouble(x, y);
430
431 if( A <= -1. )
432 {
433 if( B <= -1. )
434 { // Canyons, Deeply Incised Streams
435 pLandforms->Set_Value(x, y, LF_CANYON);
436 }
437 else if( B < 1. )
438 { // Midslope Drainages, Shallow Valleys
439 pLandforms->Set_Value(x, y, LF_MID_SLOPE);
440 }
441 else // if( B >= 1. )
442 { // Upland Drainages, Headwaters
443 pLandforms->Set_Value(x, y, LF_UPLAND);
444 }
445 }
446 else if( A < 1. )
447 {
448 if( B <= -1. )
449 { // U-shaped Valleys
450 pLandforms->Set_Value(x, y, LF_VALLEY);
451 }
452 else if( B < 1. )
453 {
454 double Slope, Aspect;
455
456 pDEM->Get_Gradient(x, y, Slope, Aspect);
457
458 if( Slope <= 5. * M_DEG_TO_RAD )
459 { // Plains
460 pLandforms->Set_Value(x, y, LF_PLAIN);
461 }
462 else
463 { // Open Slopes
464 pLandforms->Set_Value(x, y, LF_OPEN_SLOPE);
465 }
466 }
467 else // if( B >= 1. )
468 { // Upper Slopes, Mesas
469 pLandforms->Set_Value(x, y, LF_UPPER_SLOPE);
470 }
471 }
472 else // if( A >= 1. )
473 {
474 if( B <= -1. )
475 { // Local Ridges, Hills in Valleys
476 pLandforms->Set_Value(x, y, LF_LOCAL_RIDGE);
477 }
478 else if( B < 1. )
479 { // Midslope Ridges, Small Hills in Plains
480 pLandforms->Set_Value(x, y, LF_MIDSLOPE_RIDGE);
481 }
482 else // if( B >= 1. )
483 { // Mountain Tops, High Ridges
484 pLandforms->Set_Value(x, y, LF_HIGH_RIDGE);
485 }
486 }
487 }
488 }
489 }
490
491 //-----------------------------------------------------
492 return( true );
493 }
494
495
496 ///////////////////////////////////////////////////////////
497 // //
498 // //
499 // //
500 ///////////////////////////////////////////////////////////
501
502 //---------------------------------------------------------
CTPI_MultiScale(void)503 CTPI_MultiScale::CTPI_MultiScale(void)
504 {
505 //-----------------------------------------------------
506 Set_Name (_TL("Multi-Scale Topographic Position Index (TPI)"));
507
508 Set_Author ("O.Conrad (c) 2016");
509
510 Set_Description (_TW(
511 "Topographic Position Index (TPI) calculation as proposed by Guisan et al. (1999).\n"
512 "\n"
513 "This implementation calculates the TPI for different scales and integrates these into one "
514 "single grid. The hierarchical integration is achieved by starting with the standardized "
515 "TPI values of the largest scale, then adding standardized values from smaller scales "
516 "where the (absolute) values from the smaller scale exceed those from the larger scale. "
517 "This integration scheme has been proposed by N. Zimmermann."
518 ));
519
520 Add_Reference(
521 "Guisan, A., Weiss, S.B., Weiss, A.D.", "1999",
522 "GLM versus CCA spatial modeling of plant species distribution",
523 "Plant Ecology 143: 107-122."
524 );
525
526 Add_Reference(
527 "Weiss, A.D.", "2000",
528 "Topographic Position and Landforms Analysis",
529 "Poster", SG_T("http://www.jennessent.com/downloads/tpi-poster-tnc_18x22.pdf")
530 );
531
532 Add_Reference(
533 "Wilson, J.P. & Gallant, J.C.", "2000",
534 "Primary Topographic Attributes",
535 "In: Wilson, J.P. & Gallant, J.C. [Eds.]: Terrain Analysis: Principles and Applications, John Wiley & Sons, p.51-85."
536 );
537
538 Add_Reference(
539 "www.wsl.ch/staff/niklaus.zimmermann/programs/aml4_1.html",
540 SG_T("toposcale.aml script by N.Zimmermann")
541 );
542
543 //-----------------------------------------------------
544 Parameters.Add_Grid(
545 "", "DEM" , _TL("Elevation"),
546 _TL(""),
547 PARAMETER_INPUT
548 );
549
550 Parameters.Add_Grid(
551 "", "TPI" , _TL("Topographic Position Index"),
552 _TL(""),
553 PARAMETER_OUTPUT
554 );
555
556 Parameters.Add_Int(
557 "", "SCALE_MIN" , _TL("Minimum Scale"),
558 _TL("kernel radius in cells"),
559 1, 1, true
560 );
561
562 Parameters.Add_Int(
563 "", "SCALE_MAX" , _TL("Maximum Scale"),
564 _TL("kernel radius in cells"),
565 8, 1, true
566 );
567
568 Parameters.Add_Int(
569 "", "SCALE_NUM" , _TL("Number of Scales"),
570 _TL(""),
571 3, 2, true
572 );
573
574 Parameters.Add_Bool(
575 "", "UPDATE" , _TL("Update"),
576 _TL("update view for each integration step"),
577 false
578 )->Set_UseInCMD(false);
579 }
580
581
582 ///////////////////////////////////////////////////////////
583 // //
584 ///////////////////////////////////////////////////////////
585
586 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter)587 int CTPI_MultiScale::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
588 {
589 if( pParameter->Cmp_Identifier("SCALE_MIN") )
590 {
591 if( pParameter->asInt() > pParameters->Get_Parameter("SCALE_MAX")->asInt() )
592 {
593 pParameter->Set_Value(pParameters->Get_Parameter("SCALE_MAX")->asInt());
594 }
595 }
596
597 if( pParameter->Cmp_Identifier("SCALE_MAX") )
598 {
599 if( pParameter->asInt() < pParameters->Get_Parameter("SCALE_MIN")->asInt() )
600 {
601 pParameter->Set_Value(pParameters->Get_Parameter("SCALE_MIN")->asInt());
602 }
603 }
604
605 //-----------------------------------------------------
606 int Range = pParameters->Get_Parameter("SCALE_MAX")->asInt()
607 - pParameters->Get_Parameter("SCALE_MIN")->asInt();
608
609 if( Range > 0 && Range + 1 < pParameters->Get_Parameter("SCALE_NUM")->asInt() )
610 {
611 pParameters->Set_Parameter("SCALE_NUM", Range + 1);
612 }
613
614 //-----------------------------------------------------
615 return( CSG_Tool_Grid::On_Parameter_Changed(pParameters, pParameter) );
616 }
617
618 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)619 int CTPI_MultiScale::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
620 {
621 pParameters->Set_Enabled("SCALE_NUM",
622 pParameters->Get_Parameter("SCALE_MIN")->asInt() <
623 pParameters->Get_Parameter("SCALE_MAX")->asInt()
624 );
625
626 //-----------------------------------------------------
627 return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
628 }
629
630
631 ///////////////////////////////////////////////////////////
632 // //
633 ///////////////////////////////////////////////////////////
634
635 //---------------------------------------------------------
On_Execute(void)636 bool CTPI_MultiScale::On_Execute(void)
637 {
638 //-----------------------------------------------------
639 int Scale_Min = Parameters("SCALE_MIN")->asInt();
640 int Scale_Max = Parameters("SCALE_MAX")->asInt();
641 int nScales = Parameters("SCALE_NUM")->asInt();
642
643 if( Scale_Min > Scale_Max || nScales < 2 )
644 {
645 Error_Fmt("%s (min=%d, max=%d, num=%d)", _TL("invalid parameters"), Scale_Min, Scale_Max, nScales);
646
647 return( false );
648 }
649
650 double Scale = Get_Cellsize() * Scale_Max;
651 double dScale = Get_Cellsize() * (Scale_Max - Scale_Min) / (nScales - 1.);
652
653 if( dScale <= 0. )
654 {
655 nScales = 1;
656 }
657
658 //-----------------------------------------------------
659 CSG_Grid TPI(Get_System()), *pTPI = Parameters("TPI")->asGrid();
660
661 CTPI Calculator; Calculator.Set_Manager(NULL);
662
663 Calculator.Set_Parameter("DEM" , Parameters("DEM")->asGrid());
664 Calculator.Set_Parameter("TPI" , pTPI);
665 Calculator.Set_Parameter("STANDARD", true);
666
667 Calculator.Get_Parameters()->Get_Parameter("RADIUS")->asRange()->Set_Min( 0.);
668 Calculator.Get_Parameters()->Get_Parameter("RADIUS")->asRange()->Set_Max(Scale);
669
670 Process_Set_Text( "%s: %.*f [%d/%d]", _TL("Scale"), SG_Get_Significant_Decimals(Scale), Scale, 1, nScales);
671 Message_Fmt ("\n%s: %.*f [%d/%d]", _TL("Scale"), SG_Get_Significant_Decimals(Scale), Scale, 1, nScales);
672
673 SG_UI_Msg_Lock(true);
674 Calculator.Execute();
675 SG_UI_Msg_Lock(false);
676
677 Calculator.Set_Parameter("TPI", &TPI);
678
679 //-----------------------------------------------------
680 for(int iScale=1; iScale<nScales && Process_Get_Okay(); iScale++)
681 {
682 if( Parameters("UPDATE")->asBool() )
683 {
684 DataObject_Update(pTPI);
685 }
686
687 (*Calculator.Get_Parameters())("RADIUS")->asRange()->Set_Max(Scale = Scale - dScale);
688
689 Process_Set_Text( "%s: %.*f [%d/%d]", _TL("Scale"), SG_Get_Significant_Decimals(Scale), Scale, 1 + iScale, nScales);
690 Message_Fmt ("\n%s: %.*f [%d/%d]", _TL("Scale"), SG_Get_Significant_Decimals(Scale), Scale, 1 + iScale, nScales);
691
692 SG_UI_Msg_Lock(true);
693 Calculator.Execute();
694 SG_UI_Msg_Lock(false);
695
696 //-------------------------------------------------
697 #pragma omp parallel for
698 for(int y=0; y<Get_NY(); y++)
699 {
700 for(int x=0; x<Get_NX(); x++)
701 {
702 if( !pTPI->is_NoData(x, y) && fabs(pTPI->asDouble(x, y)) < fabs(TPI.asDouble(x, y)) )
703 {
704 pTPI->Set_Value(x, y, TPI.asDouble(x, y));
705 }
706 }
707 }
708 }
709
710 //-----------------------------------------------------
711 return( true );
712 }
713
714
715 ///////////////////////////////////////////////////////////
716 // //
717 // //
718 // //
719 ///////////////////////////////////////////////////////////
720
721 //---------------------------------------------------------
722