|
@@ -19,9 +19,10 @@
|
|
|
|
|
|
#include "direction.h"
|
|
|
#include "nodata.h"
|
|
|
+#include "common.h" /*for global opt->d8 flag*/
|
|
|
+
|
|
|
+#define TF_ROOTTWO 1.4142135623
|
|
|
|
|
|
-/***************************************************************/
|
|
|
-/* returns the direction corresponding to the window */
|
|
|
/* directions:
|
|
|
32 64 128
|
|
|
16 * 1
|
|
@@ -33,6 +34,21 @@ encodeDirection(const genericWindow<elevation_type>& elevwin,
|
|
|
dimension_type row,
|
|
|
dimension_type col) {
|
|
|
|
|
|
+ /*check global opt flag and call appropriate model*/
|
|
|
+ if(opt->d8){
|
|
|
+ return encodeDirectionSFD(elevwin, nrows, ncols, row, col);
|
|
|
+ }
|
|
|
+ return encodeDirectionMFD(elevwin, nrows, ncols, row, col);
|
|
|
+}
|
|
|
+
|
|
|
+/***************************************************************/
|
|
|
+/* returns the direction corresponding to the window using MFD */
|
|
|
+direction_type
|
|
|
+encodeDirectionMFD(const genericWindow<elevation_type>& elevwin,
|
|
|
+ const dimension_type nrows, const dimension_type ncols,
|
|
|
+ dimension_type row,
|
|
|
+ dimension_type col) {
|
|
|
+
|
|
|
direction_type dir = DIRECTION_UNDEF;
|
|
|
|
|
|
if(!is_nodata(elevwin.get())) {
|
|
@@ -67,7 +83,71 @@ encodeDirection(const genericWindow<elevation_type>& elevwin,
|
|
|
return dir;
|
|
|
}
|
|
|
|
|
|
+/***************************************************************/
|
|
|
+/* returns the direction corresponding to the window using SFD */
|
|
|
+direction_type
|
|
|
+encodeDirectionSFD(const genericWindow<elevation_type>& elevwin,
|
|
|
+ const dimension_type nrows, const dimension_type ncols,
|
|
|
+ dimension_type row,
|
|
|
+ dimension_type col) {
|
|
|
|
|
|
+ direction_type dir = DIRECTION_UNDEF;
|
|
|
+ float tdrop, max_drop;
|
|
|
+ int max_indx;
|
|
|
+
|
|
|
+ if(!is_nodata(elevwin.get())) {
|
|
|
+ dir = 0;
|
|
|
+ max_drop = 0;
|
|
|
+ max_indx = -1;
|
|
|
+ for(int i=0; i<9; i++){
|
|
|
+ if(i%2==1){ /*cardinal direction*/
|
|
|
+ tdrop=elevwin.get()-elevwin.get(i);
|
|
|
+ if(tdrop>max_drop){ max_drop=tdrop; max_indx=i; }
|
|
|
+ }
|
|
|
+ else if(i!=4){ /*diagonal*/
|
|
|
+ tdrop=(elevwin.get()-elevwin.get(i))/TF_ROOTTWO;
|
|
|
+ if(tdrop>max_drop){ max_drop=tdrop; max_indx=i; }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ switch(max_indx){
|
|
|
+ case 0:
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ dir=32<<max_indx; break;
|
|
|
+ case 3:
|
|
|
+ dir=16; break;
|
|
|
+ case 5:
|
|
|
+ dir=1; break;
|
|
|
+ case 6:
|
|
|
+ case 7:
|
|
|
+ case 8:
|
|
|
+ dir=8>>(max_indx-6); break;
|
|
|
+ default:
|
|
|
+ dir=0; break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* if no direction, check for boundary */
|
|
|
+ if(dir==0 || dir==DIRECTION_UNDEF) {
|
|
|
+ if(row==0) {
|
|
|
+ dir = 64;
|
|
|
+ }
|
|
|
+ if(row==nrows-1) {
|
|
|
+ dir = 48;
|
|
|
+ }
|
|
|
+ if(col==0) {
|
|
|
+ if(row==0) dir = 32;
|
|
|
+ else if(row==nrows-1) dir = 8;
|
|
|
+ else dir = 16;
|
|
|
+ }
|
|
|
+ if(col==ncols-1) {
|
|
|
+ if(row==0) dir = 128;
|
|
|
+ else if(row==nrows-1) dir = 2;
|
|
|
+ else dir = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dir;
|
|
|
+}
|
|
|
|
|
|
direction_type
|
|
|
findDominant(direction_type dir) {
|
|
@@ -143,8 +223,25 @@ findDominant(direction_type dir) {
|
|
|
return 128;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- return dir;
|
|
|
+ /* Otherwise, there is no dominant direction.
|
|
|
+ * SFD must output a single direction 1,2,4,8,16,32,64, or 128
|
|
|
+ * pick the first matching one, with preference to cardinal direction
|
|
|
+ */
|
|
|
+ if(dir & 85 ){
|
|
|
+ /* at least one cardinal direction (1+4+16+64=E+S+W+N) matches */
|
|
|
+ if(dir & 1){ return 1;}
|
|
|
+ if(dir & 4){ return 4;}
|
|
|
+ if(dir & 16){ return 16;}
|
|
|
+ if(dir & 64){ return 64;}
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ /* 2 8 32 128 = SE SW NW NE*/
|
|
|
+ if(dir & 2){ return 2;}
|
|
|
+ if(dir & 8){ return 8;}
|
|
|
+ if(dir & 32){ return 32;}
|
|
|
+ if(dir & 128){ return 128;}
|
|
|
+ }
|
|
|
+ return dir; /* shouldn't get here unless dir <= 0 */
|
|
|
}
|
|
|
|
|
|
|
|
@@ -152,7 +249,7 @@ char
|
|
|
directionSymbol(direction_type dir) {
|
|
|
char c='?';
|
|
|
int cnt=0;
|
|
|
- char *symbols = ">\\v/<\\^/";
|
|
|
+ char symbols[] = ">\\v/<\\^/";
|
|
|
|
|
|
if(dir == 0) return '.';
|
|
|
|
|
@@ -201,3 +298,4 @@ directionSymbol(direction_type dir) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+#undef TF_ROOTTWO
|