⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flow_recursivedown.cpp

📁 这是一个GPS相关的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//                    Module Library:                    //
//                     ta_hydrology                      //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                Flow_RecursiveDown.cpp                 //
//                                                       //
//                 Copyright (C) 2003 by                 //
//                      Olaf Conrad                      //
//                                                       //
//-------------------------------------------------------//
//                                                       //
// This file is part of 'SAGA - System for Automated     //
// Geoscientific Analyses'. SAGA is free software; you   //
// can redistribute it and/or modify it under the terms  //
// of the GNU General Public License as published by the //
// Free Software Foundation; version 2 of the License.   //
//                                                       //
// SAGA is distributed in the hope that it will be       //
// useful, but WITHOUT ANY WARRANTY; without even the    //
// implied warranty of MERCHANTABILITY or FITNESS FOR A  //
// PARTICULAR PURPOSE. See the GNU General Public        //
// License for more details.                             //
//                                                       //
// You should have received a copy of the GNU General    //
// Public License along with this program; if not,       //
// write to the Free Software Foundation, Inc.,          //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307,   //
// USA.                                                  //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//    e-mail:     oconrad@saga-gis.org                   //
//                                                       //
//    contact:    Olaf Conrad                            //
//                Institute of Geography                 //
//                University of Goettingen               //
//                Goldschmidtstr. 5                      //
//                37077 Goettingen                       //
//                Germany                                //
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
#include "Flow_RecursiveDown.h"

//---------------------------------------------------------
#define GET_OUTLET_DIAG__1(in, angle)		(1.0 - (1.0 - in) * tan(M_PI_090 - angle))
#define GET_OUTLET_CROSS_1(in, angle)		(in + tan(angle))

#define GET_OUTLET_DIAG__2(in, angle)		(in * tan(angle))
#define GET_OUTLET_CROSS_2(in, angle)		(in - tan(M_PI_090 - angle))

#define GET_LENGTH(a, b)					(sqrt((a)*(a) + (b)*(b)))


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CFlow_RecursiveDown::CFlow_RecursiveDown(void)
{
	Set_Name(_TL("Flow Tracing"));

	Set_Author(_TL("Copyrights (c) 2001 by Olaf Conrad"));

	Set_Description	(_TW(
		"Flow tracing algorithms for calculations of flow accumulation and related parameters. "
		"These algorithms trace the flow of each cell in a DEM separately until it finally leaves the DEM or ends in a sink.\n\n"

		"References:\n\n"

		"Rho 8 (this implementation adopted the original algorithm only for the flow routing and will give quite different results):\n"
		"- Fairfield, J. / Leymarie, P. (1991):\n"
		"    'Drainage networks from grid digital elevation models',\n"
		"    Water Resources Research, 27:709-717\n\n"

		"Kinematic Routing Algorithm:\n"
		"- Lea, N.L. (1992):\n"
		"    'An aspect driven kinematic routing algorithm',\n"
		"    in: Parsons, A.J., Abrahams, A.D. (Eds.), 'Overland Flow: hydraulics and erosion mechanics', London, 147-175\n\n"

		"DEMON:\n"
		"- Costa-Cabral, M. / Burges, S.J. (1994):\n"
		"    'Digital Elevation Model Networks (DEMON): a model of flow over hillslopes for computation of contributing and dispersal areas',\n"
		"    Water Resources Research, 30:1681-1692\n\n")
	);


	//-----------------------------------------------------
	// Method...

	Parameters.Add_Choice(
		NULL	, "Method"		, _TL("Method"),
		_TL(""),
		CSG_String::Format(SG_T("%s|%s|%s|"),
			_TL("Rho 8"),
			_TL("Kinematic Routing Algorithm"),
			_TL("DEMON")
		), 1
	);


	//-----------------------------------------------------
	// Options...

	Parameters.Add_Value(
		NULL	, "MINDQV"		, _TL("DEMON - Min. DQV"),
		_TL("DEMON - Minium Drainage Quota Volume (DQV) for traced flow tubes"),
		PARAMETER_TYPE_Double	,	0.0, 0.0, true, 1.0, true
	);

	Parameters.Add_Value(
		NULL	, "CORRECT"		, _TL("Flow Correction"),
		_TL(""),
		PARAMETER_TYPE_Bool
	);
}

//---------------------------------------------------------
CFlow_RecursiveDown::~CFlow_RecursiveDown(void)
{}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CFlow_RecursiveDown::On_Initialize(void)
{
	int		x, y;
	double	Slope, Aspect;

	//-----------------------------------------------------
	Method			= Parameters("Method"	)->asInt();
	DEMON_minDQV	= Parameters("MINDQV"	)->asDouble();
	bFlowPathWeight	= Parameters("CORRECT"	)->asBool();

	pLinear			= 1 ? SG_Create_Grid(pDTM, GRID_TYPE_Float) : NULL;

	//-----------------------------------------------------
	Lock_Create();

	//-----------------------------------------------------
	switch( Method )
	{
	case 0: default:	// Rho 8...

		pDir		= NULL;
		pDif		= NULL;

		break;

	//-----------------------------------------------------
	case 1:	case 2:		// KRA, DEMON...

		pDir		= SG_Create_Grid(pDTM, GRID_TYPE_Char);
		pDif		= SG_Create_Grid(pDTM, GRID_TYPE_Float);

		for(y=0; y<Get_NY() && Set_Progress(y); y++)
		{
			for(x=0; x<Get_NX(); x++)
			{
				if( !pDTM->is_NoData(x, y) )
				{
					Get_Gradient(x, y, Slope, Aspect);

					if( Aspect >= 0.0 )
					{
						pDir->Set_Value(x, y, 2 * (((int)(Aspect / M_PI_090)) % 4));
						pDif->Set_Value(x, y, fmod(Aspect, M_PI_090));
					}
				}
			}
		}

		break;
	}
}

//---------------------------------------------------------
void CFlow_RecursiveDown::On_Finalize(void)
{
	int		x, y, dir;
	long	n;
	double	qFlow;

	//-----------------------------------------------------
	if( pDir )
	{
		delete(pDir);
	}

	if( pDif )
	{
		delete(pDif);
	}

	Lock_Destroy();

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

			if( !pDTM->is_NoData(x, y) && (qFlow = pLinear->asDouble(x, y)) > 0.0 )
			{
				Add_Flow(x, y, qFlow);

				if( (dir = pDTM->Get_Gradient_NeighborDir(x, y)) >= 0 )
				{
					x	= Get_xTo(dir, x);
					y	= Get_yTo(dir, y);

					if( pDTM->is_InGrid(x, y) )
					{
						pLinear->Add_Value(x, y, qFlow);
					}
				}
			}
		}

		delete(pLinear);

		pLinear	= NULL;
	}
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CFlow_RecursiveDown::Calculate(void)
{
	int		x, y;

	for(y=0; y<Get_NY() && Set_Progress(y); y+=Step)
	{
		//if( !(y%2) )DataObject_Update(pFlow);

		for(x=0; x<Get_NX(); x+=Step)
		{
			Calculate(x, y);
		}
	}
}

//---------------------------------------------------------
void CFlow_RecursiveDown::Calculate(int x, int y)
{
	double 	Slope, Aspect, qFlow;

	if( !pDTM->is_NoData(x, y) && (qFlow = pWeight ? pWeight->asDouble(x, y) : 1.0) > 0.0 )
	{
		Get_Gradient(x, y, Slope, Aspect);

		Src_Height	= pDTM->asDouble(x,y);
		Src_Slope	= Slope;

		Add_Flow(x, y, qFlow);
		Lock_Set(x, y, 1);

		//-------------------------------------------------
		switch( Method )
		{
		case 0:
			Rho8_Start(		x, y, qFlow );
			break;

		case 1:
			KRA_Start(		x, y, qFlow );
			break;

		case 2:
			DEMON_Start(	x, y, qFlow );
			break;
		}

		Lock_Set(x, y, 0);
	}
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CFlow_RecursiveDown::Add_Flow(int x, int y, double Fraction)
{
	if( pCatch )
	{
		pCatch			->Add_Value(x, y, Fraction );
	}

	if( pCatch_Height )
	{
		pCatch_Height	->Add_Value(x, y, Fraction * Src_Height );
	}

	if( pCatch_Slope )
	{
		pCatch_Slope	->Add_Value(x, y, Fraction * Src_Slope );
	}
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CFlow_RecursiveDown::Rho8_Start(int x, int y, double qFlow)
{
	int		dir, ix, iy;
	double 	Slope, Aspect;

	//-----------------------------------------------------
	Get_Gradient(x, y, Slope, Aspect);

	if( Aspect >= 0.0 )
	{
		dir		= (int)(Aspect / M_PI_045);

		if( fmod(Aspect, M_PI_045) / M_PI_045 > rand() / (double)RAND_MAX )
		{
			dir++;
		}

		dir	%= 8;

		ix		= Get_xTo(dir, x);
		iy		= Get_yTo(dir, y);

		//-------------------------------------------------
		if( is_InGrid(ix, iy) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -