//---------------------------------------------------------
void CChannelNetwork_Distance::Execute_D8(int x, int y)
{
	int		nPasses	= m_pFields ? m_pPasses->asInt   (x, y) : 0;
	double	Field	= m_pFields ? m_pFields->asDouble(x, y) : 0;

	double	sz	= m_pDistVert->asDouble(x, y);
	double	sx	= m_pDistHorz->asDouble(x, y);
	double	sd	= m_pDistance->asDouble(x, y);

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

		if( m_pDEM->is_InGrid(ix, iy) && m_Dir.asInt(ix, iy) == i )
		{
			double	dz	= m_pDEM->asDouble(ix, iy) - m_pDEM->asDouble(x, y);
			double	dx	= Get_Length(i);

			if( m_pDistVert )	m_pDistVert->Set_Value(ix, iy, sz + dz);
			if( m_pDistHorz )	m_pDistHorz->Set_Value(ix, iy, sx + dx);
			if( m_pDistance )	m_pDistance->Set_Value(ix, iy, sd + sqrt(dz*dz + dx*dx));
			if( m_pTime     )	m_pTime    ->Set_Value(ix, iy, m_pTime->asDouble(x, y) + Get_Travel_Time(x, y, i));
			if( m_pSDR      )	m_pSDR     ->Set_Value(ix, iy, m_pSDR ->asDouble(x, y) + Get_Travel_Time(x, y, i));
			if( m_pFields   )	m_pPasses  ->Set_Value(ix, iy, Field != m_pFields->asDouble(ix, iy) ? nPasses + 1 : nPasses);
		}
	}

	if( m_pSDR )
	{
		m_pSDR->Set_Value(x, y, exp(-m_Flow_B * m_pSDR->asDouble(x, y)));
	}
}
예제 #2
0
//---------------------------------------------------------
double CExercise_09::Get_Area(int x, int y)
{
	int		i, ix, iy;
	double	area;

	//-----------------------------------------------------
	area	= m_pArea->asDouble(x, y);

	if( area <= 0.0 )												// cell has not been processed yet...
	{
		m_pArea->Set_Value(x, y, 1.0);								// Very important: mark this cell as processed to prevent endless loops...

		area	= Get_Cellsize() * Get_Cellsize();								// initialize the cell's area with its own cell size...

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

			if( is_InGrid(ix, iy) && i == m_pDir->asInt(ix, iy) )	// drains ith neigbour into this cell ???...
			{
				area	+= Get_Area(ix, iy);						// ...then add its area (recursive call of this function!)...
			}
		}

		m_pArea->Set_Value(x, y, area);
	}

	//-----------------------------------------------------
	return( area );
}
//---------------------------------------------------------
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 CTIN_From_Grid_Specific_Points::Get_OppositeNB(CSG_Grid *pResult, CSG_Grid *pGrid, int Threshold)
{
	int		i, x, y, ix, iy, jx, jy;
	double	z, iz, jz;
	CSG_Grid	*clo, *chi;

	clo		= SG_Create_Grid(pGrid, SG_DATATYPE_Char);
	chi		= SG_Create_Grid(pGrid, SG_DATATYPE_Char);

	// Pass 1: Auszaehlen...
	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX()-1; x++)
        {
			z	= pGrid->asDouble(x,y);

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

				if( is_InGrid(ix,iy) )
				{
					jx	= Get_xFrom(i,x);
					jy	= Get_yFrom(i,y);
  
					if( is_InGrid(jx,jy) )
					{
						iz	= pGrid->asDouble(ix,iy);
						jz	= pGrid->asDouble(jx,jy);

						if( iz>z && jz>z )
							chi->Add_Value(x,y,1);

						else if( iz<z && jz<z )
							clo->Add_Value(x,y,1);
					}
				}
			}
		}
	}

	// Pass 2: Setzen...
	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX()-1; x++)
		{
			if( chi->asChar(x,y) )
			{
				if( clo->asChar(x,y) )
					pResult->Set_Value(x,y, 5);					// Sattel
				else
					pResult->Set_Value(x,y, chi->asChar(x,y) );	// Tiefenlinie
			}
			else if( clo->asChar(x,y) )
				pResult->Set_Value(x,y, - clo->asChar(x,y) );	// Wasserscheide
			else
				pResult->Set_Value(x,y, 0);						// Nichts...

			pResult->Set_Value(x, y, abs(pResult->asInt(x, y)) >= Threshold ? 1 : 0);
		}
	}

	delete(clo);
	delete(chi);

	return( true );
}
//---------------------------------------------------------
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 );
}