📄 pit_router.cpp
字号:
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 + -