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

📄 pit_router.cpp

📁 这是一个GPS相关的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					memcpy(pOutlet->Pit_ID, Pit_ID, 8 * sizeof(int));

					//-------------------------------------
					for(i=1; i<8; i++)
					{
						iID	= Pit_ID[i];

						if( iID >= 0 )
						{
							for(j=0; j<i; j++)
							{
								jID	= Pit_ID[j];

								if( jID >= 0 && !Get_Junction(iID, jID) )
								{
									Add_Junction(iID, jID);
								}
							}
						}
					}
				}

				//-----------------------------------------
				if( iMin >= 0 )
				{
					m_pPits->Set_Value(x,y, Pit_ID[iMin] );
				}
			}
		}

		//-------------------------------------------------
		for(i=0; i<nPits; i++)
		{
			if( m_Junction[i] )
			{
				SG_Free(m_Junction[i]);
			}
		}

		SG_Free(m_Junction);

		SG_Free(m_nJunctions);
	}

	return( 0 );
}

//---------------------------------------------------------
int CPit_Router::Find_Route(TPit_Outlet *pOutlet)
{
	bool	bDrained, bNotDrained;

	int		x, y, i, ix, iy, iMin,
			Pit_ID, nPitsDrained;

	double	z, dz, dzMin;


	//-----------------------------------------------------
	// 1. Ist Outlets Verbindung zw. Drained und Not Drained ???...

	bDrained		= false;
	bNotDrained		= false;

	for(i=0; i<8; i++)
	{
		Pit_ID	= pOutlet->Pit_ID[i];

		if( Pit_ID == 0 )
		{
			bDrained	= true;
		}
		else if( Pit_ID > 0 )
		{
			if( m_Pit[Pit_ID - 1].bDrained )
			{
				bDrained	= true;
			}
			else
			{
				bNotDrained	= true;
			}
		}
	}

	//-----------------------------------------------------
	nPitsDrained	= 0;

	if( bDrained )
	{
		if( bNotDrained )
		{
			x		= pOutlet->x;
			y		= pOutlet->y;
			z		= m_pDEM->asDouble(x,y);


			//---------------------------------------------
			// 2. Threshold ??!!...

			if( m_Threshold > 0.0 )
			{
				for(i=0; i<8; i++)
				{
					Pit_ID	= pOutlet->Pit_ID[i];

					if( Pit_ID > 0 && !m_Pit[Pit_ID - 1].bDrained && m_Threshold < z - m_Pit[Pit_ID - 1].z )
					{
						pOutlet->Pit_ID[i]	= -1;
					}
				}
			}


			//---------------------------------------------
			// 3.a) nach au遝n entwaessern...

			if( !m_pRoute->asChar(x,y) )
			{
				iMin	= -1;

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

					if( !m_pDEM->is_InGrid(ix, iy) || m_pRoute->asChar(ix, iy) > 0 )
					{
						iMin	= i;
						break;
					}
					else
					{
						Pit_ID	= pOutlet->Pit_ID[i];

						if(	Pit_ID == 0 || (Pit_ID > 0 && m_Pit[Pit_ID - 1].bDrained) )
						{
							dz		= (z - m_pDEM->asDouble(ix,iy)) / m_System.Get_Length(i);

							if( iMin < 0 || dzMin < dz )
							{
								iMin	= i;
								dzMin	= dz;
							}
						}
					}
				}

				if( iMin >= 0 )
				{
					m_pRoute->Set_Value(x,y, iMin > 0 ? iMin : 8 );
				}
				else
				{
					SG_UI_Msg_Add_Error(_TL("Routing Error"));
				}
			}


			//---------------------------------------------
			// 3.b) Pit(s)/Flat(s) drainieren...

			for(i=0; i<8; i++)
			{
				Pit_ID	= pOutlet->Pit_ID[i];

				if( Pit_ID > 0 && !m_Pit[Pit_ID - 1].bDrained )
				{
					m_Pit[Pit_ID - 1].bDrained	= true;

					Drain_Pit(x,y,Pit_ID);

					nPitsDrained++;
				}
			}
		}


		//-------------------------------------------------
		// 4. pOutlet entfernen...

		if( pOutlet->Prev )
		{
			pOutlet->Prev->Next	= pOutlet->Next;
		}
		else
		{
			m_Outlets			= pOutlet->Next;
		}

		if( pOutlet->Next )
		{
			pOutlet->Next->Prev	= pOutlet->Prev;
		}

		SG_Free(pOutlet);
	}

	return( nPitsDrained );
}


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

//---------------------------------------------------------
void CPit_Router::Add_Junction(int iID, int jID)
{
	int		i;

	if( iID != jID )
	{
		if( iID > jID )
		{
			i	= iID;
			iID	= jID;
			jID	= i;
		}

		m_nJunctions[iID]++;

		i	= m_nJunctions[iID];

		m_Junction[iID]			= (int *)SG_Realloc(m_Junction[iID], i * sizeof(int));
		m_Junction[iID][i-1]	= jID;
	}
}

//---------------------------------------------------------
bool CPit_Router::Get_Junction(int iID, int jID)
{
	int		i;

	if(	iID == jID )
	{
		return( true );
	}
	else
	{
		if( iID > jID )
		{
			i	= iID;
			iID	= jID;
			jID	= i;
		}

		for(i=0; i<m_nJunctions[iID]; i++)
		{
			if( m_Junction[iID][i] == jID )
			{
				return( true );
			}
		}
	}

	return( false );
}


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

//---------------------------------------------------------
void CPit_Router::Drain_Pit(int x, int y, int Pit_ID)
{
	int		i, ix, iy, iMin;

	double	z, dz, dzMin;

	do
	{
		iMin	= -1;

		if( m_pFlats && m_pFlats->asInt(x,y) > 0 )
		{
			Drain_Flat(x,y);
		}
		else
		{
			z		= m_pDEM->asDouble(x,y);
			dzMin	= 0;

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

				if( m_pDEM->is_InGrid(ix,iy) && m_pPits->asInt(ix,iy) == Pit_ID && !m_pRoute->asChar(ix,iy) )
				{
					dz		= (z - m_pDEM->asDouble(ix,iy)) / m_System.Get_Length(i);

					if( dzMin < dz )
					{
						iMin	= i;
						dzMin	= dz;
					}
				}
			}

			if( iMin >= 0 )
			{
				x	+= m_System.Get_xTo(iMin);
				y	+= m_System.Get_yTo(iMin);

				i	= (iMin + 4) % 8;

				m_pRoute->Set_Value(x,y, i > 0 ? i : 8 );
			}
		}
	}
	while( iMin >= 0 );
}

//---------------------------------------------------------
void CPit_Router::Drain_Flat(int x, int y)
{
	bool		bContinue;

	int			i, ix, iy, j,
				n, nPlus,
				Flat_ID;

	TGEO_iRect	*pFlat;

	//-----------------------------------------------------
	Flat_ID	= m_pFlats->asInt(x,y);

	if( Flat_ID > 0 )
	{
		pFlat	= m_Flat + Flat_ID - 1;

		nPlus	= -1;

		m_pFlats->Set_Value(x,y, nPlus );

		//-------------------------------------------------
		do
		{
			bContinue	= false;
			n			= nPlus--;

			for(y=pFlat->yMin; y<=pFlat->yMax; y++)
			{
				for(x=pFlat->xMin; x<=pFlat->xMax; x++)
				{
					if( m_pFlats->asInt(x,y) == n )
					{
						for(i=0; i<8; i++)
						{
							ix	= m_System.Get_xTo(i,x);
							iy	= m_System.Get_yTo(i,y);

							if(	m_pDEM->is_InGrid(ix, iy) && Flat_ID == m_pFlats->asInt(ix, iy) )
							{
								bContinue	= true;

								j			= (i + 4) % 8;

								m_pRoute->Set_Value(ix,iy, j ? j : 8 );
								m_pFlats->Set_Value(ix,iy, nPlus );
							}
						}
					}
				}
			}
		}
		while( bContinue );

		//-------------------------------------------------
		for(y=pFlat->yMin; y<=pFlat->yMax; y++)
		{
			for(x=pFlat->xMin; x<=pFlat->xMax; x++)
			{
				if( m_pFlats->asInt(x,y) < 0 )
				{
					m_pFlats->Set_Value(x,y, 0 );
				}
			}
		}
	}
}


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

//---------------------------------------------------------
void CPit_Router::Mark_Flat(int x, int y, TGEO_iRect *pFlat, int Flat_ID, int Pit_ID)
{
	bool	goStackDown;

	int		i, ix, iy,
			iStart, iStack, nStack,
			*xMem, *yMem, *iMem;

	double	z;

	//-----------------------------------------------------
	if( !m_pFlats )
	{
		m_pFlats		= SG_Create_Grid(m_pDEM, GRID_TYPE_Int);
		//m_pFlats->Set_Cache(false);
	}

	z			= m_pDEM->asDouble(x,y);

	xMem		= NULL;
	yMem		= NULL;
	iMem		= NULL;

	iStart		= 0;
	iStack		= 0;
	nStack		= 0;

	pFlat->xMin	= pFlat->xMax	= x;
	pFlat->yMin	= pFlat->yMax	= y;

	m_pPits->Set_Value(	x, y, Pit_ID );
	m_pFlats->Set_Value(	x, y, Flat_ID );


	//-----------------------------------------------------
	do
	{
		goStackDown	= true;

		for(i=iStart; i<8 && goStackDown; i++)
		{
			ix	= m_System.Get_xTo(i,x);
			iy	= m_System.Get_yTo(i,y);

			if(	m_pDEM->is_InGrid(ix, iy) && !m_pPits->asInt(ix, iy) && IS_Flat(z, m_pDEM->asDouble(ix, iy)) )
			{
				goStackDown		= false;
				m_pPits->Set_Value(	ix, iy, Pit_ID );
				m_pFlats->Set_Value(	ix, iy, Flat_ID );
			}
		}

		//-------------------------------------------------
		if( goStackDown )
		{
			iStack--;

			if( iStack >= 0 )
			{
				x		= xMem[iStack];
				y		= yMem[iStack];
				iStart	= iMem[iStack];
			}
		}
		else
		{
			if( nStack <= iStack )
			{
				nStack	= iStack + 32;
				xMem	= (int  *)SG_Realloc(xMem, nStack * sizeof(int ));
				yMem	= (int  *)SG_Realloc(yMem, nStack * sizeof(int ));
				iMem	= (int  *)SG_Realloc(iMem, nStack * sizeof(int ));
			}

			xMem[iStack]	= x;
			yMem[iStack]	= y;
			iMem[iStack]	= i + 1;

			x				= ix;
			y				= iy;
			iStart			= 0;

			if( x < pFlat->xMin )
				pFlat->xMin	= x;
			else if( x > pFlat->xMax )
				pFlat->xMax	= x;

			if( y < pFlat->yMin )
				pFlat->yMin	= y;
			else if( y > pFlat->yMax )
				pFlat->yMax	= y;

			iStack++;
		}
	}
	while( iStack >= 0 );

	//-----------------------------------------------------
	if( nStack > 0 )
	{
		SG_Free(xMem);
		SG_Free(yMem);
		SG_Free(iMem);
	}
}


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

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

⌨️ 快捷键说明

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