Ejemplo n.º 1
0
SweepContext::SweepContext(std::vector<Point*> polyline) :
  front_(0),
  head_(0),
  tail_(0),
  af_head_(0),
  af_middle_(0),
  af_tail_(0)
{
  basin = Basin();
  edge_event = EdgeEvent();

  points_ = polyline;

  InitEdges(points_);
}
Ejemplo n.º 2
0
DBInt DBNetworkIF::Build ()

	{
	DBInt i, j, row, col, basin, dir, projection = DataPTR->Projection ();
	DBCoordinate coord0, coord1;
	char nameStr [DBStringLength];
	DBPosition pos;
	DBObjRecord *cellRec, *toCell, *fromCell, *basinRec, *symbolRec;

	_DBnetIF = this;

	for (j = 0;j  < BasinTable->ItemNum ();++j)
		{
		basinRec = BasinTable->Item (j);
		if (((cellRec = Cell (MouthPosFLD->Position (basinRec))) == (DBObjRecord *) NULL) ||
			 (ToCell (cellRec) != (DBObjRecord *) NULL))
			{ BasinTable->Delete (basinRec); j--; }
		}
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		DBPause (i * 10 / CellNum ());
		if (Cell (CellPosition (cellRec)) == (DBObjRecord *) NULL) continue;
		else if (ToCell (ToCell (cellRec)) == cellRec)	ToCellFLD->Int (cellRec,DBNull);
		}
	DBPause (10);

	for (i = 0;i <  CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		DBPause (10 + i * 10 / CellNum ());
		pos = CellPosition (cellRec);
		if (((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] == DBFault)
			{ CellTable->Delete (cellRec); --i; }
		else
			{
			cellRec->Flags (DBObjectFlagLocked,DBClear);
			FromCellFLD->Int (cellRec,DBNull);
			OrderFLD->Int (cellRec,1);
			BasinFLD->Int (cellRec,DBFault);
			BasinCellsFLD->Int (cellRec,1);
			TravelFLD->Int (cellRec,0);
			UpCellPosFLD->Position (cellRec,pos);
			CellAreaFLD->Float (cellRec,DBMathRectangleArea (projection,Center (cellRec) - CellSize () / 2,Center (cellRec) + CellSize () / 2));
			coord0 = Center (cellRec); coord1 = Center (cellRec) + Delta (cellRec);
			CellLengthFLD->Float (cellRec,DBMathCoordinateDistance (DataPTR->Projection (),coord0,coord1));
			SubbasinLengthFLD->Float (cellRec,CellLength (cellRec));
			SubbasinAreaFLD->Float (cellRec,CellAreaFLD->Float (cellRec));
			}
		}
	for (j = 0;j  < BasinTable->ItemNum ();++j)
		{
		basinRec = BasinTable->Item (j);
		cellRec = Cell (MouthPosFLD->Position (basinRec));
		if ((cellRec == (DBObjRecord *) NULL) ||
			 ((cellRec->Flags () & DBObjectFlagLocked) == DBObjectFlagLocked))
			{ BasinTable->Delete (basinRec); j--; }
		else	cellRec->Flags (DBObjectFlagLocked,DBSet);
		}
	DBPause (20);

	for (row = 0;row < RowNum ();row++)	for (col = 0;col < ColNum ();col++)
			((DBInt *) DataRec->Data ()) [row * ColNum () + col] = DBFault;
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		cellRec->Flags (DBObjectFlagLocked,DBClear);
		DBPause (20 + i * 10 / CellNum ());
		pos = CellPosition (cellRec);
		if (((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] != DBFault)
			{ CellTable->Delete (cellRec); --i; }
		else
			((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID ();
		}
	DBPause (30);

	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		if ((toCell = ToCell (cellRec)) != (DBObjRecord *) NULL)
			FromCellFLD->Int (toCell,FromCellFLD->Int (toCell) | _DBNetworkOppositeDirection (ToCellFLD->Int (cellRec)));
		}
	for (i = 0;i < CellNum ();++i)
		{
		DBPause (30 + i * 10 / CellNum ());
		cellRec = CellTable->Item (i);
		if (ToCell (cellRec) == (DBObjRecord *) NULL) Climb (cellRec,0);
		}
	DBPause (40);
	CellTable->ItemSort (_DBGNetworkCellCompare);
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		DBPause (35 + i * 10/ CellNum ());
		pos = CellPosition (cellRec);
		((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID ();
		}
	DBPause (50);
	basin = 0;
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		DBPause (50 + i * 20 / CellNum ());
		if (ToCell (cellRec) == (DBObjRecord *) NULL)
			{
			SetBasin (cellRec,basin + 1);
			basinRec = (DBObjRecord *) NULL;
			for (j = 0;j < BasinTable->ItemNum ();++j)
				{
				if (((basin - j) >= 0) && ((basin - j) < BasinTable->ItemNum ()) &&
					 (cellRec == MouthCell (basinRec = BasinTable->Item (basin - j)))) break;
				if (((basin + j) < BasinTable->ItemNum ()) &&
					 (cellRec == MouthCell (basinRec = BasinTable->Item (basin + j)))) break;
				basinRec = (DBObjRecord *) NULL;
				}
			if (basinRec == (DBObjRecord *) NULL)
				{
				basinRec = BasinTable->Add ("GHAASBasin");
				MouthPosFLD->Position (basinRec,CellPosition (cellRec));
				}
			basinRec->ListPos (basin++);
			}
		}
	DBPause (70);
	CellTable->ItemSort (_DBGNetworkCellCompare);
	BasinTable->ItemSort ();
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		DBPause (70 + i * 10 / CellNum ());
		pos = CellPosition (cellRec);
		((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID ();
		sprintf (nameStr,"GHAASCell:%d",cellRec->RowID () + 1);
		cellRec->Name (nameStr);
		}
	DBPause (80);
	SymbolTable->DeleteAll ();
	symbolRec = SymbolTable->Add ("Network Symbol");
	SymbolIDFLD->Int (symbolRec,1);
	ForegroundFLD->Int (symbolRec,1);
	BackgroundFLD->Int (symbolRec,0);

	for (j = 0;j  < BasinTable->ItemNum ();++j)
		{
		basinRec = BasinTable->Item (j);
		if ((strncmp (basinRec->Name (),"GHAASBasin",strlen ("GHAASBasin")) == 0) ||
			 (strlen (basinRec->Name ()) < 1))
			{
			sprintf (nameStr,"GHAASBasin%d",basinRec->RowID () + 1);
			basinRec->Name (nameStr);
			}
		ColorFLD->Int (basinRec,DBFault);
		BasinOrderFLD->Int (basinRec,CellOrder (MouthCell (basinRec)));
		BasinAreaFLD->Float (basinRec,CellBasinArea (MouthCell (basinRec)));
		BasinLengthFLD->Float (basinRec,CellBasinLength (MouthCell (basinRec)));
		SymbolFLD->Record (basinRec,symbolRec);
		}
	basin = DBFault;
	for (i = 0;i < CellNum ();++i)
		{
		cellRec = CellTable->Item (i);
		if ((basinRec = Basin (cellRec)) == (DBObjRecord *) NULL)
			{ CMmsgPrint (CMmsgAppError,"BasinID: %d CellID:%d",BasinFLD->Int (cellRec),cellRec->RowID ()); continue; }
		if (basin != basinRec->RowID ())
			{
			basin = basinRec->RowID ();
			DBPause (80 + basin * 20 / BasinNum ());
			ColorFLD->Int (basinRec,7);
			toCell = cellRec;
			}
		for (dir = 0;dir < 8;dir += 2)
			{
			if ((fromCell = FromCell (cellRec,0x01 << dir,false)) == (DBObjRecord *) NULL) continue;
			if (basinRec == Basin (fromCell)) continue;
			if (ColorFLD->Int (basinRec) == ColorFLD->Int (Basin (fromCell)))
				{
				ColorFLD->Int (basinRec,ColorFLD->Int (basinRec) + 1);
				cellRec = MouthCell (basinRec);
				i = cellRec->RowID () - 1;
				}
			}
		}
	DBPause (100);
	if (DistToMouth ())	SetDistToMouth ();
	if (DistToOcean ())	SetDistToOcean ();
	if (Magnitude ())	SetMagnitude ();
	return (DBSuccess);
	}
int main (int nNumberofArgs,char *argv[])
{
  
  //Test for correct input arguments
	if (nNumberofArgs!=7)
	{
		cout << "FATAL ERROR: wrong number of inputs. The program needs the path (with trailing slash), the filename prefix, window radius, "; 
    cout << "basin order, a switch to use or exclude floodplains and a switch to write rasters if desired." << endl;
		exit(EXIT_SUCCESS);
	}
  
  //load input arguments
  string path = argv[1];
	string filename = argv[2];
  float window_radius = atof(argv[3]); //6
  int BasinOrder = atoi(argv[4]);  //2
  int FloodplainSwitch = atoi(argv[5]);
  int WriteRasters = atoi(argv[6]);  //0 (do not write rasters) or 1 (write rasters) 
  
  //set boundary conditions
  vector<string> BoundaryConditions(4, "No Flux");

  //load dem
  LSDRaster DEM((path+filename+"_dem"), "flt");  
  
  //Fill 
  float MinSlope = 0.0001;
  LSDRaster FilledDEM = DEM.fill(MinSlope);
  
  //surface fitting
  vector<int> raster_selection;
  
  raster_selection.push_back(0);
  raster_selection.push_back(1); //slope 
  raster_selection.push_back(1); //aspect
  raster_selection.push_back(1); //curvature
  raster_selection.push_back(1); //plan curvature
  raster_selection.push_back(0); 
  raster_selection.push_back(0);
  raster_selection.push_back(0);

  vector<LSDRaster> Surfaces = FilledDEM.calculate_polyfit_surface_metrics(window_radius, raster_selection);
  LSDRaster slope = Surfaces[1];
  LSDRaster aspect = Surfaces[2];   
  
  cout << "\nGetting drainage network and basins\n" << endl;

  // get a flow info object
	LSDFlowInfo FlowInfo(BoundaryConditions,FilledDEM);
  
  //get stream net from channel heads
  vector<int> sources = FlowInfo.Ingest_Channel_Heads((path+filename+"_dem_CH"), "flt"); //swap to csv? 
  LSDJunctionNetwork ChanNetwork(sources, FlowInfo);
  LSDIndexRaster StreamNetwork = ChanNetwork.StreamOrderArray_to_LSDIndexRaster();

  //load floodplain and merge with the channel network if required, otherwise the 
  //floodplain mask will only contain the channel data
  LSDIndexRaster ChannelAndFloodplain;

  if (FloodplainSwitch == 1){
    LSDIndexRaster Floodplains((path+filename+"_FloodPlain"), "flt");
    ChannelAndFloodplain = StreamNetwork.MergeChannelWithFloodplain(Floodplains);
  }
  else{
    ChannelAndFloodplain = StreamNetwork;
  }
                                                         
  //Extract basins based on input stream order
  vector< int > basin_junctions = ChanNetwork.ExtractBasinJunctionOrder(BasinOrder, FlowInfo);
  LSDIndexRaster Basin_Raster = ChanNetwork.extract_basins_from_junction_vector(basin_junctions, FlowInfo);
  
  cout << "\nExtracting hilltops and hilltop curvature" << endl;
  
  // extract hilltops - no critical slope filtering is performed here
  LSDRaster hilltops = ChanNetwork.ExtractRidges(FlowInfo);   
     
  //get hilltop curvature using filter to remove positive curvatures         
  LSDRaster cht_raster = FilledDEM.get_hilltop_curvature(Surfaces[3], hilltops);
  LSDRaster CHT = FilledDEM.remove_positive_hilltop_curvature(cht_raster);  
  
  //get d infinity flowdirection and flow area
  Array2D<float> dinf = FilledDEM.D_inf_FlowDir();
  LSDRaster dinf_rast = FilledDEM.LSDRasterTemplate(dinf);
  LSDRaster DinfArea = FilledDEM.D_inf_units();
  
  cout << "Starting hilltop flow routing\n" << endl;
  
  //start of Hilltop flow routing
  string prefix = (path+filename+"_dreich_");  //set a path to write the hillslope length data to, based on the input path and filename given by the user
  
  // these params do not need changed during normal use of the HFR algorithm
  bool print_paths_switch = false;
  int thinning = 1;
  string trace_path = "";
  bool basin_filter_switch = false;                          
  vector<int> Target_Basin_Vector;

  //run HFR    
  vector< Array2D<float> > HFR_Arrays = FlowInfo.HilltopFlowRouting(FilledDEM, hilltops, slope, ChannelAndFloodplain, aspect, prefix, Basin_Raster, Surfaces[4], print_paths_switch, thinning, trace_path, basin_filter_switch, Target_Basin_Vector);
   
  LSDRaster HFR_LH = hilltops.LSDRasterTemplate(HFR_Arrays[1]);
  LSDRaster HFR_Slope = hilltops.LSDRasterTemplate(HFR_Arrays[2]);
  LSDRaster relief = hilltops.LSDRasterTemplate(HFR_Arrays[3]);
  //end of HFR 

  //create lsdbasin objects in a loop over each junction number
  vector< LSDBasin > Basins;

  //slope area plotting parameters - these defaults are usually fine
  float log_bin_width = 0.1;
  int SplineResolution = 10000;
  int bin_threshold = 0;
  float CriticalSlope = 1.2; //this needs modified to generate proper E*R* data
  
  cout << "\nCreating each LSDBasin" << endl;
  
  //loop over each basin, generating an LSDBasin object which contains that basin's measurements
  for (int w = 0; w < int(basin_junctions.size()); ++w){
    
    cout << (w+1) << " / " << basin_junctions.size() << endl;
    
    LSDBasin Basin(basin_junctions[w], FlowInfo, ChanNetwork);
    Basin.set_FlowLength(StreamNetwork, FlowInfo);
    Basin.set_DrainageDensity();
    Basin.set_all_HillslopeLengths(FlowInfo, HFR_LH, slope, DinfArea, log_bin_width, SplineResolution, bin_threshold);
    Basin.set_SlopeMean(FlowInfo, slope);
    Basin.set_AspectMean(FlowInfo, aspect);
    Basin.set_ElevationMean(FlowInfo, FilledDEM);
    Basin.set_ReliefMean(FlowInfo, relief);
    Basin.set_CHTMean(FlowInfo, CHT);
    Basin.set_EStar_RStar(CriticalSlope);
    
    Basins.push_back(Basin);
                             
  }
 
  //create a filestream to write the output data
  // use the input arguments to generate a path and filename for the output file
  ofstream WriteData;                 
  stringstream ss;
  ss << path << filename << "_dreich_PaperData.txt";                
  WriteData.open(ss.str().c_str());

  //write headers
  WriteData << "BasinID HFR_mean HFR_median HFR_stddev HFR_stderr HFR_Nvalues HFR_range HFR_min HFR_max SA_binned_LH SA_Spline_LH LH_Density Area Basin_Slope_mean Basin_Slope_median Basin_Slope_stddev Basin_Slope_stderr Basin_Slope_Nvalues Basin_Slope_range Basin_Slope_min Basin_Slope_max Basin_elev_mean Basin_elev_median Basin_elev_stddev Basin_elev_stderr Basin_elev_Nvalues Basin_elev_Range Basin_elev_min Basin_elev_max Aspect_mean CHT_mean CHT_median CHT_stddev CHT_stderr CHT_Nvalues CHT_range CHT_min CHT_max EStar RStar HT_Slope_mean HT_Slope_median HT_Slope_stddev HT_Slope_stderr HT_Slope_Nvalues HT_Slope_range HT_Slope_min HT_Slope_max HT_relief_mean HT_relief_median HT_relief_stddev HT_relief_stderr HT_relief_Nvalues HT_relief_range HT_relief_min HT_relief_max" << endl;

  cout << "\nWriting data to file\n" << endl;

  //write all data to the opened file, ensuring that there are data points to be written in each basin                                         
  for (int q = 0; q < int(Basins.size()); ++q){
    // only work where we have data points
    if (Basins[q].CalculateNumDataPoints(FlowInfo, HFR_LH) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, slope) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, FilledDEM) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, CHT) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, HFR_Slope) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, relief) != 0){
      
      // BasinID
      WriteData << Basins[q].get_Junction()<< " ";
      
      //HFR
      WriteData << Basins[q].get_HillslopeLength_HFR() << " " << Basins[q].CalculateBasinMedian(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinStdError(FlowInfo, HFR_LH) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinRange(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinMin(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinMax(FlowInfo, HFR_LH)<< " ";         
      
      //SA_Bins
      WriteData << Basins[q].get_HillslopeLength_Binned()<< " ";
      
      //SA_Spline
      WriteData << Basins[q].get_HillslopeLength_Spline()<< " ";
      
      //Density
      WriteData << Basins[q].get_HillslopeLength_Density()<< " ";
      
      //Area
      WriteData << Basins[q].get_Area()<< " ";
      
      //Slope_Basin
      WriteData << Basins[q].get_SlopeMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, slope) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, slope) << " " << Basins[q].CalculateBasinStdError(FlowInfo, slope) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, slope) << " " << Basins[q].CalculateBasinRange(FlowInfo, slope) << " " << Basins[q].CalculateBasinMin(FlowInfo, slope) << " " << Basins[q].CalculateBasinMax(FlowInfo, slope)<< " ";
      
      //Elev_Basin
      WriteData << Basins[q].get_ElevationMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinStdError(FlowInfo, FilledDEM) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinRange(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinMin(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinMax(FlowInfo, FilledDEM)<< " ";
      
      //Aspect_Basin
      WriteData << Basins[q].get_AspectMean()<< " ";
      
      //CHT
      WriteData << Basins[q].get_CHTMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, CHT) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, CHT) << " " << Basins[q].CalculateBasinStdError(FlowInfo, CHT) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, CHT) << " " << Basins[q].CalculateBasinRange(FlowInfo, CHT) << " " << Basins[q].CalculateBasinMin(FlowInfo, CHT) << " " << Basins[q].CalculateBasinMax(FlowInfo, CHT) << " ";
      
      //EStar
      WriteData << Basins[q].get_EStar()<< " ";
      
      //RStar
      WriteData << Basins[q].get_RStar()<< " ";
      
      //Slope_mean
      WriteData << Basins[q].CalculateBasinMean(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMedian(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinStdError(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinRange(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMin(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMax(FlowInfo, HFR_Slope)<< " ";
      
      //Relief_mean
      WriteData << Basins[q].get_ReliefMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, relief) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, relief) << " " << Basins[q].CalculateBasinStdError(FlowInfo, relief) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, relief) << " " << Basins[q].CalculateBasinRange(FlowInfo, relief) << " " << Basins[q].CalculateBasinMin(FlowInfo, relief) << " " << Basins[q].CalculateBasinMax(FlowInfo, relief)<< "\n";
  
    }    
  } 
   
  // close the output file
  WriteData.close();

  //if the user requests the raster to be written, write the rasters
  if (WriteRasters == 1){
    cout << "Writing Rasters\n" << endl;                                   
   // FilledDEM.write_raster((path+filename+"_Fill"), "flt");
    Surfaces[1].write_raster((path+filename+"_dreich_Slope"),"flt");
    //Surfaces[2].write_raster((path+filename+"_Aspect"),"flt");
    //Surfaces[3].write_raster((path+filename+"_Curvature"),"flt");
    //StreamNetwork.write_raster((path+filename+"_STNET"), "flt"); 
    //Basin_Raster.write_raster((path+filename+"_Basins"), "flt"); 
    CHT.write_raster((path+filename+"_dreich_CHT"),"flt");
    HFR_LH.write_raster((path+filename+"_dreich_HFR_LH"),"flt"); 
    HFR_Slope.write_raster((path+filename+"_dreich_HFR_SLP"),"flt");
    relief.write_raster((path+filename+"_dreich_Relief"),"flt");
    
    //perform a hillshade
    //LSDRaster Hillshade = FilledDEM.hillshade(45.0,315.0,1.0);
    //Hillshade.write_raster((path+filename+"_HS"),"flt");
  
  }
}