-
Notifications
You must be signed in to change notification settings - Fork 0
/
LSDRaster.hpp
1292 lines (1190 loc) · 56.3 KB
/
LSDRaster.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// LSDRaster
// Land Surface Dynamics Raster
//
// An object within the University
// of Edinburgh Land Surface Dynamics group topographic toolbox
// for manipulating
// and analysing raster data, with a particular focus on topography
//
// Developed by:
// Simon M. Mudd
// Martin D. Hurst
// David T. Milodowski
// Stuart W.D. Grieve
// Declan A. Valters
// Fiona Clubb
//
// Copyright (C) 2013 Simon M. Mudd 2013
//
// Developer can be contacted by simon.m.mudd _at_ ed.ac.uk
//
// Simon Mudd
// University of Edinburgh
// School of GeoSciences
// Drummond Street
// Edinburgh, EH8 9XP
// Scotland
// United Kingdom
//
// This program is free software;
// you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;
// without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the
// GNU General Public License along with this program;
// if not, write to:
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301
// USA
//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/** @file LSDRaster.hpp
@author Simon M. Mudd, University of Edinburgh
@author David Milodowski, University of Edinburgh
@author Martin D. Hurst, British Geological Survey
@author Stuart W. D. Grieve, University of Edinburgh
@author Fiona Clubb, University of Edinburgh
@version Version 1.0.0
@brief Main analysis object to interface with other LSD objects.
@details This object contains a diverse range of geomophological
analysis routines which can be used in conjunction with the other objects in
the package.
<b>change log</b>an
MASSIVE MERGE: Starting version 1.0.0 on 15/07/2013
@date 16/07/2013
*/
/**
@mainpage
This is the documentation for Edinburgh Topographic Analysis Package (ETAP),
incorporating LSDRaster.
These pages will help you get started using this software.
\image html ./logo.png
Tools are included to:
- Generate topographic metrics
- Perform Chi analysis
- And other important science stuff
.
@author Simon M. Mudd, University of Edinburgh
@author David Milodowski, University of Edinburgh
@author Martin D. Hurst, British Geological Survey
@author Stuart W. D. Grieve, University of Edinburgh
@author Fiona Clubb, University of Edinburgh
*/
//-----------------------------------------------------------------
//DOCUMENTATION URL: http://www.geos.ed.ac.uk/~s0675405/LSD_Docs/
//-----------------------------------------------------------------
#include <string>
#include <vector>
#include "TNT/tnt.h"
#include "LSDIndexRaster.hpp"
using namespace std;
using namespace TNT;
#ifndef LSDRaster_H
#define LSDRaster_H
///@brief Main analysis object to interface with other LSD objects.
class LSDRaster
{
public:
// declare the LSDFlowInfo object to be a friend class
// this gives the LSDFlowInfo object access to the data elements
// in the LSDRaster
/// @brief Object to perform flow routing.
friend class LSDFlowInfo;
/// @brief The create function. This is default and throws an error.
LSDRaster() { create(); }
/// @brief Create an LSDRaster from a file.
/// Uses a filename and file extension
/// @return LSDRaster
/// @param filename A String, the file to be loaded.
/// @param extension A String, the file extension to be loaded.
LSDRaster(string filename, string extension) { create(filename, extension); }
/// @brief Create an LSDRaster from memory.
/// @return LSDRaster
/// @param nrows An integer of the number of rows.
/// @param ncols An integer of the number of columns.
/// @param xmin A float of the minimum X coordinate.
/// @param ymin A float of the minimum Y coordinate.
/// @param cellsize A float of the cellsize.
/// @param ndv An integer of the no data value.
/// @param data An Array2D of floats in the shape nrows*ncols,
///containing the data to be written.
LSDRaster(int nrows, int ncols, float xmin, float ymin,
float cellsize, float ndv, Array2D<float> data)
{ create(nrows, ncols, xmin, ymin, cellsize, ndv, data); }
// Get functions
/// @return Number of rows as an integer.
int get_NRows() const { return NRows; }
/// @return Number of columns as an integer.
int get_NCols() const { return NCols; }
/// @return Minimum X coordinate as an integer.
float get_XMinimum() const { return XMinimum; }
/// @return Minimum Y coordinate as an integer.
float get_YMinimum() const { return YMinimum; }
/// @return Data resolution as an integer.
float get_DataResolution() const { return DataResolution; }
/// @return No Data Value as an integer.
int get_NoDataValue() const { return NoDataValue; }
/// @return Raster values as a 2D Array.
Array2D<float> get_RasterData() const { return RasterData.copy(); }
/// Assignment operator.
LSDRaster& operator=(const LSDRaster& LSDR);
/// @brief Read a raster into memory from a file.
///
/// The supported formats are .asc and .flt which are
/// both exported and imported by arcmap.
///
/// The filename is the string of characters before the '.' in the extension
/// and the extension is the characters after the '.'.
///
/// If the full filename is my_dem.01.asc then:
/// filename = "my_dem.01" and extension = "asc".
///
///
/// For float files both a data file and a header are read
/// the header file must have the same filename, before extention, of
/// the raster data, and the extension must be .hdr.
///
/// @author SMM
/// @date 01/01/12
void read_raster(string filename, string extension);
/// @brief Read a raster from memory to a file.
///
/// The supported formats are .asc and .flt which are
/// both exported and imported by arcmap.
///
/// The filename is the string of characters before the '.' in the extension
/// and the extension is the characters after the '.'.
///
/// If the full filename is my_dem.01.asc then:
/// filename = "my_dem.01" and extension = "asc".
///
/// For float files both a data file and a header are written
/// the header file must have the same filename, before extention, of
/// the raster data, and the extension must be .hdr.
///
/// @param filename a string of the filename _without_ the extension.
/// @param extension a string of the extension _without_ the leading dot
/// @author SMM
/// @date 01/01/12
void write_raster(string filename, string extension);
/// @brief rewrite all the data array values with random numbers (with a
/// uniform distribution).
/// @param range is the range of values.
/// @author SMM
/// @date 18/02/14
void rewrite_with_random_values(float range);
/// @brief Calculate the minimum bounding rectangle for an LSDRaster Object and crop out
/// all the surrounding NoDataValues to reduce the size and load times of output rasters.
///
/// @details Ideal for use with chi analysis tools which output basin and chi m value rasters
/// which can be predominantly no data. As an example, a 253 Mb file can be reduced to
/// ~5 Mb with no loss or resampling of data.
///
/// @return A trimmed LSDRaster object.
/// @author SWDG
/// @date 22/08/13
LSDRaster RasterTrimmer();
/// @brief Make LSDRaster object using a 'template' raster and an Array2D of data.
/// @param InputData 2DArray of floats to be written to LSDRaster.
/// @return LSDRaster containing the data passed in.
/// @author SWDG
/// @date 29/8/13
LSDRaster LSDRasterTemplate(Array2D<float> InputData);
// Functions for the Diamond Square algorithm
/// @brief This returns a value from the array data element but wraps around
/// the array dimensions so that row > NRows (for example) returns a value.
/// @param The row of the data point you want.
/// @parame Column of desired data point.
/// @return The value of the data array at the desired row and column.
/// @author SMM
/// @date 16/02/2014
float WrapSample(int row, int col);
/// @brief This sets a value in the data array withthe added feature that it
/// wraps beyond NRows and NCols.
/// @param The row of data to be reset.
/// @param The column of the data to be reset.
/// @param The value of the data to be reset.
/// @author SMM
/// @date 16/02/2014
void SetWrapSample(int row, int col, float value);
/// @brief This sets the corners of features as the first step in the diamond
/// square algorithm.
/// @param The first parameter is the feature size. This needs to be a power of 2, but
/// this is set by the parent DiamondSquare function (that is, this function should not
/// be called independantly.
/// @param The scale is effectivly the maximum relief of the surface to be produced by the
/// algorithm.
/// @author SMM
/// @date 16/02/2014
void DSSetFeatureCorners(int featuresize, float scale);
/// @brief This is the square sampling step of the diamond square algorithm: it takes
/// the average of the four corners and adds a random number to set the centrepoint
/// of a square.
/// @param The row of the centrepoint.
/// @param The column of the centrepoint.
/// @param The size of this square (in pixels, must be divisible by 2).
/// @param The random value added to the average of the four corners.
/// @author SMM
/// @date 16/02/2014
void DSSampleSquare(int row,int col, int size, float value);
/// @brief This is the diamond sampling step of the diamond square algorithm: it takes
/// the average of the four corners and adds a random number to set the centrepoint
/// of a diamond.
/// @param The row of the centrepoint.
/// @param The column of the centrepoint.
/// @param The size of this diamond (in pixels, must be divisible by 2).
/// @param The random value added to the average of teh four corners.
/// @author SMM
/// @date 16/02/2014
void DSSampleDiamond(int row, int col, int size, float value);
/// @brief This is the sampling function for the diamond square algorithm: it
/// runs both a diamond and a square sampling for each step.
///
/// @param The stepsize, which is the size of the diamonds and the squares.
/// @param The scale which sets the maxmum relief within a particular square or
/// diamond and is scaled by the stepsize (that is smaller squares have smaller scales).
///
/// @author SMM
/// @date 16/02/2014
void DiamondSquare_SampleStep(int stepsize, float scale);
/// @brief This is the driving function for the diamond square algorithm.
/// @details The driving function takes the current raster and then pads it
/// in each direction to have rows and columns that are the nearest powers
/// of 2. The xllocation and yllocation data values are preserved. The function
/// returns a pseudo fractal landscape generated with the diamond square algorithm
///
/// @param feature order is an interger n where the feature size consists of 2^n nodes.
/// If the feature order is set bigger than the dimensions of the parent raster then
/// this will default to the order of the parent raster.
/// @param Scale is a floating point number that sets the maximum relief of the resultant raster.
/// @return Returns a diamond square pseudo-fractal surface in and LSDRaster object.
/// @author SMM
/// @date 16/02/2014
LSDRaster DiamondSquare(int feature_order, float scale);
// Functions relating to shading, shadowing and shielding
/// @brief This function generates a hillshade raster.
///
/// It uses the the algorithm outlined in Burrough and McDonnell Principles
/// of GIS (1990) and in the ArcMap web help
/// http://edndoc.esri.com/arcobjects/9.2/net/shared/geoprocessing/
/// spatial_analyst_tools/how_hillshade_works.htm
///
/// Default values are altitude = 45, azimuth = 315, z_factor = 1
/// @param altitude of the illumination source in degrees.
/// @param azimuth of the illumination source in degrees
/// @param z_factor Scaling factor between vertical and horizontal.
/// @return Hillshaded LSDRaster object
/// @author SWDG
/// @date February 2013
LSDRaster hillshade(float altitude, float azimuth, float z_factor);
/// @brief This function generates a hillshade derivative raster using the
/// algorithm outlined in Codilean (2006).
///
/// @details It identifies areas in shadow as 1 and all other values as 0. Is
/// interfaced through LSDRaster::TopoShield and should not be called directly,
/// to generate a hillshade use LSDRaster::hillshade instead.
/// @param theta The zenith angle of the illumination source in degrees.
/// @param phi The azimuth angle of the illumination source in degrees.
/// @return 2D Array of floats.
/// @author SWDG
/// @date 11/4/13
Array2D<float> Shadow(int theta, int phi);
/// @brief This function generates a topographic shielding raster using the algorithm outlined in Codilean (2006).
///
/// @details Creating a raster of values between 0 and 1 which can be used as a
/// scaling factor in Cosmo analysis.
///
/// Goes further than the original algorithm allowing a theoretical theta,
/// phi pair of 1,1 to be supplied and although this will increase the
/// computation time significantly, it is much faster than the original
/// Avenue and VBScript implementations.
///
/// Takes 2 ints, representing the theta, phi paring required.
/// Codilean (2006) used 5,5 as the standard values, but in reality values of
/// 10,15 are often preferred to save processing time.
/// @param theta_step Spacing of sampled theta values.
/// @param phi_step Spacing of sampled phi values.
/// @pre phi_step must be a factor of 360.
/// @author SWDG
/// @date 11/4/13
LSDRaster TopoShield(int theta_step, int phi_step);
/// @brief This looks for isolated instances of no data.
///
/// Does nothing else but print their location to the screen.
/// @author MDH, DTM
/// @date 01/01/12
void check_isolated_nodata();
/// @brief Get the raster data at a specified location.
/// @param row An integer, the X coordinate of the target cell.
/// @param column An integer, the Y coordinate of the target cell.
/// @return The raster value at the position (row, column).
/// @author SMM
/// @date 01/01/12
float get_data_element(int row, int column) { return RasterData[row][column]; }
/// @brief Surface polynomial fitting and extraction of topographic metrics
///
/// @detail A six term polynomial surface is fitted to all the points that lie
/// within circular neighbourhood that is defined by the designated window
/// radius. The user also inputs a binary raster, which tells the program
/// which rasters it wants to create (label as "1" to produce them, "0" to
/// ignore them. This has 8 elements, as listed below:
/// 0 -> Elevation (smoothed by surface fitting)
/// 1 -> Slope
/// 2 -> Aspect
/// 3 -> Curvature
/// 4 -> Planform Curvature
/// 5 -> Profile Curvature
/// 6 -> Tangential Curvature
/// 8 -> Stationary point classification (1=peak, 2=depression, 3=saddle)
/// The program returns a vector of LSDRasters. For options marked "false" in
/// boolean input raster, the returned LSDRaster houses a blank raster, as this
/// metric has not been calculated. The desired LSDRaster can be retrieved from
/// the output vector by using the cell reference shown in the list above i.e. it
/// is the same as the reference in the input boolean vector.
/// @param window_radius -> the radius of the circular window over which to
/// fit the surface
/// @param raster_selection -> a binary raster, with 8 elements, which
/// identifies which metrics you want to calculate.
/// @return A vector of LSDRaster objects. Those that you have not asked to
/// be calculated are returned as a 1x1 Raster housing a NoDataValue
///
/// @author DTM
/// @date 28/03/2014
vector<LSDRaster> calculate_polyfit_surface_metrics(float window_radius, vector<int> raster_selection);
/// @brief Surface polynomial fitting and extraction of roughness metrics
///
/// @detail
/// A six term polynomial surface is fitted to all the points that lie within
/// circular neighbourhood that is defined by the designated window radius.
/// This surface is used to determine the orientation of the surface normal
/// vector at each cell. The algorithm then searches through the grid again,
/// using a second search window to look for the local variability in normal
/// vector orientation. The user also inputs a binary raster, which tells the
/// program which rasters it wants to create (label as "1" to produce them,
/// "0" to ignore them. This has 3 elements, as listed below:
/// 0 -> s1 -> describes clustering of normals around the major axis
/// 1 -> s2 -> describes clustering of normals around semi major axis
/// 2 -> s3 -> describes clustering around minor axis
/// The program returns a vector of LSDRasters. For options marked "0" in
/// binary input raster, the returned LSDRaster houses a blank raster, as this
/// metric has not been calculated. The desired LSDRaster can be retrieved from
/// the output vector by using the same cell reference shown in the list above
/// i.e. it is the same as the reference in the input binary vector.
/// @param window_radius1 -> the radius of the circular window over which to
/// fit the surface
/// @param window_radius2 -> the radius of the circular window over which to
/// look for local variability of surface normal orientation
/// @param raster_selection -> a binary raster, with 3 elements, which
/// identifies which metrics you want to calculate.
/// @return A vector of LSDRaster objects. Those that you have not asked to
/// be calculated are returned as a 1x1 Raster housing a NoDataValue
///
/// @author DTM
/// @date 01/04/2014
vector<LSDRaster> calculate_polyfit_roughness_metrics(float window_radius1, float window_radius2, vector<int> raster_selection);
// this calculates coefficeint matrices for calculating a variety of
// surface metrics such as slope, aspect, curvature, etc.
/// @brief This function calculates 6 coefficient matrices that allow the user to
/// then calcualte slope, curvature, aspect, a classification for finding saddles and peaks
/// and other metrics.
///
/// @details The coefficient matrices are overwritten during the running of this member function.
///
/// Have N simultaneous linear equations, and N unknowns.
/// => b = Ax, where x is a 1xN array containing the coefficients we need for
/// surface fitting.
/// A is constructed using different combinations of x and y, thus we only need
/// to compute this once, since the window size does not change.
/// For 2nd order surface fitting, there are 6 coefficients, therefore A is a
/// 6x6 matrix.
/// Updated 15/07/2013 to use a circular mask for surface fitting - DTM.
/// Updated 24/07/2013 to check window_radius size and correct values below data resolution - SWDG.
/// @param window_radius Radius of the mask in <b>spatial units</b>.
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @param c coefficeint c.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @param f coefficeint f.
/// @author DTM, SMM
/// @date 01/01/12
void calculate_polyfit_coefficient_matrices(float window_radius,
Array2D<float>& a, Array2D<float>& b,
Array2D<float>& c, Array2D<float>& d,
Array2D<float>& e, Array2D<float>& f);
// a series of functions for retrieving derived data from the polyfit calculations
/// @brief This function calculates the elevation based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param f coefficeint f.
/// @return LSDRaster of elevations.
/// @author FC
/// @date 24/03/13
LSDRaster calculate_polyfit_elevation(Array2D<float>& f);
/// @brief This function calculates the slope based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of slope.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_slope(Array2D<float>& d, Array2D<float>& e);
/// @brief This function calculates the aspect based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of aspect.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_aspect(Array2D<float>& d,Array2D<float>& e);
/// @brief This function calculates the curvature based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @return LSDRaster of curvature.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_curvature(Array2D<float>& a,Array2D<float>& b);
/// @brief This function calculates the planform curvature based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @param c coefficeint c.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of planform curvature.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_planform_curvature(Array2D<float>& a, Array2D<float>& b, Array2D<float>& c,
Array2D<float>& d, Array2D<float>& e);
/// @brief This function calculates the profile curvature based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @param c coefficeint c.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of profile curvature.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_profile_curvature(Array2D<float>& a, Array2D<float>& b, Array2D<float>& c,
Array2D<float>& d, Array2D<float>& e);
/// @brief This function calculates the tangential curvature based on a polynomial fit.
///
/// @details the window is determined by the calculate_polyfit_coefficient_matrices
/// this function also calculates the a,b,c,d,e and f coefficient matrices.
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @param c coefficeint c.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of tangential curvature.
/// @author DTM, SMM
/// @date 01/01/12
LSDRaster calculate_polyfit_tangential_curvature(Array2D<float>& a, Array2D<float>& b, Array2D<float>& c,
Array2D<float>& d, Array2D<float>& e);
/// @brief This function identifies approximate position of stationary points within
/// discrete surface using a threshold slope.
///
/// @details The nature of the stationary point is then determined to discriminate
/// peaks, depressions and saddles. \n
/// 0 = Non-stationary \n
/// 1 = Peak \n
/// 2 = Depression \n
/// 3 = Saddle \n
/// @param a coefficeint a.
/// @param b coefficeint b.
/// @param c coefficeint c.
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @return LSDRaster of classified elevation data.
/// @author DTM
/// @date 17/09/2012
LSDIndexRaster calculate_polyfit_classification(Array2D<float>& a, Array2D<float>& b, Array2D<float>& c,
Array2D<float>& d, Array2D<float>& e);
/// @brief Gets the hilltop curvature raster.
///
/// @details Modified to take an LSDRaster of hilltops - SWDG 29/8/13
///
/// @param curvature LSDRaster of curvatures.
/// @param Hilltops LSDRaster of hilltops.
/// @return LSDRaster of hilltop curvatures.
/// @author DTM
/// @date 30/04/13
LSDRaster get_hilltop_curvature(LSDRaster& curvature, LSDRaster& Hilltops);
/// @brief Removes positive hilltop curvature values
///
/// @details Modifies the hilltop curvature raster to remove pixels with
/// positive curvature caused by noise
/// @param hilltop_curvature hilltop curvature input raster
/// @return LSDRaster of hilltop curvature with positive values removed
/// @author FJC
/// @date 24/03/14
LSDRaster remove_positive_hilltop_curvature(LSDRaster& hilltop_curvature);
// surface roughness
/// @brief Algorithm that assesses surface roughness based on a polynomial fit.
///
/// @details Runs a moving window across the DEM and assesses the variability of
/// surface normals within that window. Specifically the components of the
/// normals are combined into an orientation matrix, which is then solved to
/// find the eigenvalues s1, s2, s3 (Woodcock, 1977).
/// @param d coefficeint d.
/// @param e coefficeint e.
/// @param l coefficeint l.
/// @param m coefficeint m.
/// @param n coefficeint n.
/// @author DTM
/// @date 13/09/2012
void calculate_polyfit_directional_cosines(Array2D<float>& d, Array2D<float>& e, Array2D<float>& l,
Array2D<float>& m, Array2D<float>& n);
/// @brief Find eigenvalues for orientation matrix
/// @param window_radius
/// @param l coefficeint l.
/// @param m coefficeint m.
/// @param n coefficeint n.
/// @param s1 coefficeint s1.
/// @param s2 coefficeint s2.
/// @param s3 coefficeint s3.
/// @author DTM
/// @date 13/09/2012
void calculate_orientation_matrix_eigenvalues(float window_radius,
Array2D<float>& l, Array2D<float>& m,
Array2D<float>& n, Array2D<float>& s1,
Array2D<float>& s2, Array2D<float>& s3);
// Rock exposure index / roughness
/// @brief This function is a wrapper to get the three roughness eigenvalues
/// s1, s2 and s3.
/// @param window_radius
/// @param a_plane
/// @param b_plane
/// @param c_plane
/// @author DTM
/// @date 15/7/2013
void calculate_plane_coefficient_matrices(float window_radius, Array2D<float>& a_plane,
Array2D<float>& b_plane, Array2D<float>& c_plane);
/// @brief Create the REI raster
///
/// @details
/// @param a_plane
/// @param b_plane
/// @param CriticalSlope
/// @return LSDIndexRaster of rock exposure.
/// @author DTM
LSDRaster calculate_REI(Array2D<float>& a_plane, Array2D<float>& b_plane, float CriticalSlope);
/// @brief Create the REI raster (imporoved wrapper)
/// Rock exposure index defined as areas with local slope exceeding some
/// critical slope as defined by DiBiase et al. (2012)
/// @details
/// @param window radius
/// @param CriticalSlope
/// @return LSDIndexRaster of rock exposure.
/// @author DTM
LSDRaster calculate_REI(float window_radius, float CriticalSlope);
/// @brief this function takes the polyfit functions and requires a window radius and a vector telling the
/// function which rasters to print to file.
///
/// @details The function is data efficient since one does not need to
/// recalculate the polyfit coefficeint matrices. It also takes a string
/// which is the prename of the data files the file codes in the vector are:\n
/// 0 slope \n
/// 1 aspect \n
/// 2 curvature \n
/// 3 planform curvature\n
/// 4 profile curvature \n
/// 6 tangential curvature \n
/// 7 classification \n
/// @param window_radius Radius of the mask.
/// @param file_prefix Output filename string.
/// @param file_list Vector of files to be created.
/// @author SMM
/// @date 19-12-2012
void calculate_and_print_polyfit_rasters(float window_radius,
string file_prefix, vector<int> file_list);
// this function combines the polyfit functions and the roughness function in one package that
// is data efficient becasue it only requires one calcualtion of the polyfit matrices.
// it takes the window radius of the polyfit and the window of the roughness calcualtion
// the file codes in the vector are:
// 0 slope
// 1 aspect
// 2 curvature
// 3 planform curvature
// 4 profile curvature
// 6 tangential curvature
// 7 classification
// 8 roughness s1
// 9 roughness s2
// 10 roughness s3
// SMM 19-12-2012
/// @brief This function takes the combines the polyfit functions and the roughness function in one package.
///
/// @details The function is data efficient since one does not need to
/// recalculate the polyfit coefficeint matrices. Itakes the window radius of
/// the polyfit and the window of the roughness calculation the file codes in
/// the vector are:\n
/// 0 slope \n
/// 1 aspect \n
/// 2 curvature \n
/// 3 planform curvature\n
/// 4 profile curvature \n
/// 6 tangential curvature \n
/// 7 classification \n
/// 8 roughness s1 \n
/// 9 roughness s2 \n
/// 10 roughness s3 \n
/// @param window_radius Radius of the mask.
/// @param roughness_radius Radius of the roughness window.
/// @param file_prefix Output filename string.
/// @param file_list Vector of files to be created.
/// @author SMM
/// @date 19-12-2012
void calculate_and_print_polyfit_and_roughness_rasters(float window_radius, float roughness_radius,
string file_prefix, vector<int> file_list);
// this function combines the polyfit functions and the roughness function in one package that
// is data efficient becasue it only requires one calculation of the polyfit matrices.
// it takes the window radius of the polyfit and the window of the roughness calcualtion
// the file codes in the vector are:
// 0 roughness s1
// 1 roughness s2
// 2 roughness s3
// DTM 15-07-2013
/// @brief This function takes the combines the roughness functions in one package.
///
/// @details The function is data efficient since one does not need to
/// recalculate the polyfit coefficeint matrices. I takes the window radius of
/// the polyfit and the window of the roughness calculation the file codes in
/// the vector are:\n
/// 0 roughness s1 \n
/// 1 roughness s2 \n
/// 2 roughness s3 \n
/// @param window_radius Radius of the mask.
/// @param roughness_radius Radius of the roughness window.
/// @param file_prefix Output filename string.
/// @param file_code Vector of files to be created.
/// @author DTM
/// @date 15-07-2013
void calculate_roughness_rasters(float window_radius, float roughness_radius, string file_prefix, vector<int> file_code);
// hydrology tools
///@brief This function fills pits/sinks in a DEM by incrementing elevations for cells with
///no downslope neighbour. The process is repeated adnausium until no cells require
///incrementing.
///
///Inputs required are a DEM file in ascii raster format as created by ARCMap
///and a file name to create a filled DEM grid.
///
///This code was built ontop of code made available by Jon D. Pelletier as part
///of his book:
///
///Pelletier,J.D.,'Quantitative Modelling of Landscapes' Cambridge University Press
///
///---------------------------------------------------------------------------------
///
/// v1.3 reduced fill increment to 1mm to avoid 'overfilling'
///
/// Martin Hurst, October 2011
///
///---------------------------------------------------------------------------------
///
/// v1.2 modified to read *.flt files
///
/// Martin Hurst, November 2010
///
///---------------------------------------------------------------------------------
///
/// v1.1 function incorporated to allow the tool to fill adjacent pixels immediately
/// after filling a given pixel, should speed things up.
///
/// Martin Hurst, October 2010
///
///---------------------------------------------------------------------------------
///
/// v1.0 is slow as it requires many iterations through the dem
///
/// Martin Hurst, June 2010
/// @return Filled LSDRaster.
/// @author MDH
/// @date 01/06/10
LSDRaster fill();
/// @brief This is a recursive algorithm that is called by the fill function.
/// @param fill_data
/// @param i
/// @param j
/// @author MDH
/// @date 01/06/10
void fill_iterator(Array2D<float>& fill_data, int i, int j);
/// @brief This function fills pits/sinks in a DEM by checking for pits from
///lowest to highest elevation, starting at the DEM boundary (raster edge or
/// adjacent to NDVs).
///
/// @details Utilises a priority queue to progressively populate the stack and
/// pop out the the lowest value before checking that the neighbouring cells
/// that are yet to be visited must be higher in a hydrologically correct DEM.
/// This method is substantially faster on datasets with pits consisting of
/// multiple cells since each cell only needs to be visited once.
///
/// Method taken from Wang and Liu (2006), Int. J. of GIS. 20(2), 193-213
/// @param MinSlope The minimum slope between two Nodes once filled. If set
/// to zero will create flats.
/// @return Filled LSDRaster object.
/// @author Martin Hurst
/// @date 12/3/13
LSDRaster fill(float& MinSlope);
// multidirection flow routing
/// @brief Generate a flow area raster using a multi direction algorithm.
///
/// @details Computes the proportion of all downslope flows for each cell in
/// the input DEM and routes the flow accordingly. Consequently the dem is
/// sorted and indexed using LSDStatsTools. Can handle DEMs containing flats,
/// but pits must be filled using the new LSDRaster fill.
///
/// Currently only works with periodic boundaries. Function built around
/// original c++ code by Martin Hurst.
/// @param BoundaryConditions Vector as in LSDFlowInfo object.
/// @return LSDRaster of flow area.
/// @author SWDG
/// @date 18/4/13 - 24/4/13
LSDRaster MDFlow(vector<string> BoundaryConditions);
/// @brief Generate a flow area raster using a multi direction algorithm.
///
/// @details Computes the proportion of all downslope flows for each cell in the input
/// DEM, and weights them using the equation from Freeman et al 1991 and routes the
/// flow accordingly.
///
/// Paper link: http://www.sciencedirect.com/science/article/pii/009830049190048I
///
/// Cardinal Weighting = (elevation_drop/total_elevation_drop)^1.1 \n
/// Diagonal Weighting = ((elevation_drop/total_elevation_drop)*(1/root(2)))^1.1
///
/// Can <b>NOT</b> handle DEMs containing flats or pits - must be filled using the new
/// LSDRaster fill. Function built around original c++ code by Martin Hurst.
/// @return LSDRaster of flow area.
/// @author SWDG
/// @date 18/4/13
LSDRaster FreemanMDFlow();
/// @brief Route flow from one source pixel using FreemanMDFlow. Adapted from SWDG's
/// code above.
/// @param i_source -> the row index of the source pixel
/// @param j_source -> the column index of the source pixel
/// @author DTM
/// @date 07/11/2013
LSDRaster FreemanMDFlow_SingleSource(int i_source,int j_source);
/// @brief This is used to reduce a map of potential sources down to a simplified source
/// network for channel extraction by removing potential sources that are on ANY
/// downslope pathway from previous sources
/// @param source_row_vec -> vector of row indeces for potential source pixels
/// @param source_col_vec -> vector of column indeces for potential source pixels
/// @author DTM
/// @date 07/11/2013
LSDIndexRaster IdentifyFurthestUpstreamSourcesWithFreemanMDFlow(vector<int> source_row_vec,vector<int> source_col_vec);
/// @brief Generate a flow area raster using a multi direction algorithm.
///
/// @details Computes the proportion of all downslope flows for each cell in the input
/// DEM, and weights them using the equation from Quinn et al 1991 and routes the
/// flow accordingly.
///
/// Paper link: http://onlinelibrary.wiley.com/doi/10.1002/hyp.3360050106/abstract
///
/// Cardinal Weighting = (elevation_drop/total_elevation_drop)*DataResolution/2 \n
/// Diagonal Weighting = ((elevation_drop/total_elevation_drop)*(1/root(2)))* DataResolution*0.354
///
/// Can <b>NOT</b> handle DEMs containing flats or pits - must be filled using the new
/// LSDRaster fill. Function built around original c++ code by Martin Hurst.
/// @return LSDRaster of flow area.
/// @author SWDG
/// @date 18/4/13
LSDRaster QuinnMDFlow();
/// @brief Generate a flow area raster using a multi 2-direction algorithm.
///
/// @details Computes the proportion of all downslope flows for each cell in the input
/// DEM. Finds the cell of the steepest descent and then checks the two
/// neighbouring cells slopes. If either is also downslope proportion flow
/// between the steepest cell and the steepest neighbour. If neither neighbour
/// is downslope 100% of flow follows the steepest path.
///
/// Can <b>NOT</b> handle DEMs containing flats or pits - must be filled using the new
/// LSDRaster fill. Function built around original c++ code by Martin Hurst.
/// @return LSDRaster of flow area.
/// @author SWDG
/// @date 02/08/13
LSDRaster M2DFlow();
// channel head identification
/// @brief This function is used to predict channel head locations based on the method proposed by Pelletier (2013).
///
/// @details It creates a contour curvature map and identifies channel heads as pixels greater
/// than a user defined contour curvature threshold value, set by default at 0.1. The threshold curvature
/// can also be defined as a multiple of the standard deviation of the curvature. Before this function is called
/// the DEM must be filtered using the wiener filter in the LSDRasterSpectral object in order to remove high frequency
/// noise.
///
/// Reference: Pelletier (2013) A robust, two-parameter method for the extraction of drainage
/// networks from high-resolution digital elevation models (DEMs): Evaluation using synthetic and real-world
/// DEMs, Water Resources Research 49: 1-15
///
/// @param window_radius Integer window radius - suggest 6m.
/// @param tan_curv_threshold Double curvature threshold value.
/// @param tan_curv_array 2D array of tangential curvature.
/// @return LSDIndexRaster of predicted channel head locations.
/// @author FC, DTM
/// @date 07/11/13
LSDIndexRaster calculate_pelletier_channel_heads(float window_radius, float tan_curv_threshold, Array2D<float>& tan_curv_array);
// some tools associated with ridgeline analyis
/// @brief Module to sample LSDRaster values running along a ridgetop network.
///
/// @details Ridge network is generated from LSDJunctionNetwork::ExtractRidges.
/// @param Ridges 2D Array of ridge lines.
/// @return Sampled LSDRaster object.
/// @author SWDG
/// @date 04/2013
LSDRaster RidgeSample(Array2D<float>& Ridges);
/// @brief Pass a smoothing window over a ridge LSDRaster object to calculate
/// an average value running along the ridgetop.
/// @param WindowRadius optional integer smoothing radius between 1 and 6.
/// @pre Default smoothing radius is 2 and will revert to that value if a
/// radius outside the vaid range (1 to 6) is passed.
/// @return Averaged LSDRaster object.
/// @author SWDG
/// @date 04/2013
LSDRaster RidgeSmoother(int WindowRadius);
/// @brief Pass a buffer over a ridge LSDRaster object to increase sampling area.
///
/// @details Buffers equally in all directions, so use with care to avoid
/// sampling areas away from the axis of the original ridge line.
/// @param BufferRadius optional integer buffer radius between 1 and 6.
/// @pre Default buffer radius is 2 and will revert to that value if a
/// radius outside the vaid range (1 to 6) is passed.
/// @return LSDRaster object containing buffered ridges.
/// @author SWDG
/// @date 04/2013
LSDRaster RidgeBuffer(int BufferRadius);
/// @brief Module assigns an average LSDRaster value to each basin.
///
/// @details Works by searching for every hilltop value that falls within a
/// basin, summing these values and writing the final average to every cell
/// identified as the basin in question.
///
/// Very inefficent at present. Module loops through every cell in LSDRaster
/// (2 * number of basins) + 1 times. Beware!
/// @param Basins LSDIndexRaster of Drainage basins, generated using
/// ChannelNetwork::ExtractBasinsOrder.
/// \n\n Bug fixed in assignment of basin IDs - SWDG 2/9/13.
/// @return LSDRaster of average basin value for each identified basin.
/// @author SWDG
/// @date 04/2013
LSDRaster BasinAverager(LSDIndexRaster& Basins);
/// @brief Write the area(in spatial units) of each basin to the basin's pixels.
///
/// @details Big optimisation following the Drainage density's design pattern.
/// Works by flattening the raster into a 1D vector, sorting it and summing
/// each run of Basin IDs. Gives a fast count of the number of pixels per basin,
/// which is multiplied by the cellsize to get an area in spatial units.
/// @param Basins LSDIndexRaster of drainage basins to measure.
/// @return LSDRaster of basin areas.
/// @author SWDG
/// @date 20/11/2013
LSDRaster BasinArea(LSDIndexRaster Basins);
/// @brief Convert a basin, given by a basin ID, into a chain of xy coordinates for
/// fast plotting of vector basin outlines.
///
/// @details Produces a generalised polygon and will not cope well with complex geometries.
/// \n\n
/// Needs to be updated to write data into an esri ascii format so the files can
/// be loaded into arc. Currently writes to a text file called chain.txt.
/// @param Basins IndexRaster of basins
/// @param BasinOfInterest integer of the basin ID to be converted.
/// @author SWDG
/// @date 21/11/2013
void GetBasinVector(LSDIndexRaster Basins, int BasinOfInterest);
/// @brief Punch basins out of an LSDRaster to create DEMs of a single catchment.
///
/// @details Writes files in the user supplied format (flt or asc) and returns a vector
/// of LSDRasters so they can be loaded into other functions.
/// Updated 24/9/13 to return a vector of LSDRasters - SWDG.
/// @param basin_ids Vector of basins to punch out.
/// @param BasinArray Basin outlines used to punch out the LSDRasters.
/// @return Vector of output filenames.