示例#1
0
//---------------------------------------------------------
void CD8_Flow_Analysis::Get_Basins(void)
{
	Process_Set_Text(_TL("Drainage Basins"));

	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(int x=0; x<Get_NX(); x++)
		{
			Get_Basin(x, y);
		}
	}

	//-----------------------------------------------------
	CSG_Shapes	*pBasins	= Parameters("BASINS")->asShapes();

	if( pBasins )
	{
		bool	bResult;

		SG_RUN_MODULE(bResult, "shapes_grid", 6,
				pModule->Get_Parameters()->Set_Parameter(SG_T("GRID")    , m_pBasins)
			&&	pModule->Get_Parameters()->Set_Parameter(SG_T("POLYGONS"),   pBasins)
		)

		pBasins->Set_Name(_TL("Drainage Basins"));
	}
}
示例#2
0
//---------------------------------------------------------
int CD8_Flow_Analysis::Get_Basin(int x, int y)
{
	int		i, Basin	= m_pBasins->asInt(x, y);

	if( Basin <= 0 && (i = m_pDir->asInt(x, y)) >= 0 && (Basin = Get_Basin(Get_xTo(i, x), Get_yTo(i, y))) > 0 )
	{
		m_pBasins->Set_Value(x, y, Basin);
	}

	return( Basin );
}
示例#3
0
//---------------------------------------------------------
int CWatersheds::Get_Basin(int x, int y)
{
	int		i, ix, iy, nCells;

	if( m_pBasins->is_NoData(x, y) && !m_Direction.is_NoData(x, y) )
	{
		m_pBasins->Set_Value(x, y, m_nBasins);

		for(i=0, nCells=1; i<8; i++)
		{
			ix	= Get_xTo(i, x);
			iy	= Get_yTo(i, y);

			if( is_InGrid(ix,iy) && m_Direction.asInt(ix, iy) == i )
			{
				nCells	+= Get_Basin(ix, iy);
			}
		}

		return( nCells );
	}

	return( -1 );
}
//---------------------------------------------------------
bool CWatersheds_ext::Get_Basin(CSG_Grid *pBasins, CSG_Shapes *pPolygons, int xMouth, int yMouth, int Main_ID)
{
	int						x, y, Basin_ID	= 1 + pPolygons->Get_Count();
	CSG_Shape				*pPolygon;
	CSG_Grid_Stack			Stack;
	CSG_Simple_Statistics	s_Height, s_Distance;

	//-----------------------------------------------------
	Stack.Push(x = xMouth, y = yMouth);

	pBasins		->Set_Value(x, y, Basin_ID);
	m_Distance	 .Set_Value(x, y, 0.0);

	s_Height	+= m_pDEM->asDouble(x, y);
	s_Distance	+= 0.0;

	//-----------------------------------------------------
	while( Stack.Get_Size() > 0 && Process_Get_Okay() )
	{
		Stack.Pop(x, y);

		double	d	= m_Distance.asDouble(x, y);

		//-------------------------------------------------
		for(int i=0; i<8; i++)
		{
			int	ix	= Get_xFrom(i, x);
			int	iy	= Get_yFrom(i, y);

			if( is_InGrid(ix, iy) && pBasins->is_NoData(ix, iy) && i == m_Direction.asInt(ix, iy) )
			{
				Stack.Push(ix, iy);

				pBasins		->Set_Value(ix, iy, Basin_ID);
				m_Distance	 .Set_Value(ix, iy, d + Get_Length(i));

				s_Height	+= m_pDEM->asDouble(ix, iy);
				s_Distance	+= d + Get_Length(i);
			}
		}
	}

	//-----------------------------------------------------
	if( s_Height.Get_Count() > 1 && (pPolygon = Get_Basin(pBasins, pPolygons)) != NULL )
	{
		double		d, Area, Perimeter, Side_A, Side_B;
		CSG_String	Gravelius;

	//	Area		= s_Height.Get_Count() * Get_System()->Get_Cellarea();
		Area		= ((CSG_Shape_Polygon*)pPolygon)->Get_Area();
		Perimeter	= ((CSG_Shape_Polygon*)pPolygon)->Get_Perimeter();

		d			= 0.28 * Perimeter / sqrt(Area);
		Gravelius	= d > 1.75 ? _TL("rectangular")
					: d > 1.5  ? _TL("ovalooblonga-rectangularoblonga")
					: d > 1.25 ? _TL("ovaloredonda-ovalooblonga")
					:            _TL("redonda-ovaloredonda");

		d			= pow(Perimeter, 2.0) - 8.0 * Area;
		Side_A		= d > 0.0 ? (Perimeter + sqrt(d))      / 4.0 : -1.0;
		Side_B		= d > 0.0 ? (Perimeter - 2.0 * Side_A) / 2.0 : -1.0;

		pPolygon->Set_Value(FIELD_ID			, Basin_ID);
		pPolygon->Set_Value(FIELD_ID_MAIN		, Main_ID);

		pPolygon->Set_Value(FIELD_MOUTH_X		, Get_System()->Get_xGrid_to_World(xMouth));
		pPolygon->Set_Value(FIELD_MOUTH_Y		, Get_System()->Get_yGrid_to_World(yMouth));

		pPolygon->Set_Value(FIELD_PERIMETER		, Perimeter);
		pPolygon->Set_Value(FIELD_AREA			, Area);

		pPolygon->Set_Value(FIELD_CENTROID_X	, ((CSG_Shape_Polygon*)pPolygon)->Get_Centroid().x);
		pPolygon->Set_Value(FIELD_CENTROID_Y	, ((CSG_Shape_Polygon*)pPolygon)->Get_Centroid().y);

		pPolygon->Set_Value(FIELD_Z_MEAN		, s_Height  .Get_Mean());
		pPolygon->Set_Value(FIELD_Z_RANGE		, s_Height  .Get_Range());

		pPolygon->Set_Value(FIELD_DIST_MEAN		, s_Distance.Get_Mean());
		pPolygon->Set_Value(FIELD_DIST_MAX		, s_Distance.Get_Maximum());

		pPolygon->Set_Value(FIELD_CONCTIME		, s_Height.Get_Range() <= 0.0 ? -1.0 :
			pow(0.87 * pow(s_Distance.Get_Maximum() / 1000.0, 3.0) / s_Height.Get_Range(),  0.385)
		);

		pPolygon->Set_Value(FIELD_BASIN_TYPE	, Gravelius);

		pPolygon->Set_Value(FIELD_EQVRECT_A		, Side_A);
		pPolygon->Set_Value(FIELD_EQVRECT_B		, Side_B);

		pPolygon->Set_Value(FIELD_OROG_IDX		, SG_Get_Square(s_Height.Get_Mean()) / (0.0001 * Area));	// Orographic index, defined as the mean catchment altitude times the ratio of the mean catchment altitude to the orthogonal projection of drainage area (Alcázar, Palau (2010): Establishing environmental flow regimes in a Mediterranean watershed based on a regional classification. Journal of Hydrology, V. 388
		pPolygon->Set_Value(FIELD_MASS_IDX		, Perimeter / (0.0001 * Area));								// Perimeter / (0.0001 * Area) ??!!

		pPolygon->Set_Value(FIELD_BASINS_UP		, 0.0);	// Upslope Basins
		pPolygon->Set_Value(FIELD_BASINS_DOWN	, 0.0);	// Downslope Basins

		return( true );
	}

	return( false );
}
//---------------------------------------------------------
bool CWatersheds_ext::On_Execute(void)
{
	int			x, y;
	CSG_Grid	*pBasins, *pSubBasins, Inflows;
	CSG_Shapes	*pHeads, *pMouths, *pVBasins, *pVSubBasins;

	m_pDEM		= Parameters("DEM")			->asGrid(); 
	m_pChannels	= Parameters("CHANNELS")	->asGrid();
	pBasins		= Parameters("BASINS")		->asGrid();
	pSubBasins	= Parameters("SUBBASINS")	->asGrid();
	pVBasins	= Parameters("V_BASINS")	->asShapes();
	pVSubBasins	= Parameters("V_SUBBASINS")	->asShapes();
	pHeads		= Parameters("HEADS")		->asShapes();
	pMouths		= Parameters("MOUTHS")		->asShapes();

	//-----------------------------------------------------
	Inflows		.Create(*Get_System(), SG_DATATYPE_Char);

	m_Direction	.Create(*Get_System(), SG_DATATYPE_Char);
	m_Direction	.Set_NoData_Value(-1);

	m_Distance	.Create(*Get_System(), SG_DATATYPE_Float);
	m_Distance	.Set_NoData_Value(-1);
	m_Distance	.Assign_NoData();

	pBasins		->Assign(0.0);
	pBasins		->Set_NoData_Value(0.0);

	pSubBasins	->Assign(0.0);
	pSubBasins	->Set_NoData_Value(0.0);

	pHeads		->Create(SHAPE_TYPE_Point	, _TL("Heads"));
	pHeads		->Add_Field("ID"			, SG_DATATYPE_Int);
	pHeads		->Add_Field("MAIN_ID"		, SG_DATATYPE_Int);
	pHeads		->Add_Field("ELEVATION"		, SG_DATATYPE_Double);
	pHeads		->Add_Field("DISTANCE"		, SG_DATATYPE_Double);

	pMouths		->Create(SHAPE_TYPE_Point	, _TL("Mouths"));
	pMouths		->Add_Field("ID"			, SG_DATATYPE_Int);
	pMouths		->Add_Field("MAIN_ID"		, SG_DATATYPE_Int);
	pMouths		->Add_Field("ELEVATION"		, SG_DATATYPE_Double);

	pVBasins	->Create(SHAPE_TYPE_Polygon	, _TL("Basins"));
	BASIN_ADD_FIELDS(pVBasins);

	pVSubBasins	->Create(SHAPE_TYPE_Polygon	, _TL("Subbasins"));
	BASIN_ADD_FIELDS(pVSubBasins);

	//-----------------------------------------------------
	Process_Set_Text(_TL("flow directions..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			int	Direction	= -1;

			if( m_pDEM->is_InGrid(x, y) )
			{
				double	dMax		= 0.0;

				for(int i=0; i<8; i++)
				{
					int	ix	= Get_xTo(i, x);
					int	iy	= Get_yTo(i, y);

					if( m_pDEM->is_InGrid(ix, iy) && !m_pChannels->is_NoData(ix, iy) )
					{
						double	dz	= (m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy)) / Get_Length(i);

						if( dMax < dz )
						{
							dMax		= dz;
							Direction	= i;
						}
					}
				}

				if( !m_pChannels->is_NoData(x, y) )
				{
					if( Direction >= 0 )
					{
						int	ix	= Get_xTo(Direction, x);
						int	iy	= Get_yTo(Direction, y);

						if( m_pDEM->is_InGrid(ix, iy) )
						{
							Inflows.Add_Value(ix, iy, 1);
						}
					}
				}
				else if( Direction < 0 )
				{
					Direction	= m_pDEM->Get_Gradient_NeighborDir(x, y);
				}
			}

			m_Direction.Set_Value(x, y, Direction);
		}
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("main basins..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			if( m_pChannels->is_InGrid(x, y) && is_Outlet(x, y) )
			{
				Get_Basin(pBasins, pVBasins, x, y, -1);

				CSG_Shape	*pMouth	= pMouths->Add_Shape();

				pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y));

				pMouth->Set_Value(0, pVBasins->Get_Count());	// ID
				pMouth->Set_Value(1, pVBasins->Get_Count());	// MAIN_ID
				pMouth->Set_Value(2, m_pDEM->asDouble(x, y));	// ELEVATION
			}
		}
	}

	if( Parameters("DISTANCE")->asBool() )
	{
		m_Distance.Set_Name(_TL("Flow Distance"));

		DataObject_Add(SG_Create_Grid(m_Distance));
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("heads and mouths..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			if( m_pChannels->is_InGrid(x, y) )
			{
				//-----------------------------------------
				if( Inflows.asInt(x, y) > 1 )		// mouth, linking channels of subcatchments
				{
					CSG_Shape	*pMouth	= pMouths->Add_Shape();

					pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y));

					pMouth->Set_Value(0, pMouths->Get_Count());		// ID
					pMouth->Set_Value(1, pBasins->asDouble(x, y));	// MAIN_ID
					pMouth->Set_Value(2, m_pDEM->asDouble(x, y));	// ELEVATION
				}

				//-----------------------------------------
				else if( Inflows.asInt(x, y) == 0 )	// head
				{
					CSG_Shape	*pHead	= pHeads->Add_Shape();

					pHead->Add_Point(Get_System()->Get_Grid_to_World(x, y));

					pHead->Set_Value(0, pHeads->Get_Count() + 1);
					pHead->Set_Value(1, m_Distance.asDouble(x, y));
				}
			}
		}
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("subbasins..."));

	pMouths->Set_Index(1, TABLE_INDEX_Ascending, 2, TABLE_INDEX_Descending);

	for(int iMouth=0; iMouth<pMouths->Get_Count() && Set_Progress(iMouth, pMouths->Get_Count()); iMouth++)
	{
		CSG_Shape	*pMouth	= pMouths->Get_Shape_byIndex(iMouth);

		if( Get_System()->Get_World_to_Grid(x, y, pMouth->Get_Point(0)) )
		{
			if( pMouth->asInt(0) == pMouth->asInt(1) )
			{
				Get_Basin(pSubBasins, pVSubBasins, x, y, pMouth->asInt(1));
			}
			else
			{
				for(int i=0; i<8; i++)
				{
					int	ix	= Get_xFrom(i, x);
					int	iy	= Get_yFrom(i, y);

					if( m_pChannels->is_InGrid(ix, iy) && m_Direction.asInt(ix, iy) == i )
					{
						Get_Basin(pSubBasins, pVSubBasins, ix, iy, pMouth->asInt(1));
					}
				}
			}
		}
	}

	if( Parameters("DISTANCE")->asBool() )
	{
		m_Distance.Set_Name(_TL("Subbasin Flow Distance"));

		DataObject_Add(SG_Create_Grid(m_Distance));
	}

	//-----------------------------------------------------
	m_Distance	.Destroy();
	m_Direction	.Destroy();

	return( true );
}
示例#6
0
//---------------------------------------------------------
bool CWatersheds::On_Execute(void)
{
	int			x, y, nCells, nCells_Min, nBasins;
	sLong		n;
	CSG_Grid	*pDTM, *pSeed, *pRoute;

	//-----------------------------------------------------
	pDTM		= Parameters("ELEVATION")->asGrid();
	pSeed		= Parameters("CHANNELS" )->asGrid();
	pRoute		= Parameters("SINKROUTE")->asGrid();
	nCells_Min	= Parameters("MINSIZE"  )->asInt();
	m_pBasins	= Parameters("BASINS"   )->asGrid();

	m_pBasins->Set_NoData_Value(NO_BASIN);
	m_pBasins->Assign_NoData();

	if( !pDTM->Set_Index() )
	{
		Error_Set(_TL("index creation failed"));

		return( false );
	}

	m_Direction.Create(m_pBasins, SG_DATATYPE_Char);

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			if( pDTM->is_NoData(x, y) )
			{
				m_Direction.Set_NoData(x, y);
			}
			else
			{
				if( !pRoute || (n = pRoute->asChar(x, y)) <= 0 )
				{
					n	= pDTM->Get_Gradient_NeighborDir(x, y);
				}

				m_Direction.Set_Value(x, y, (int)(n < 0 ? -1 : (n + 4) % 8));
			}
		}
	}

	//-----------------------------------------------------
	for(n=0, m_nBasins=0; n<Get_NCells() && Set_Progress_NCells(n); n++)
	{
		pDTM->Get_Sorted(n, x, y, true, false);

		if( !pSeed->is_NoData(x, y) && pSeed->asInt(x, y) < 0 )
		{
			m_nBasins++;

			if( (nCells = Get_Basin(x, y)) < nCells_Min )
			{
				nBasins		= m_nBasins - 1;
				m_nBasins	= NO_BASIN;
				Get_Basin(x, y);
				m_nBasins	= nBasins;
			}
		}
	}

	//-----------------------------------------------------
	m_Direction.Destroy();

	return( true );
}