-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathLSDRaster.hpp
More file actions
2352 lines (2110 loc) · 105 KB
/
Copy pathLSDRaster.hpp
File metadata and controls
2352 lines (2110 loc) · 105 KB
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, Univeristy of Glasgow
@author Stuart W. D. Grieve, University College London
@author Fiona Clubb, University of Potsdam
@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 API documentation for LSDTopotools.
These pages will help you get started using this software.
\image html ./LSD-logo.png
Tools are included to:
- Generate topographic metrics
- Extract Channels
- Perform Chi analysis
.
@author Simon M. Mudd, University of Edinburgh
@author David Milodowski, University of Edinburgh
@author Martin D. Hurst, Univeristy of Glasgow
@author Stuart W. D. Grieve, University College London
@author Fiona Clubb, University of Potsdam
*/
#ifndef LSDRaster_H
#define LSDRaster_H
#include <string>
#include <vector>
#include <map>
#include "TNT/tnt.h"
#include "LSDIndexRaster.hpp"
#include "LSDShapeTools.hpp"
using namespace std;
using namespace TNT;
///@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); }
/// @brief Create an LSDRaster from memory, with the elvation
/// data stored as double precision floats.
/// @return LSDRaster
/// @details Created to maintain compatibility with LSDCatchmentModel
/// @author DAV
LSDRaster(int nrows, int ncols, double xmin, double ymin,
double cellsize, double ndv, Array2D<double> data)
{ create(nrows, ncols, xmin, ymin, cellsize, ndv, data); }
/// @brief Create an LSDRaster from memory, includes georeferencing
/// @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,
/// @param temp_GRS a map of strings containing georeferencing information. Used
/// mainly with ENVI format files
///containing the data to be written.
LSDRaster(int nrows, int ncols, float xmin, float ymin,
float cellsize, float ndv, Array2D<float> data, map<string,string> temp_GRS)
{ create(nrows, ncols, xmin, ymin, cellsize, ndv, data, temp_GRS); }
// 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(); }
/// @brief Get the raw raster data, double format
/// @author DAV
Array2D<double> get_RasterData_dbl() const { return RasterData_dbl.copy(); }
/// @brief Get the raw raster data, integer format
/// @author DAV
Array2D<int> get_RasterData_int() const { return RasterData_int.copy(); }
/// @return map containing the georeferencing strings
map<string,string> get_GeoReferencingStrings() const { return GeoReferencingStrings; }
/// @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 Sets 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.
/// @param value The value of the updated raster element
/// @author SMM
/// @date 19/05/16
void set_data_element(int row, int column, float value) { RasterData[row][column] = value; }
/// 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 Reads a raster from an ascii file for use in LSDCatchmentModel
/// @bug You can't return a TNT::Array properly in a function. See google for details.
/// @author DAV
/// @return Returns a 2D Array of the raster file.
TNT::Array2D<double> get_ascii_raster(string FILENAME);
/// @brief reads a raster from an ascii file, populates an LSDRaster object array
/// @author DAV
/// @details This method takes a filename (the .asc file).
/// It reads in the ascii file and fills in the array (and header) part of the LSDRaster object
/// with double precision values in the array. You must have declared an instance of an LSDRaster object.
/// @example myLSDRasterobject.read_ascii_raster("elevations.asc")
/// @result The myLSDRasterobject.RasterData_dbl data member is now populated with an array of
/// the DEM data. The data members for NCols, NRows, etc. are also updated.
void read_ascii_raster(string FILENAME);
/// @brief Reads a raster of integers and populates LSDRaster integer array member data
/// @author DAV
/// @todo Really, one ought to modify LSDRaster so that it is a class template, and then
/// wouldn't need different TNT Array data members for when we have floats, double, ints
/// etc. Might be tricky though, although if done carefully it should not break
/// peoples code.
void read_ascii_raster_integers(string FILENAME);
/// @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 This calls raster write functions, writing from Arrays of type <double> to raster format.
/// @details Sorry for duplicating a load of code, but I couldn't think
/// of a good way to overload the function without passing the raster data array or
/// breaking someone elses code.
/// @param filename a string of the filename _without_ the extension.
/// @param extension a string of the extension _without_ the leading dot
/// @author DAV
/// @date 07-12-2015
void write_double_raster(string filename, string extension);
/// @brief Writes out a double array to an ascii
void write_double_asc_raster(string string_filename);
/// @brief Writes out a double array to a binary flt file
void write_double_flt_raster(string filename, string string_filename);
/// @brief Writes out a double array to a ENVI bil file (untested!)
/// @bug Unlikely to work as Georeferencing not set. DAV to fix.
void write_double_bil_raster(string filename, string string_filename);
/// @brief Checks to see if two rasters have the same dimensions
/// @detail Does NOT check georeferencing
/// @param Compare_raster: the raster to compare
/// @author SMM
/// @date 04/05/2015
bool does_raster_have_same_dimensions(LSDRaster& Compare_raster);
/// @brief Checks to see if two rasters have the same dimensions
/// @detail Does NOT check georeferencing
/// @param Compare_raster: the raster to compare
/// @author SMM
/// @date 04/05/2015
bool does_raster_have_same_dimensions(LSDIndexRaster& Compare_raster);
/// @brief Checks to see if two rasters have the same georeferencing
/// @param Compare_raster: the raster to compare
/// @author SMM
/// @date 02/03/2015
bool does_raster_have_same_dimensions_and_georeferencing(LSDRaster& Compare_raster);
/// @brief Checks to see if two rasters have the same georeferencing
/// @param Compare_raster: the raster to compare
/// @author SMM
/// @date 02/03/2015
bool does_raster_have_same_dimensions_and_georeferencing(LSDIndexRaster& Compare_raster);
/// @brief Method which takes a new xmin and ymax value and modifys the GeoReferencingStrings
/// map_info line to contain these new values.
///
/// @details Intended for use in the rastertrimmer methods and is called from within these methods.
/// Modifying georeferencing information by hand is messy and should be avoided if
/// at all possible.
/// @param NewXmin floating point value of the new minimum x value in the raster.
/// @param NewYmax floating point value of the new maximum y value in the raster.
/// @return An updated GeoReferencingStrings object.
///
/// @author SWDG
/// @date 6/11/14
map<string, string> Update_GeoReferencingStrings(float NewXmin, float NewYmax);
/// @brief Method which updates the map info element of the georeferencing strings based on
/// information within the datamembers of the raster
///
/// @details Intended for use when changing raster dimesions
///
/// @author SMM
/// @date 6/11/14
void Update_GeoReferencingStrings();
/// @brief This method imposes georefereing strings assuming the coordinate
/// system is UTM
/// @param zone the UTM zone
/// @param NorS a string containing characters that start either N (for north)
/// or S for south. The letter is not case sensitive
/// @author SMM
/// @date 6/11/14
void impose_georeferencing_UTM(int zone, string NorS);
/// @brief This method looks up the central meridian given a UTM zone
/// @param UTM_zone the UTM zone
/// @return central_meridian an integer of the central meridian of this UTM zone
/// @author SMM
/// @date 6/11/14
int Find_UTM_central_meridian(int UTM_zone);
/// @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 This returns vectors of all the easting and northing points in the raster
/// Used for interpolations
/// @param Eastings a vector of easting coordinates. Will be replaced by method.
/// @param Northings a vector of northing coordinates. Will be replaced by method.
/// @author SMM
/// @date 17/03/2017
void get_easting_and_northing_vectors(vector<float>& Eastings, vector<float>& Northings);
/// @brief This interpolates a vector of points onto the raster. Uses bilinear interpolation.
/// @param UTMEvec Easting coordinates of points to be interpolatiod.
/// @param UTMNvec Northing coordinates of points to be interpolatiod.
/// @return The vector of interpolated data.
/// @author SMM
/// @date 17/03/2017
vector<float> interpolate_points_bilinear(vector<float> UTMEvec, vector<float> UTMNvec);
/// @brief This fills a raster with precalculated interpolated data
/// @param rows_of_nodes the rows of the interpolated points
/// @param cols_of_nodes the colss of the interpolated points
/// @param interpolated data the actual data that has been interpolated
/// @author SMM
/// @date 17/02/2017
LSDRaster fill_with_interpolated_data(vector<int> rows_of_nodes, vector<int> cols_of_nodes,
vector<float> interpolated_data);
/// @brief This gets the value at a point in UTM coordinates
/// @param UTME the easting coordinate
/// @param UTMN the northing coordinate
/// @return The value at that point
/// @author SMM
/// @date 14/03/2017
float get_value_of_point(float UTME, float UTMN);
/// @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 Gets the row and column of a point in the raster
/// @param X_coordinate the x location of the point
/// @param Y_coordinate the y location of the point
/// @param row the row of the point, replaced upon running the routine
/// @param col the col of the point, replaced upon running the routine
/// @author SMM
/// @date 22/01/2016
void get_row_and_col_of_a_point(float X_coordinate,float Y_coordinate,int& row, int& col);
/// @brief This function returns a vector with the X adn Y minimum and max
/// values
/// @return XYMinMax a vector with four elements
/// XYMinMax[0] = XMinimum
/// XYMinMax[1] = YMinimum
/// XYMinMax[2] = XMaximum
/// XYMinMax[3] = XMaximum
/// @author SMM
/// @date 3/7/2015
vector<float> get_XY_MinMax();
///@brief This function returns the raster data as a vector
///@return vector<float> with raster data
///@author FJC
///@date 06/11/15
vector<float> get_RasterData_vector();
///@brief This function returns the raster data as a vector, ignoring NDVs
///@return vector<float> with raster data
///@author MDH
///@date 06/02/17
vector<float> get_RasterData_vector_No_NDVs();
///@brief This function returns the raster data as text file
///@return text file with raster data
///@author FJC
///@date 30/09/16
void write_RasterData_to_text_file(string filename);
/// @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 Create a raster in of the same number of rows and cols with nodata
/// @author FJC
/// @date 07/04/17
LSDRaster create_raster_nodata();
/// @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.\n
///
/// Modded 6/11/14 to cope with bil files and to catch cases where some or all of the
/// edges cannot be trimmed - SWDG
///
/// @return A trimmed LSDRaster object.
/// @author SWDG
/// @date 22/08/13
LSDRaster RasterTrimmer();
/// @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.
/// Similar to RasterTrimmer but has a pixel buffer. Useful for CRN data since
/// sometimes the channel in the DEM does not correspond exactly with the
/// data point.
/// @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.\n
/// @param padded_pixels the number of pixels to pad the DEM with
/// @return A trimmed LSDRaster object.
/// @author SMM
/// @date 18/03/15
LSDRaster RasterTrimmerPadded(int padded_pixels);
/// @brief Takes a raster and trims nodata from around the edges to
/// result in a rectangular LSDRaster
/// @return A trimmed LSDRaster object.
/// @author SMM
/// @date 5/11/14
LSDRaster RasterTrimmerSpiral();
/// @brief This returns a clipped raster that has the same dimensions as the
/// smaller raster
/// @param smaller_raster the raster to which the bigger raster should be
/// clipped
/// @author SMM
/// @date 20/03/2015
LSDRaster clip_to_smaller_raster(LSDRaster& smaller_raster);
/// @brief This returns a clipped raster that has the same dimensions as the
/// smaller raster
/// @param smaller_raster the raster to which the bigger raster should be
/// clipped
/// @author SMM
/// @date 20/03/2015
LSDRaster clip_to_smaller_raster(LSDIndexRaster& smaller_raster);
/// @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);
/// @brief Strips the edge rows/columns of a LSDRaster on each side of the array.
/// @details This removes 1 pixel/grid cell from each side of an LSDRaster
/// Note that it modifies the original raster and reassigns the RasterData_dbl
/// data member to the new 'trimmed' raster. It then reduces the NCols and NRows
/// values by 2, but does not modify the ll-corner values. It was primarily
/// written for a special case in LSDCatchmentModel but will work with any LSDRaster.
/// @author DAV
/// @date 01/04/2016
void strip_raster_padding();
/// @brief Buffers a raster using a circular kernel of a user-defined radius (m)
/// @param window_radius radius in metres
/// @author FJC
/// @date 10/02/17
LSDRaster BufferRasterData(float window_radius);
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// Simple topographic metrics
// Several simple topographic metrics measuered over a kernal
//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/// @brief Calculates a relief raster
/// @param The width in metres of the kernal you wnat to use for resolution
/// @param if this ==1 then you use a circular kernal. Otherwise kernal is square
/// @return The spatially distributed relief
/// @author JAJ (entered into trunk SMM)
/// @date 6/06/2014 Happy 3rd Birthday Skye!!!
LSDRaster calculate_relief(float kernelWidth, int kernelType);
/// @brief Calculates mean elevation of a raster
/// @return The spatially distributed relief
/// @author JAJ (entered into trunk SMM)
/// @date 01/02/2014 modified 09/06/2014 by SMM
float mean_elevation(void);
/// @brief Calculates max elevation of a raster
/// @return The spatially distributed relief
/// @author JAJ (entered into trunk SMM)
/// @date 01/02/2014
float max_elevation(void);
/// @brief Calculates mean relief of a raster, it defaults to a circular kernal
/// @return The spatially distributed relief
/// @author JAJ (entered into trunk SMM)
/// @date 01/02/2014 modified 09/06/2014 by SMM
float mean_relief(float kernelsize);
/// @brief Calculates the mean difference between two rasters
/// @details checks raster dimensions but not georeferencing since it
/// is used to compare asc format model results
/// @author SMM
/// @date 04/05/2015
float difference_rasters(LSDRaster& compare_raster);
/// @brief This multiplies the raster data by a multiplier
/// @detail Note that values are replaced
/// @author SMM
/// @date 06/05/2015
void raster_multiplier(float multiplier);
/// @brief This multiplies two rasters, elementwise
/// @detail Simple elementwise multiplictation
/// @param M_raster The raster by which to multiply the current raster
/// @return A raster holding the elementwise product of the two rasters
/// @author SMM
/// @date 27/10/2016
LSDRaster MapAlgebra_multiply(LSDRaster& M_raster);
/// @brief This divides two rasters, elementwise
/// @detail Simple elementwise division
/// @param M_raster The raster by which to divide the current raster
/// @return A raster holding the elementwise quotient of the two rasters
/// @author SMM
/// @date 27/10/2016
LSDRaster MapAlgebra_divide(LSDRaster& M_raster);
/// @brief This add two rasters, elementwise
/// @detail Simple elementwise addition
/// @param M_raster The raster by which to add the current raster
/// @return A raster holding the elementwise sum of the two rasters
/// @author SMM
/// @date 27/10/2016
LSDRaster MapAlgebra_add(LSDRaster& M_raster);
/// @brief This subtracts two rasters, elementwise
/// @detail Simple elementwise subtraction
/// @param M_raster The raster by which to subtract the current raster
/// @return A raster holding the elementwise difference of the two rasters
/// @author SMM
/// @date 27/10/2016
LSDRaster MapAlgebra_subtract(LSDRaster& M_raster);
// 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
/// Believe it or not this algorithm is absed on code poseted by Notch, the creator of Minecraft,
/// who then had it modified by Charles Randall
/// https://www.bluh.org/code-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 (float) of the illumination source in degrees.
/// @param azimuth (float) of the illumination source in degrees
/// @param z_factor (float) Scaling factor between vertical and horizontal.
/// @return Hillshaded LSDRaster object
/// @author SWDG
/// @date February 2013
LSDRaster hillshade();
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 Function to determine areas of a DEM that are in shadow from a
/// given radiation source defined by an Azimuth and Zenith following Codilean (2006).
///
/// @details Performs a coordinate transformation, rotating the x,y,z coordinates about the
/// Azimuth and Zenith such that the coordinates are aligned with the Azimuth and Zenith.
/// Shaded cells are then found by tracking in the direction of the radiation source and
/// looking for transformed z values greater than that at the cell of interest which would
/// therefore cast a shadow.
///
/// @param Azimuth of the illumination source in degrees.
/// @param ZenithAngle of the illumination source in degrees
/// @return Hillshaded LSDIndexRaster
/// @author MDH
/// @date Feb 2015
LSDRaster CastShadows(int Azimuth, int ZenithAngle);
/// @brief Function to determine areas of a DEM that are in shadow from a
/// given radiation source defined by an Azimuth and Zenith following Codilean (2006).
///
/// @details Performs a coordinate transformation, rotating the x,y,z coordinates about the
/// Azimuth and Zenith such that the coordinates are aligned with the Azimuth and Zenith.
/// Shaded cells are then found by tracking in the direction of the radiation source and
/// looking for transformed z values greater than that at the cell of interest which would
/// therefore cast a shadow.
///
/// @param Azimuth of the illumination source in degrees.
/// @param ZenithAngle of the illumination source in degrees
/// @return Hillshaded 2D Array of ints
/// @author MDH
/// @date Feb 2015
Array2D<float> Shadows(int Azimuth, int ZenithAngle);
/// @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 of shadowed cells 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 (This is probably no longer true
/// now that we incorporate drop shadows (MDH, Feb 2015)).
///
/// 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 TopographicShielding(int theta_step, int phi_step);
LSDRaster TopographicShielding();
/// @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
/// 7 -> 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);