-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLSDFlowInfo.hpp
1479 lines (1299 loc) · 67.8 KB
/
LSDFlowInfo.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
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// LSDFlowInfo
// Land Surface Dynamics FlowInfo
//
// An object within the University
// of Edinburgh Land Surface Dynamics group topographic toolbox
// for organizing flow routing under the Fastscape algorithm
// (see Braun and Willett, Geomorphology 2013, v180, p 170-179)
//
//
// 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 LSDFlowInfo.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
@brief Object to perform flow routing.
@details This is a data object which generates and then
stores information about flow routing.
It is the object that is used to generate contributing area, etc.
@date 29/08/2012
*/
//-----------------------------------------------------------------
//DOCUMENTATION URL: http://www.geos.ed.ac.uk/~s0675405/LSD_Docs/
//-----------------------------------------------------------------
#ifndef LSDFlowInfo_H
#define LSDFlowInfo_H
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include "TNT/tnt.h"
#include "LSDRaster.hpp"
#include "LSDIndexRaster.hpp"
using namespace std;
using namespace TNT;
// Sorting compiling problems with MSVC
#ifdef _WIN32
#ifndef M_PI
extern double M_PI;
#endif
#endif
/// @brief Object to perform flow routing.
class LSDFlowInfo
{
public:
/// @brief The create function. This is default and throws an error.
/// @author SMM
/// @date 01/016/12
LSDFlowInfo() { create(); }
/// @brief Creates a FlowInfo object from a binary flowinfo data.
/// @param fname String of the binary flowinfo data file to be read.
/// @author SMM
/// @date 01/016/12
LSDFlowInfo(string fname) { create(fname); }
/// @brief Creates a FlowInfo object from a binary flowinfo data.
/// @detail This assumes no flux boundaries
/// @param TopoRaster LSDRaster object containing the topographic data.
/// @author SMM
/// @date 3/07/2015
LSDFlowInfo(LSDRaster& TopoRaster)
{ create(TopoRaster); }
/// @brief Creates a FlowInfo object from topography.
/// @param BoundaryConditions Vector<string> of the boundary conditions at each edge of the
/// DEM file. Boundary conditions can start with 'P' or 'p' for periodic,
/// 'B' or 'b' for base level, or anything else for no flux.
/// the vector shold have 4 elements, 0 is north, 1 is east, 2 is south and 3 is west
/// @param TopoRaster LSDRaster object containing the topographic data.
/// @author SMM
/// @date 01/016/12
LSDFlowInfo(vector<string>& BoundaryConditions, LSDRaster& TopoRaster)
{ create(BoundaryConditions, TopoRaster); }
/// @brief Copy of the LSDJunctionNetwork description here when written.
friend class LSDJunctionNetwork;
// some functions for retrieving information out of the data vectors
/// @brief this function gets the UTM_zone and a boolean that is true if
/// the map is in the northern hemisphere
/// @param UTM_zone the UTM zone. Replaced in function.
/// @param is_North a boolean that is true if the DEM is in the northern hemisphere.
/// replaced in function
/// @author SMM
/// @date 22/12/2014
void get_UTM_information(int& UTM_zone, bool& is_North);
/// @brief this gets the x and y location of a node at row and column
/// @param row the row of the node
/// @param col the column of the node
/// @param x_loc the x location (Northing) of the node
/// @param y_loc the y location (Easting) of the node
/// @author SMM
/// @date 22/12/2014
void get_x_and_y_locations(int row, int col, double& x_loc, double& y_loc);
/// @brief this gets the x and y location of a node at row and column
/// @param row the row of the node
/// @param col the column of the node
/// @param x_loc the x location (Northing) of the node
/// @param y_loc the y location (Easting) of the node
/// @author SMM
/// @date 22/12/2014
void get_x_and_y_locations(int row, int col, float& x_loc, float& y_loc);
/// @brief a function to get the lat and long of a node in the raster
/// @detail Assumes WGS84 ellipsiod
/// @param row the row of the node
/// @param col the col of the node
/// @param lat the latitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param long the longitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param Converter a converter object (from LSDShapeTools)
/// @author SMM
/// @date 22/12/2014
void get_lat_and_long_locations(int row, int col, double& lat,
double& longitude, LSDCoordinateConverterLLandUTM Converter);
/// @brief a function to get the lat and long of a location provided as northing and easting
/// @detail Assumes WGS84 ellipsiod
/// @param X the Easting of the location
/// @param Y the Northing of the location
/// @param lat the latitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param long the longitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param Converter a converter object (from LSDShapeTools)
/// @author MDH
/// @date 27/7/2017
void get_lat_and_long_locations(double X, double Y, double& lat,
double& longitude, LSDCoordinateConverterLLandUTM Converter);
/// @brief a function to get the northing and easting provided as lat and long
/// @detail Assumes WGS84 ellipsiod
/// @param lat the latitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param long the longitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// @param X the Easting of the location
/// @param Y the Northing of the location
/// @author SMM
/// @date 30/09/2019
void get_x_and_y_from_latlong(double lat, double longitude, double& X, double& Y );
/// @brief this check to see if a point is within the raster
/// @param X_coordinate the x location of the point
/// @param Y_coordinate the y location of the point
/// @return is_in_raster a boolean telling if the point is in the raster
/// @author SMM
/// @date 13/11/2014
bool check_if_point_is_in_raster(float X_coordinate,float Y_coordinate);
///@brief Gives the reciever information for a given node.
///@param current_node Integer
///@param reveiver_node Empty integer to be assigned the index of the reciever
///node.
///@param receiver_row Empty integer to be assigned the row index of the
///reciever node.
///@param receiver_col Empty integer to be assigned the column index of the
///reciever node.
/// @author SMM
/// @date 01/016/12
void retrieve_receiver_information(int current_node,int& reveiver_node, int& receiver_row,
int& receiver_col);
///@brief Gives the reciever information for a given node.
///@param current_node Integer
///@param reveiver_node Empty integer to be assigned the index of the reciever
///node.
/// @author BG
/// @date 06/01/2018
void retrieve_receiver_information(int current_node,int& reveiver_node);
///@brief Get the row and column indices of a given node.
///@param current_node Integer index of a given node.
///@param curr_row Empty integer to be assigned the row index of the given
///node.
///@param curr_col Empty integer to be assigned the column index of the given
///node.
/// @author SMM
/// @date 01/016/12
void retrieve_current_row_and_col(int current_node,int& curr_row,
int& curr_col);
///@brief Get the index from row/col
///@param int row/col of the nodeindex 2DArray
///@author BG
///@date 27/12/2017
int get_NodeIndex_from_row_col(int row, int col);
///@brief Get the X and Y coordinates of a given node.
///@param current_node Integer index of a given node.
///@param current_X Empty integer to be assigned the X coordinate of the given
///node.
///@param current_Y Empty integer to be assigned the Y coordinate of the given
///node.
/// @author BG
/// @date 20/02/2017
void get_x_and_y_from_current_node(int current_node,float& current_X, float& current_Y);
///@brief Get the lat and longitude coordinates of a given node.
///@param current_node Integer index of a given node.
///@param current_lat latitude. Will be replaced by function
///@param current_long longitude. Will be replaced by function
///@param Converter A coordinate converter object
/// @author SMM
/// @date 26/04/2017
void get_lat_and_long_from_current_node(int current_node, double& current_lat, double& current_long, LSDCoordinateConverterLLandUTM Converter);
///@brief This function takes a vector of node indices and prints a csv
///file that can be read by arcmap
///@param nodeindex vec is a vector of nodeindices (which are ints)
///@param outfilename is a string of the filename
/// @author SMM
/// @date 03/06/14
void print_vector_of_nodeindices_to_csv_file(vector<int>& nodeindex_vec, string outfilename);
///@brief This function takes a vector of node indices and prints a csv
///file that can be read by arcmap: similar to above but also prints lat and long
///@param nodeindex vec is a vector of nodeindices (which are ints)
///@param outfilename is a string of the filename
/// @author SMM
/// @date 20/05/16
void print_vector_of_nodeindices_to_csv_file_with_latlong(vector<int>& nodeindex_vec, string outfilename);
/// @brief This function takes a vector of node indices and prints a csv
/// file that can be read by arcmap: similar to above but also prints lat and long
/// @detail Adds an option for a path
/// @param nodeindex vec is a vector of nodeindices (which are ints)
/// @param path to the outfile
/// @param outfilename is a string of the filename
/// @author SMM
/// @date 20/05/16
void print_vector_of_nodeindices_to_csv_file_with_latlong(vector<int> node_list,string path, string filename);
/// @brief This function takes a vector of node indices and prints a csv
/// file that can be read by arcmap: similar to above but also prints lat and long
/// @detail Adds an option for a path
/// @param nodeindex vec is a vector of nodeindices (which are ints)
/// @param path to the outfile
/// @param outfilename is a string of the filename
/// @param Elevation an elevation raster
/// @param FlowDistance
/// @param drainage_area
/// @author SMM
/// @date 30/09/19
void print_vector_of_nodeindices_to_csv_file_with_latlong(vector<int> node_list,string path, string filename, LSDRaster& Elevation, LSDRaster& FlowDistance,
LSDRaster& drainage_area);
///@brief This function takes a vector of node indices and prints a csv
///file that can be read by arcmap, adding in a unique id to each row, independent of the nodeindex.
///
///@details The unique ID is used to tie triplets of channel heads together for hollow analysis.
///@param nodeindex vec is a vector of nodeindices (which are ints)
///@param outfilename is a string of the filename
///@author SWDG after SMM
///@date 2/2/16
void print_vector_of_nodeindices_to_csv_file_Unique(vector<int>& nodeindex_vec, string outfilename);
///@brief Get the number of pixels flowing into a node.
///@param node Integer of node index value.
///@return Integer of the number of contributing pixels.
/// @author SMM
/// @date 01/016/12
int retrieve_contributing_pixels_of_node(int node)
{ return NContributingNodes[node]; }
///@brief Get the FlowLengthCode of a given node.
///@param node Integer of node index value.
///@return Integer of the FlowLengthCode.
/// @author SMM
/// @date 01/016/12
int retrieve_flow_length_code_of_node(int node)
{ return FlowLengthCode[ RowIndex[node] ][ ColIndex[node] ]; }
///@brief Get the FlowDirection of a row and column pair.
///@param row Integer of row index.
///@param col Integer of col index.
///@return Integer of the flow direction.
///@author SWDG
///@date 04/02/14
int get_LocalFlowDirection(int row, int col)
{ return FlowDirection[row][col]; }
/// @brief get the number of donors to a given node
/// @param current_node the node index from which to get n donors
/// @return the number of donors to this cell
/// @author SMM
/// @date 19/9/2014
int retrieve_ndonors_to_node(int current_node)
{ return NDonorsVector[current_node]; }
///@brief Get the node for a cell at a given row and column
///@param row index
///@param column index
///@return node index
///@author DTM
///@date 08/11/2013
int retrieve_node_from_row_and_column(int row, int column);
/// @brief gets a vector of all the donors to a given node
/// @param current_node the node index from which to get n donors
/// @return a vector containing all the donors to this node
/// @author SMM
/// @date 19/9/2014
vector<int> retrieve_donors_to_node(int current_node);
/// @brief returns the draiange area of a node in square km
/// @param this_node node of interest
/// @return draiange area in square km
/// @author FJC
/// @date 06/02/17
float get_DrainageArea_square_km(int this_node);
/// @brief returns the draiange area of a node in square m
/// @param this_node node of interest
/// @return draiange area in square km
/// @author FJC
/// @date 01/05/18
float get_DrainageArea_square_m(int this_node);
// 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 Georeferencing information
map<string,string> get_GeoReferencingStrings() const { return GeoReferencingStrings; }
/// @return Number of nodes with data as an integer.
int get_NDataNodes () const { return NDataNodes; }
/// @return Vector of all base level nodes.
vector<int> get_BaseLevelNodeList () { return BaseLevelNodeList; }
/// @return donor stack vector (depth first search sequence of nodes)
vector <int> get_donorStack() const { return DonorStackVector; }
/// @return the S vector, which is a sorted list of nodes (see Braun and Willett 2012)
vector <int> get_SVector() const { return SVector; }
/// @return FlowDirection values as a 2D Array.
Array2D<int> get_FlowDirection() const { return FlowDirection; }
///@brief Recursive add_to_stack routine, from Braun and Willett (2012)
///equations 12 and 13.
///@param lm_index Integer
///@param j_index Integer
///@param bl_node Integer
void add_to_stack(int lm_index, int& j_index, int bl_node);
// some functions that print out indices to rasters
///@brief Write NodeIndex to an LSDIndexRaster.
///@return LSDIndexRaster of node index data.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_NodeIndex_to_LSDIndexRaster();
///@brief Write FlowDirection to an LSDIndexRaster.
///@return LSDIndexRaster of flow directions.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_FlowDirection_to_LSDIndexRaster();
///@brief Write FlowLengthCode to an LSDIndexRaster.
///@return LSDIndexRaster of flow lengths.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_FlowLengthCode_to_LSDIndexRaster();
/// @brief This function writes and LSDIndexRaster containing the location of nodes in the nodeindexvector.
/// @param nodeindexvec a vector containing node indices one use is to export
/// the LSDIndexRaster of pixels that are in the node index vector.
/// @return LSDIndexRaster of pixels that are in the node index vector.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_NodeIndexVector_to_LSDIndexRaster(vector<int>& nodeindexvec);
/// @brief This function writes an LSDIndesxRaster given a list of node indices, and give every pixel its nodeindex value, which is unique.
/// @param nodeindexvec a vector containing node indices one use is to export
/// the LSDIndexRaster of pixels that are in the node index vector.
/// @return LSDIndexRaster of pixels that are in the node index vector.
/// @author SWDG after SMM
/// @date 2/2/16
LSDIndexRaster write_NodeIndexVector_to_LSDIndexRaster_Unique(vector<int>& nodeindexvec);
///@brief Write NContributingNodes to an LSDIndexRaster.
///@return LSDIndexRaster of number of contributing nodes for each cell.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_NContributingNodes_to_LSDIndexRaster();
///@brief Writes flow directions to an LSDIndexRaster.
///Flow direction in arcmap format is: \n\n
/// 32 64 128 \n
/// 16 0 1 \n
/// 8 4 2 \n
///
///@return LSDIndexRaster of flow directions in arcgis format.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster write_FlowDirection_to_LSDIndexRaster_Arcformat();
///@brief
///@return
///@author Fiona Clubb
///@date 15/11/12
LSDRaster write_DrainageArea_to_LSDRaster();
///@brief Prints the flow information to file.
///@param filename String of the output file to be written.
/// @author SMM
/// @date 01/016/12
void print_flow_info_vectors(string filename);
///@brief Unpickles flow information data from a binary file.
///@param filename String of the binary file to be read.
/// @author SMM
/// @date 01/016/12
void unpickle(string filename);
///@brief Pickles flow information data from a binary file.
///@details WARNING!!! This creates HUGE files (sometimes 10x bigger than
/// original file). Testing indicates reading this file takes
/// almost as long as recalculating the flowinfo object so
/// is probably not worth doing
///@param filename String of the binary file to be written.
/// @author SMM
/// @date 01/016/12
void pickle(string filename);
/// @brief This loads a csv file, putting the data into a data map
/// @param filename The name of the csv file including path and extension
/// @author SMM (ported into FlowInfo FJC 23/03/17)
/// @date 16/02/2017
map<string, vector<string> > load_csv_data(string filename);
/// @brief This gets a data column from the csv file
/// @param column_name a string that holds the column name
/// @return a vector of strings: this holds the data.
/// @author SMM (ported into FlowInfo FJC 23/03/17)
/// @date 17/02/2017
vector<string> get_data_column(string column_name, map<string, vector<string> > data_map);
/// @brief This gets a data column from the csv file, and converts it to a
/// float vector
/// @param column_name a string that holds the column name
/// @return a vector of floats: this holds the data.
/// @author SMM (ported into FlowInfo FJC 23/03/17)
/// @date 17/02/2017
vector<float> data_column_to_float(string column_name, map<string, vector<string> > data_map);
/// @brief This gets a data column from the csv file, and converts it to an
/// int vector
/// @param column_name a string that holds the column name
/// @return a vector of ints: this holds the data.
/// @author SMM (ported into FlowInfo FJC 23/03/17)
/// @date 17/02/2017
vector<int> data_column_to_int(string column_name, map<string, vector<string> > data_map);
/// @brief Method to ingest the channel heads raster generated using channel_heads_driver.cpp
/// into a vector of source nodes so that an LSDJunctionNetwork can be created easily
/// from them. **UPDATE** if the extension is a csv file it reads the node indices directly
/// **UPDATE, FJC 20/01/16 - changed default input switch to 2**
/// @details Assumes the FlowInfo object has the same dimensions as the channel heads raster.
/// @param filename of the channel heads raster.
/// @param extension of the channel heads raster.
/// @param (optional) input_switch, ONLY NEEDED FOR LOADING .csv FILES!
/// An integer to determine whether to use the node index (0 -> default), row and column indices (1),
/// or point coordinates from .csv file (2) to locate the channel heads
/// @return Vector of source nodes.
/// @author SWDG updated SMM updated DTM
/// @date 6/6/14 Happy 3rd birthday Skye!!
vector<int> Ingest_Channel_Heads(string filename, string extension, int input_switch = 2);
/// @brief Method to ingest the channel heads raster generated using channel_heads_driver.cpp
/// into a vector of source nodes so that an LSDJunctionNetwork can be created easily
/// from them. **UPDATE** if the extension is a csv file it reads the node indices directly
/// **UPDATE, FJC 20/01/16 - changed default input switch to 2**
/// ***********UPDATE - overloaded function to read in the column headers using the csv logic
/// rather than assume that the columns have to be in a specific order. ONLY WORKS WITH CSV
/// EXTENSIONS. FJC 23/03/17*************************
/// @details Assumes the FlowInfo object has the same dimensions as the channel heads raster.
/// @param filename of the channel heads raster.
/// @param extension of the channel heads raster.
/// @param (optional) input_switch, ONLY NEEDED FOR LOADING .csv FILES!
/// An integer to determine whether to use the node index (0 -> default),
/// row and column indices (1), or point coordinates from .csv file (2) to locate the channel heads
/// @return Vector of source nodes.
/// @author SWDG updated SMM updated DTM
/// @date 6/6/14 Happy 3rd birthday Skye!!
vector<int> Ingest_Channel_Heads(string filename, int input_switch = 2);
/// @brief Method to ingest sources from OS MasterMap Water Network Layer (csv) into a vector
/// of source nodes so that an LSDJunctionNetwork can be easily created from them.
/// @param csv_filename CSV file name
/// @return vector of source nodes
/// @author FJC
/// @date 28/11/16
vector<int> Ingest_Channel_Heads_OS(string csv_filename);
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Minimalistic method to ingest the channel heads from vectors of x y coordinates
// Using xy allows a "universal" method that can ingest external or internal data
// B.G. 11/11/2018
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
vector<int> Ingest_Channel_Heads(vector<float>& x_coord, vector<float>& y_coord);
// functions for getting flow, discharge, sediment flux, etc
///@brief This function calculates the contributing pixels.
///It can be converted to contributing area by multiplying by the
///DataResolution^2. In this function a pixel that has no donors has a
///contributing pixel value of 0.
///@return LSDIndexRaster of upslope contributing pixels.
/// @author SMM
/// @date 01/016/12
LSDIndexRaster calculate_n_pixels_contributing_from_upslope();
///@brief This calculates area and makes an index into the s vector for
///efficient calculation of the basin upslope of a given node.
/// @author SMM
/// @date 01/016/12
void calculate_upslope_reference_indices();
// algorithms for basin collection
///@brief This function returns the base level node with the greatest
///drainage area.
///@return Integer node index.
int retrieve_largest_base_level();
/// @brief This gets the base level node for any given node
/// @param node the starting node
/// @return the base level node
/// @author SMM
/// @date 18/12/2016
int retrieve_base_level_node(int node);
/// @brief This creates a new raster that has any nodes influenced by the edge removed
/// @detail uses D8 flow routing to do this
/// @param topography A topography raster (must be same dimension as that used to make flowinfo)
/// @author SMM
/// @date 08/10/2019
LSDRaster remove_nodes_influneced_by_edge(LSDRaster& topography);
/// @brief This creates a new raster. It takes a node list (usually a channel) and then
/// looks at all the donors to that channel and sees if any are influenced upslope
/// by nodata. It then removes all these pixels. This way you can isolate both
/// nodes drainaing to a local base level but eliminate nodes draining from the edge.
/// @detail uses D8 flow routing to do this
/// @param topography A topography raster (must be same dimension as that used to make flowinfo)
/// @param node_list a list of nodes (often read by an LSDSpatialCSVReader object)
/// @author SMM
/// @date 08/10/2019
LSDRaster find_nodes_not_influenced_by_edge_draining_to_nodelist(vector<int> node_list,LSDRaster& topography);
///@brief This function returns an integer vector containing all the node
///indexes upslope of of the node with number node_number_outlet.
///@param node_number_outlet Integer of the target node.
///@return Integer vector of upslope node indexes.
/// @author SMM
/// @date 01/016/12
vector<int> get_upslope_nodes(int node_number_outlet);
///@brief This function returns an integer vector containing all the node
///indexes upslope of of the node with number node_number_outlet, and then includes the outlet
///@param node_number_outlet Integer of the target node.
///@return Integer vector of upslope node indexes plus outlet node index.
/// @author SMM
/// @date 30/07/19
vector<int> get_upslope_nodes_include_outlet(int node_number_outlet);
/// @brief This function takes a list of sources and then creates a raster
/// with nodata values where points are not upslope of the sources
/// and 1.0 if they are upslope
/// @param source_nodes a vector of node indicies into the sources
/// @author SMM
/// @date 11/11/2015
LSDRaster get_upslope_node_mask(vector<int> source_nodes);
/// @brief This function takes a list of sources and then creates a raster
/// with nodata values where points are not upslope of the sources
/// and node_values if they are upslope
/// @param source_nodes a vector of node indicies into the sources
/// @param node_values a vector of the value of the nodes upslope of the sources
/// this vector needs to be the same size as the source_nodes vector
/// @author SMM
/// @date 12/11/2015
LSDRaster get_upslope_node_mask(vector<int> source_nodes, vector<float> node_values);
///@brief This function accumulates some variable from an LSDRaster
///The most probably use is to accumulate precipitation in order
///to get a discharge raster
///@param A raster that contains the variable to be accumulated (e.g., precipitation)
///@return A raster containing the accumulated variable: NOTE the accumulation
///does not include the node itself
///@author SMM
///@date 09/06/2014
LSDRaster upslope_variable_accumulator(LSDRaster& accum_raster);
///@brief This function accumulates some variable from an LSDRaster
///The most probably use is to accumulate precipitation in order
///to get a discharge raster
///@param A raster that contains the variable to be accumulated (e.g., precipitation)
///@param bool Determinde if the current node is accumulated to itself or not. Default to yes.
///@return A raster containing the accumulated variable
///@author BG, SMM
///@date 17/04/2019
LSDRaster upslope_variable_accumulator_v2(LSDRaster& accum_raster);
LSDRaster upslope_variable_accumulator_v2(LSDRaster& accum_raster, bool accum_current_node);
///@brief This function tests whether one node is upstream of another node
///@param current_node
///@param test_node
///@return Boolean indicating whether node is upstream or not
///@author FC
///@date 08/10/13
int is_node_upstream(int current_node, int test_node);
///@brief This function tests whether a node is a base level node
///@param node
///@return int which is 1 if node is base level, 0 if not
///@author FJC
///@date 26/08/15
int is_node_base_level(int node);
/// @brief this function gets a list of the node indices of the donors to a particular node
/// @param node this is the nodeindex of the node for which you want to find the donors
/// @return a vector of the donor nodes
/// @author SMM
/// @date 21/10/2013
vector<int> get_donor_nodes(int node);
// algorithms for stream profile analysis
/// @brief This function calculates the chi function for all the nodes upslope
/// of a given node.
/// @param starting_node Integer index of node to analyse upslope of.
/// @param m_over_n
/// @param A_0
/// @return Vector of chi values. The node indices of these values are those
/// that would be retured from get_uplope_nodes
/// @author SMM
/// @date 01/16/2012
vector<float> get_upslope_chi(int starting_node, float m_over_n, float A_0);
/// @brief This function calculates the chi function for all the nodes upslope
/// of a given node.
/// @detail this version uses discharge rather than area
/// @param starting_node Integer index of node to analyse upslope of.
/// @param m_over_n
/// @param A_0 the referecen discharge
/// @param Discharge a raster of the discharge
/// @return Vector of chi values. The node indices of these values are those
/// that would be retured from get_uplope_nodes
/// @author SMM
/// @date 16/10/2015
vector<float> get_upslope_chi(int starting_node, float m_over_n, float A_0, LSDRaster& Discharge);
/// @brief This function calculates the chi function for a list of nodes
/// it isn't really a standalone modules, but is only called from get_upslope_chi
/// above
/// @param upslope_pixel_list Vector of nodes to analyse.
/// @param m_over_n
/// @param A_0
/// @return Vector of chi values.
/// @author SMM
/// @date 16/01/12
vector<float> get_upslope_chi(vector<int>& upslope_pixel_list, float m_over_n, float A_0);
/// @brief This function calculates the chi function for a list of nodes
/// it isn't really a standalone modules, but is only called from get_upslope_chi
/// above
/// @detail this version uses discharge rather than area
/// @param upslope_pixel_list Vector of nodes to analyse.
/// @param m_over_n
/// @param A_0
/// @param Discharge and LSDRaster of the discharge
/// @return Vector of chi values.
/// @author SMM
/// @date 16/10/15
vector<float> get_upslope_chi(vector<int>& upslope_pixel_list, float m_over_n, float A_0, LSDRaster& Discharge);
/// @brief This function calculates the chi function for a list of nodes
/// it isn't really a standalone modules, but is only called from get_upslope_chi
/// above. It returns a map, which is used to speed up computation
/// @param upslope_pixel_list Vector of nodes to analyse.
/// @param m_over_n
/// @param A_0
/// @param mimum_pixels This minimum number of contributing pixels needed before chi is calculated
/// @return A map where the key is the node index and the value is chi
/// @author SMM
/// @date 13/07/17
map<int,float> get_upslope_chi_return_map(vector<int>& upslope_pixel_list, float m_over_n, float A_0, int minimum_pixels);
/// @brief This function calculates the chi function for a list of nodes
/// it isn't really a standalone modules, but is only called from get_upslope_chi
/// above. It returns a map, which is used to speed up computation
/// @detail this version uses discharge rather than area
/// @param upslope_pixel_list Vector of nodes to analyse.
/// @param m_over_n
/// @param A_0
/// @param mimum_pixels This minimum number of contributing pixels needed before chi is calculated
/// @param Discharge and LSDRaster of the discharge
/// @return A map where the key is the node index and the value is chi
/// @author SMM
/// @date 13/07/17
map<int,float> get_upslope_chi_return_map(vector<int>& upslope_pixel_list, float m_over_n, float A_0, int minimum_pixels, LSDRaster& Discharge);
/// @brief this function takes a vector that contains the node indices of
/// starting nodes, and then calculates chi upslope of these nodes
/// to produce a chi map. A threshold drainage area can be used
/// to only map chi where nodes have greater than the threshold drainage area
/// @details this function is meant to mimic the function of the Willett et al
/// (2014) Science paper. You do need to extract the wanted node indices
/// for your starting nodes from a node index map
/// @param starting_nodes an integer vector containing all the node indices
/// of the node from which you want to start the chi analysis. All of these
/// nodes will be considered to have a starting chi of 0
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference drainage area. This is a but arbitrary. We usually use
/// 1000 m^2. Willet et al(2014, Science) used 1m^2. As of 28 July 2014 we've not
/// done any detailed sensitivity analysis on this parameter
/// @param area_threshold the threshold area (in m^2) that sets the area above
/// which chi is recorded in the chi raster
/// @return this returns an LSDRaster for the chi values upslope of all of the
/// nodes indicated in starting_nodes
/// @author SMM
/// @date 28/14/2014
LSDRaster get_upslope_chi_from_multiple_starting_nodes(vector<int>& starting_nodes,
float m_over_n, float A_0, float area_threshold);
/// @brief this function takes a vector that contains the node indices of
/// starting nodes, and then calculates chi upslope of these nodes
/// to produce a chi map. A threshold drainage area can be used
/// to only map chi where nodes have greater than the threshold drainage area
/// @details this function is meant to mimic the function of the Willett et al
/// (2014) Science paper. You do need to extract the wanted node indices
/// for your starting nodes from a node index map
/// This version allows computation with discharge
/// @param starting_nodes an integer vector containing all the node indices
/// of the node from which you want to start the chi analysis. All of these
/// nodes will be considered to have a starting chi of 0
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference discharge. This is arbitrary. As of 28 July 2014 we've not
/// done any detailed sensitivity analysis on this parameter
/// @param area_threshold the threshold area (in m^2) that sets the area above
/// which chi is recorded in the chi raster
/// @return this returns an LSDRaster for the chi values upslope of all of the
/// nodes indicated in starting_nodes
/// @author SMM
/// @date 16/10/2015
LSDRaster get_upslope_chi_from_multiple_starting_nodes(vector<int>& starting_nodes,
float m_over_n, float A_0, float area_threshold, LSDRaster& Discharge);
/// @brief This funtion gets all the upslope chi of a starting node (assuming
/// chi at starting node is 0) and returns a map
/// @param starting_nodes an integer containing the node index
/// of the node from which you want to start the chi analysis.
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference discharge.
/// @param mimum_pixels This minimum number of contributing pixels needed before chi is calculated
/// @return Returns a map where the key is the node index and the value is chi
/// @author SMM
/// @date 13/07/2017
map<int,float> get_upslope_chi_from_single_starting_node(int starting_node,
float m_over_n, float A_0, int minimum_pixels);
/// @brief This funtion gets all the upslope chi of a starting node (assuming
/// chi at starting node is 0) and returns a map
/// @details This version allows computation with discharge
/// @param starting_nodes an integer containing the node index
/// of the node from which you want to start the chi analysis.
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference discharge.
/// @param mimum_pixels This minimum number of contributing pixels needed before chi is calculated
/// @param Discharge The discharge raster
/// @return Returns a map where the key is the node index and the value is chi
/// @author SMM
/// @date 13/07/2017
map<int,float> get_upslope_chi_from_single_starting_node(int starting_node,
float m_over_n, float A_0, int minimum_pixels, LSDRaster& Discharge);
/// @brief This function gets the chi upslope of every base level node
/// that is, it gets the chi values of the entire DEM, assuming all
/// base level nodes have a chi of 0
/// @detail because this assumes all base level nodes have a chi of 0,
/// this function is probably only appropriate for numerical models.
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference drainage area. This is a but arbitrary. We usually use
/// 1000 m^2. Willet et al(2014, Science) used 1m^2. As of 28 July 2014 we've not
/// done any detailed sensitivity analysis on this parameter
/// @param area_threshold the threshold area (in m^2) that sets the area above
/// which chi is recorded in the chi raster
/// @return this returns an LSDRaster for the chi values of the entire raster,
/// with base level nodes assumed to have chi = 0
/// @author SMM
/// @date 28/14/2014
LSDRaster get_upslope_chi_from_all_baselevel_nodes(float m_over_n, float A_0,
float area_threshold);
/// @brief This function gets the chi upslope of every base level node
/// that is, it gets the chi values of the entire DEM, assuming all
/// base level nodes have a chi of 0
/// @detail because this assumes all base level nodes have a chi of 0,
/// this function is probably only appropriate for numerical models.
/// This version of the function allows computation with a discharge raster
/// @param m_over_n the m/n ratio. Chi is quite sensitive to this
/// @param A_0 the reference discharge (same units as discharge. As of 28 July 2014 we've not
/// done any detailed sensitivity analysis on this parameter
/// @param area_threshold the threshold area (in m^2) that sets the area above
/// which chi is recorded in the chi raster
/// @param Discharge a raster of the discharge
/// @return this returns an LSDRaster for the chi values of the entire raster,
/// with base level nodes assumed to have chi = 0
/// @author SMM
/// @date 16/10/2015
LSDRaster get_upslope_chi_from_all_baselevel_nodes(float m_over_n, float Q_0,
float area_threshold,
LSDRaster& Discharge);
/// @brief Calculates the distance from outlet of all the base level nodes.
/// Distance is given in spatial units, not in pixels.
/// @return LSDRaster of the distance to the outlet for all baselevel nodes.
/// @author SMM
/// @date 01/016/12
LSDRaster distance_from_outlet();
/// @biref calculates the slope measured in the d8 flow direction
/// base level nodes have slope of 0; slope is measured from node to receiver
/// @param the elevation raster
/// @return A raster of the d8 slope
/// @author SMM
/// @date 21/09/2014
LSDRaster calculate_d8_slope(LSDRaster& Elevation);
/// @brief This returns the node index of the pixel farthest upslope from the input node.
/// @param node the node from which you want to find the farthest upslope pixel.
/// @param DistFromOutlet an LSDRaster containing the distance from the outlet.
/// @return This returns the node index of the pixel farthest upslope
/// from the input node.
/// @author SMM
/// @date 25/19/13
int find_farthest_upslope_node(int node, LSDRaster& DistFromOutlet);
/// @brief This takes a list of nodes and sorts them according to a
/// sorting raster (it could be anything) fin ascending order
/// nodes are then reordered to reflect the sorting of the raster
/// @param node_vec A vector of nodes
/// @param SortingRaster a raster that contains some values that will
/// be used to sort the nodes.
/// @return sorted_nodes a vector containing the sorted nodes
/// @author SMM
/// @date 20/05/2016
vector<int> sort_node_list_based_on_raster(vector<int> node_vec, LSDRaster& SortingRaster);
/// @brief This takes a list of nodes and sorts them according to a
/// sorting raster (it could be anything) fin ascending order
/// nodes are then reordered to reflect the sorting of the raster
/// @param node_vec A vector of nodes
/// @param SortingRaster a raster that contains some values that will
/// be used to sort the nodes.
/// @return sorted_nodes a vector containing the sorted nodes
/// @author SMM
/// @date 20/05/2016
vector<int> sort_node_list_based_on_raster(vector<int> node_vec, LSDIndexRaster& SortingRaster);
/// @brief Function to get the node index for a point using its X and Y coordinates
/// @param X_coordinate X_coord of point
/// @param Y_coordinate Y_coord of point
/// @return int with node index of point
/// @author FJC
/// @date 11/02/14
int get_node_index_of_coordinate_point(float X_coordinate, float Y_coordinate);
/// @brief Get vector of nodeindices from csv file
/// @param csv_filename input csv file
/// @return vector<int> with nodeindices. Ignores nodatavalues
/// @author FJC
/// @date 14/02/17
void get_nodeindices_from_csv(string csv_filename, vector<int>& NIs, vector<float>& X_coords, vector<float>& Y_coords);
/// @brief Function to return the closest value of a raster to a specified node index
/// @param NodeIndex of interest
/// @param InputRaster raster to return value of
/// @param search_radius rectangular window to search for, in n_pixels
/// @return float value of raster closest to the node index
/// @author FJC
/// @date 08/02/17
float snap_RasterData_to_Node(int NodeIndex, LSDRaster& InputRaster, int search_radius);
///@brief A get sources version that uses the flow accumulation pixels.
///@param FlowPixels LSDIndexRaster of flow accumulation in pixels.
///@param threshold Integer flow accumulation threshold.
///@return Vector of source integers: these refer to the node indices of the sources.
/// @author SMM
/// @date 01/016/12
vector<int> get_sources_index_threshold(LSDIndexRaster& FlowPixels, int threshold);
/// @brief A get sources version that uses AS^2 (area and slope).
/// @param FlowPixels LSDIndexRaster of flow accumulation in pixels.
/// @param Slope LSDRaster of slope values
/// @param threshold Integer AS^2 threshold
/// @return Vector of source integers: these refer to the node indices of the sources.
/// @author FJC
/// @date 11/02/14
vector<int> get_sources_slope_area(LSDIndexRaster& FlowPixels, LSDRaster& Slope, int threshold);
/// @brief Gets a vector of source nodes based on the X and Y coordinates of mapped channel
/// heads. Can be used if all the channel heads in a basin were mapped to get the stream