//--------------------------------------------------------- void CHillslope_Evolution_FTCS::Set_Diffusion(double dFactor) { int iStep = Parameters("NEIGHBOURS")->asInt() == 1 ? 1 : 2; m_pDEM_Old->Assign(m_pDEM); #pragma omp parallel for for(int y=0; y<Get_NY(); y++) { for(int x=0; x<Get_NX(); x++) { if( !m_pDEM_Old->is_NoData(x, y) ) { double z = m_pDEM_Old->asDouble(x, y); double dz = 0.0; for(int i=0; i<8; i+=iStep) { int ix = Get_xTo(i, x); int iy = Get_yTo(i, y); if( m_pDEM_Old->is_InGrid(ix, iy) ) { dz += (m_pDEM_Old->asDouble(ix, iy) - z) / Get_UnitLength(i); } } m_pDEM->Add_Value(x, y, dFactor * dz); } } } }
//--------------------------------------------------------- void CKinWav_D8::Get_Runoff(int x, int y) { int Direction = m_Direction.asChar(x, y); if( Direction >= 0 ) { m_pFlow->Set_Value(x, y, Get_Runoff( m_pFlow ->asDouble(x, y), m_Flow_Last .asDouble(x, y), m_Alpha .asDouble(x, y), Get_UnitLength(Direction), 0.0, 0.0 ) ); m_pFlow->Add_Value(Get_xTo(Direction, x), Get_yTo(Direction, y), m_Flow_Last.asDouble(x, y)); } }
//--------------------------------------------------------- void CPit_Eliminator::Fill_Sink(int x, int y, int j, double z) { int i, ix, iy; if( is_InGrid(x, y) && !is_Locked(x, y) && goRoute->asChar(x, y) == j ) { Lock_Set(x, y); z += M_ALMOST_ZERO * Get_UnitLength(j); if( pDTM->asDouble(x, y) < z ) { pDTM->Set_Value(x, y, z); for(i=0, j=4; i<8; i++, j=(j+1)%8) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); Fill_Sink(ix, iy, j, z); } } } }
//--------------------------------------------------------- void CChannelNetwork::Set_Channel_Route(int x, int y) { const int BUFFER_GROWSIZE = 256; int xStart, yStart, i, ix, iy, goDir, m, n, nDiv; double z, dz, dzMin, Length; //----------------------------------------------------- if( pStart->asChar(x,y) && !pChannelRoute->asChar(x,y) ) { Lock_Create(); n = 0; nDiv = 0; Length = 0; xStart = x; yStart = y; do { //--------------------------------------------- // 1. Divergence ?!... if( pConvergence ) { if( pConvergence->asDouble(x,y) > -1.0 ) { nDiv++; } else { nDiv = 0; } } if( pConvergence && nDiv > maxDivCells ) { goDir = -1; } else { //----------------------------------------- // 2. Is there any channel around ?!... goDir = 0; z = pDTM->asDouble(x,y); for(i=1; i<=8; i++) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( pDTM->is_InGrid(ix,iy) && !is_Locked(ix,iy) && pChannelRoute->asChar(ix,iy) ) { dz = (z - pDTM->asDouble(ix,iy)) / Get_Length(i); if( goDir <= 0 || dzMin < dz ) { goDir = i; dzMin = dz; } } } if( goDir <= 0 ) // ...if not then go as usual... { goDir = pChannels->asInt(x,y); } //----------------------------------------- // 3. Go to Drainage Direction !... if( goDir > 0 ) { Lock_Set(x,y); x = Get_xTo(goDir,x); y = Get_yTo(goDir,y); Length += Get_UnitLength(goDir); if( n >= Direction_Buffer ) { Direction_Buffer += BUFFER_GROWSIZE; Direction = (int *)SG_Realloc(Direction, Direction_Buffer * sizeof(int)); } Direction[n++] = goDir; } } } while( goDir > 0 && pDTM->is_InGrid(x,y) && !is_Locked(x,y) && !pChannelRoute->asChar(x,y) ); //------------------------------------------------- if( Length >= minLength ) { x = xStart; y = yStart; if( goDir < 0 ) { n -= nDiv; } for(m=0; m<n; m++) { goDir = Direction[m]; pChannelRoute->Set_Value(x,y,goDir); for(i=0; i<8; i++) // Don't start new channels beside existing ones... { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( pDTM->is_InGrid(ix,iy) ) { pStart->Set_Value(ix,iy,0); } } x = Get_xTo(goDir,x); y = Get_yTo(goDir,y); } } } }
//--------------------------------------------------------- bool CCost_Accumulated::Get_Cost(CPoints &Points) { CPoints Next; CSG_Grid Next_Index(Get_System(), SG_DATATYPE_Int); double Threshold = Parameters("THRESHOLD")->asDouble(); sLong nProcessed = Points.Get_Count(); while( Points.Get_Count() > 0 && Set_Progress_NCells(nProcessed) ) { Process_Set_Text("%s: %d", _TL("cells in process"), Points.Get_Count()); int iPoint; //------------------------------------------------- Next.Clear(); for(iPoint=0; iPoint<Points.Get_Count(); iPoint++) { TSG_Point_Int p = Points[iPoint]; double Cost = m_pCost ->asDouble(p.x, p.y); double Accu = m_pAccumulated->asDouble(p.x, p.y); for(int i=0; i<8; i++) { int ix = Get_xTo(i, p.x); int iy = Get_yTo(i, p.y); if( m_pCost->is_InGrid(ix, iy) ) { double iCost = Get_UnitLength(i); if( m_pDirection && m_pDirection->is_InGrid(p.x, p.y) && m_pDirection->is_InGrid(ix, iy) ) { static const double dAngles[8] = { 0.0, M_PI_045, M_PI_090, M_PI_135, M_PI_180, M_PI_225, M_PI_270, M_PI_315 }; double d1 = m_pDirection->asDouble(p.x, p.y); d1 = pow(cos(fabs((m_bDegree ? M_DEG_TO_RAD * d1 : d1) - dAngles[i])), m_dK); double d2 = m_pDirection->asDouble( ix, iy); d2 = pow(cos(fabs((m_bDegree ? M_DEG_TO_RAD * d2 : d2) - dAngles[i])), m_dK); iCost *= (d1 + d2) / 2.0; } iCost = Accu + iCost * (Cost + m_pCost->asDouble(ix, iy)) / 2.0; //------------------------------------- bool bProcessed = !m_pAccumulated->is_NoData(ix, iy); if( !bProcessed || m_pAccumulated->asDouble(ix, iy) > iCost + Threshold ) { if( !bProcessed ) { nProcessed++; } Next_Index .Set_Value(ix, iy, Next.Get_Count()); // remember last point (least cost!) added at position ix/iy Next .Add (ix, iy); m_pAccumulated->Set_Value(ix, iy, iCost); } } } } //------------------------------------------------- Points.Clear(); for(iPoint=0; iPoint<Next.Get_Count(); iPoint++) { TSG_Point_Int p = Next[iPoint]; if( Next_Index.asInt(p.x, p.y) == iPoint ) { Points.Add(p.x, p.y); } } } return( true ); }