Esempio n. 1
0
/* -------------------------------------------------------------
   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;
}
Esempio n. 2
0
/* -------------------------------------------------------------
   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;
}