/* ------------------------------------------------------------- HeadSlopeAspect This computes slope and aspect using the water table elevation. Comment: rewritten to fill the sinks (Ning, 2013) ------------------------------------------------------------- */ void HeadSlopeAspect(MAPSIZE * Map, TOPOPIX ** TopoMap, SOILPIX ** SoilMap, float **FlowGrad, unsigned char ***Dir, unsigned int **TotalDir) { int x; int y; int n; float neighbor_elev[NNEIGHBORS]; /* let's assume for now that WaterLevel is the SOILPIX map is computed elsewhere */ for (x = 0; x < Map->NX; x++) { for (y = 0; y < Map->NY; y++) { if (INBASIN(TopoMap[y][x].Mask)) { float slope, aspect; for (n = 0; n < NNEIGHBORS; n++) { int xn = x + xneighbor[n]; int yn = y + yneighbor[n]; if (valid_cell(Map, xn, yn)) { neighbor_elev[n] = ((TopoMap[yn][xn].Mask) ? SoilMap[yn][xn].WaterLevel : (float) OUTSIDEBASIN); } else { neighbor_elev[n] = (float) OUTSIDEBASIN; } } slope_aspect(Map->DX, Map->DY, SoilMap[y][x].WaterLevel, neighbor_elev, &slope, &aspect); flow_fractions(Map->DX, Map->DY, slope, aspect, neighbor_elev, &(FlowGrad[y][x]), Dir[y][x], &(TotalDir[y][x])); } } } return; }
/* ------------------------------------------------------------- ElevationSlopeAspect ------------------------------------------------------------- */ void ElevationSlopeAspect(MAPSIZE * Map, TOPOPIX ** TopoMap) { const char *Routine = "ElevationSlopeAspect"; int x; int y; int n; int k; float neighbor_elev[NNEIGHBORS]; int tempdir[NDIRS]; int steepestdirection; unsigned int sum; float min; int xn, yn; /* fill neighbor array */ for (x = 0; x < Map->NX; x++) { for (y = 0; y < Map->NY; y++) { if (INBASIN(TopoMap[y][x].Mask)) { /* Count the number of cells in the basin. Need this to allocate memory for the new, smaller Elev[] and Coords[][]. */ Map->NumCells++; for (n = 0; n < NNEIGHBORS; n++) { xn = x + xneighbor[n]; yn = y + yneighbor[n]; if (valid_cell(Map, xn, yn)) { neighbor_elev[n] = ((TopoMap[yn][xn].Mask) ? TopoMap[yn][xn].Dem : (float) OUTSIDEBASIN); } else { neighbor_elev[n] = (float) OUTSIDEBASIN; } } slope_aspect(Map->DX, Map->DY, TopoMap[y][x].Dem, neighbor_elev, &(TopoMap[y][x].Slope), &(TopoMap[y][x].Aspect)); /* fill Dirs in TopoMap too */ flow_fractions(Map->DX, Map->DY, TopoMap[y][x].Slope, TopoMap[y][x].Aspect, neighbor_elev, &(TopoMap[y][x].FlowGrad), TopoMap[y][x].Dir, &(TopoMap[y][x].TotalDir)); /* Check that upslope neighbors && outsidebasin Dir = 0. */ for (n = 0; n < NDIRS; n++) tempdir[n] = 0; /* initialize */ sum = 0; for (n = 0; n < NDIRS; n++) { xn = x + xdirection[n]; yn = y + ydirection[n]; if ((TopoMap[y][x].Dir[n] > 0) && valid_cell(Map, xn, yn)) { if (!INBASIN(TopoMap[yn][xn].Mask)) { /* Can never have flow in this direction.*/ (TopoMap[y][x].TotalDir) -= TopoMap[y][x].Dir[n]; TopoMap[y][x].Dir[n] = 0; } else if(TopoMap[yn][xn].Dem >= TopoMap[y][x].Dem) { /* Will put flow in this direction if no other choice to preserve water balance. */ (TopoMap[y][x].TotalDir) -= TopoMap[y][x].Dir[n]; tempdir[n]=TopoMap[y][x].Dir[n]; TopoMap[y][x].Dir[n] = 0; } } else if((TopoMap[y][x].Dir[n] > 0) && valid_cell(Map, xn, yn)) { /* Can never have flow in this direction, should not be possible to get here. */ (TopoMap[y][x].TotalDir) -= TopoMap[y][x].Dir[n]; TopoMap[y][x].Dir[n] = 0; } sum+=TopoMap[y][x].Dir[n]; } /* If there is a sink, check again to see if there is a direction of steepest descent. Does not account for ties.*/ steepestdirection = -99; if(sum==0) { min = DHSVM_HUGE; for (n = 0; n < NDIRS; n++) { xn = x + xdirection[n]; yn = y + ydirection[n]; if (valid_cell(Map, xn, yn)) { if (INBASIN(TopoMap[yn][xn].Mask)) { if(TopoMap[yn][xn].Dem < min) { min = TopoMap[yn][xn].Dem; steepestdirection = n; }} } } if(min < TopoMap[y][x].Dem) { TopoMap[y][x].Dir[steepestdirection] = (int)(255.0 + 0.5); TopoMap[y][x].TotalDir = (int)(255.0 + 0.5); } else { /* Last resort: set the Dir of the cell to the cell that is closest in elevation. This should only happen for the basin outlet, unless the Dem wasn't filled. */ TopoMap[y][x].Dir[steepestdirection] = (int)(255.0 + 0.5); TopoMap[y][x].TotalDir = (int)(255.0 + 0.5); xn = x + xdirection[steepestdirection]; yn = y + ydirection[steepestdirection]; } } } // end if (INBASIN(TopoMap[y][x].Mask)) { } } // end of for loops /* Create a structure to hold elevations of only those cells within the basin and the y,x of those cells.*/ if (!(Map->OrderedCells = (ITEM *) calloc(Map->NumCells, sizeof(ITEM)))) ReportError((char *) Routine, 1); k = 0; for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { /* Save the elevation, y, and x in the ITEM structure. */ if (INBASIN(TopoMap[y][x].Mask)) { Map->OrderedCells[k].Rank = TopoMap[y][x].Dem; Map->OrderedCells[k].y = y; Map->OrderedCells[k].x = x; k++; } } } /* Sort Elev in descending order-- Elev.x and Elev.y hold indices. */ quick(Map->OrderedCells, Map->NumCells); /* End of modifications to create ordered cell coordinates. SRW 10/02, LCB 03/03 */ return; }