//--------------------------------------------------------- double CExercise_14::Vectorise(int x, int y, CSG_Shape *pSegment) { int Dir, ix, iy; double Length; Length = 0.0; pSegment->Add_Point(Get_XMin() + x * Get_Cellsize(), Get_YMin() + y * Get_Cellsize()); if( (Dir = m_pDir->asInt(x, y)) >= 0 ) { Length = Get_Length(Dir); ix = Get_xTo(Dir, x); iy = Get_yTo(Dir, y); switch( m_pChnl->asInt(ix, iy) ) { case CHANNEL: Length += Vectorise(ix, iy, pSegment); // recursive function call... break; case MOUTH: Length += Get_Length(Dir); pSegment->Add_Point(Get_XMin() + ix * Get_Cellsize(), Get_YMin() + iy * Get_Cellsize()); break; } } return( Length ); }
//--------------------------------------------------------- double CErosion_LS_Fields::Get_Flow(int x, int y, double dz[8]) { if( m_Fields.is_NoData(x, y) ) { return( 0.0 ); } double d, z = m_pDEM->asDouble(x, y), dzSum = 0.0; int ID = m_Fields.asInt(x, y); for(int i=0; i<8; i++) { dz[i] = 0.0; int ix = Get_xTo(i, x); int iy = Get_yTo(i, y); if( m_pDEM->is_InGrid(ix, iy) && (d = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { if( ID == m_Fields.asInt(ix, iy) ) { dzSum += (dz[i] = pow(d / Get_Length(i), 1.1)); } else if( m_bStopAtEdge ) { dzSum += pow(d / Get_Length(i), 1.1); } } } return( dzSum ); }
//--------------------------------------------------------- void CChannelNetwork_Distance::Initialize_MFD(int x, int y) { const double MFD_Convergence = 1.1; double Flow[8], dz, zSum = 0.0, z = m_pDEM->asDouble(x, y); if( m_pRoute ) { for(int i=0, ix, iy; i<8; i++) { if( m_pDEM->is_InGrid(ix=Get_xTo(i, x), iy=Get_yTo(i, y)) && !m_pRoute->is_NoData(ix, iy) && (dz = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { zSum += (Flow[i] = pow(dz / Get_Length(i), MFD_Convergence)); } else { Flow[i] = 0.0; } } } if( zSum == 0.0 ) { for(int i=0, ix, iy; i<8; i++) { if( m_pDEM->is_InGrid(ix=Get_xTo(i, x), iy=Get_yTo(i, y)) && (dz = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { zSum += (Flow[i] = pow(dz / Get_Length(i), MFD_Convergence)); } else { Flow[i] = 0.0; } } } if( zSum > 0.0 ) { m_Flow[8].Set_Value(x, y, zSum); for(int i=0; i<8; i++) { if( Flow[i] > 0.0 ) { m_Flow[i].Set_Value(x, y, Flow[i] / zSum); } } } }
//--------------------------------------------------------- void CChannelNetwork::Set_Route_Standard(int x, int y) { int i, ix, iy, iMin; double z, dz, dzMin; z = pDTM->asDouble(x,y); iMin = 0; for(i=1; i<=8; i++) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( !pDTM->is_InGrid(ix,iy) ) { iMin = i; break; } else { dz = (z - pDTM->asDouble(ix,iy)) / Get_Length(i); if( iMin <= 0 || dzMin < dz ) { iMin = i; dzMin = dz; } } } pChannels->Set_Value(x,y, iMin ); }
//--------------------------------------------------------- bool CChannelNetwork_Distance::Set_D8(int x, int y) { int Direction; if( !Get_D8(x, y, Direction) ) { return( false ); } int ix = Get_xTo(Direction, x), iy = Get_yTo(Direction, y); double dz = m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy); double dx = Get_Length(Direction); m_pDistance->Set_Value(x, y, m_pDistance->asDouble(ix, iy) + sqrt(dz*dz + dx*dx)); m_pDistVert->Set_Value(x, y, m_pDistVert->asDouble(ix, iy) + dz); m_pDistHorz->Set_Value(x, y, m_pDistHorz->asDouble(ix, iy) + dx); if( m_pTime ) { double dt = Get_Travel_Time(x, y, Direction); m_pTime->Set_Value(x, y, m_pTime->asDouble(ix, iy) + dt); } if( m_pFields ) { int Crossed = m_pFields->asDouble(ix, iy) == m_pFields->asDouble(x, y) ? 0 : 1; m_pPasses->Set_Value(x, y, m_pPasses->asInt(ix, iy) + Crossed); } return( true ); }
//--------------------------------------------------------- inline double CChannelNetwork_Distance::Get_Travel_Time(int x, int y, int Direction) { int ix = Get_xTo(Direction, x), iy = Get_yTo(Direction, y); double v, k, R, dz, dx; dz = m_pDEM->is_InGrid(ix, iy) ? m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy) : 0.1; dx = Get_Length(Direction); // k = m_pFlow_K && !m_pFlow_K->is_NoData(x, y) ? m_pFlow_K->asDouble(x, y) : m_Flow_K; k = !m_pFlow_K || (m_pFlow_K->is_NoData(x, y) && m_pFlow_K->is_NoData(ix, iy)) ? m_Flow_K : m_pFlow_K->is_NoData( x, y) ? m_pFlow_K->asDouble(ix, iy) : m_pFlow_K->is_NoData(ix, iy) ? m_pFlow_K->asDouble( x, y) : (m_pFlow_K->asDouble(x, y) + m_pFlow_K->asDouble(ix, iy)) / 2.0; // R = m_pFlow_R && !m_pFlow_R->is_NoData(x, y) ? m_pFlow_R->asDouble(x, y) : m_Flow_R; R = !m_pFlow_R || (m_pFlow_R->is_NoData(x, y) && m_pFlow_R->is_NoData(ix, iy)) ? m_Flow_R : m_pFlow_R->is_NoData( x, y) ? m_pFlow_R->asDouble(ix, iy) : m_pFlow_R->is_NoData(ix, iy) ? m_pFlow_R->asDouble( x, y) : (m_pFlow_R->asDouble(x, y) + m_pFlow_R->asDouble(ix, iy)) / 2.0; v = k * pow(R, 2.0 / 3.0) * sqrt(dz / dx); // [m / s], simplified Manning equation return( dx / (v * 3600.0) ); // return travel time in hours }
//--------------------------------------------------------- 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))); } }
//--------------------------------------------------------- void CFlow_by_Slope::Set_Area(int x, int y) { double Decay; if( Get_Decay(x, y, Decay) ) { int i, ix, iy; double z, dzSum, dz[8]; for(i=0, dzSum=0.0, z=m_pDEM->asDouble(x, y); i<8; i++) { if( m_pDEM->is_InGrid(ix = Get_xTo(i, x), iy = Get_yTo(i, y)) && (dz[i] = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { dzSum += (dz[i] = pow(dz[i] / Get_Length(i), 1.1)); } else { dz[i] = 0.0; } } if( dzSum > 0.0 ) { Decay *= m_pFlow->asDouble(x, y) / dzSum; for(i=0; i<8; i++) { if( dz[i] > 0.0 ) { m_pFlow->Add_Value(Get_xTo(i, x), Get_yTo(i, y), Decay * dz[i]); } } } } }
//--------------------------------------------------------- void CChannelNetwork_Distance::Initialize_D8(int x, int y) { int i, iMax, iRoute; double z, dz, dzMax, dzRoute; for(i=0, iMax=-1, dzMax=0.0, iRoute=-1, dzRoute=0.0, z=m_pDEM->asDouble(x, y); i<8; i++) { int ix = Get_xTo(i, x); int iy = Get_yTo(i, y); if( is_InGrid(ix, iy) && (dz = (z - m_pDEM->asDouble(ix, iy)) / Get_Length(i)) > 0.0 ) { if( dz > dzMax ) { iMax = i; dzMax = dz; } if( m_pRoute && !m_pRoute->is_NoData(ix, iy) && dz > dzRoute ) { iRoute = i; dzRoute = dz; } } } m_Dir.Set_Value(x, y, iRoute >= 0 ? iRoute : iMax); }
//--------------------------------------------------------- void CFlow_RecursiveUp::Set_MFD(int x, int y) { int i, ix, iy; double z, d, *dz, dzSum; z = pDTM->asDouble(x,y); dz = Flow[y][x]; dzSum = 0; for(i=0; i<8; i++) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( is_InGrid(ix,iy) ) { d = z - pDTM->asDouble(ix,iy); if( d > 0 ) dzSum += dz[i] = pow(d / Get_Length(i), MFD_Converge); } } if( dzSum ) { for(i=0; i<8; i++) if( dz[i] > 0 ) dz[i] /= dzSum; } }
//--------------------------------------------------------- double CConvergence::Get_2x2(int x, int y, bool bGradient) { int i, n; double Height, Slope, Aspect, iSlope, iAspect, d, dSum; for(i=0, n=0, dSum=0.0, iAspect=-M_PI_135; i<4; i++, iAspect+=M_PI_090) { if( Get_2x2_Gradient(x, y, i, Slope, Aspect, Height) ) { d = Aspect - iAspect; if( bGradient ) { iSlope = atan((Height - m_pDTM->asDouble(x, y)) / Get_Length(1)); d = acos(sin(Slope) * sin(iSlope) + cos(Slope) * cos(iSlope) * cos(d)); // Nach dem Seiten-Kosinus-Satz... } d = fmod(d, M_PI_360); if( d < -M_PI_180 ) { d += M_PI_360; } else if( d > M_PI_180 ) { d -= M_PI_360; } dSum += fabs(d); n++; } } return( n > 0 ? (dSum / (double)n - M_PI_090) * 100.0 / M_PI_090 : 0.0 ); }
//--------------------------------------------------------- double CSG_Vector::Get_Angle(const CSG_Vector &Vector) const { if( Get_N() > Vector.Get_N() ) { return( Vector.Get_Angle(*this) ); } int i; double A, B, z, *Z = Get_Data(); if( (A = Get_Length()) > 0.0 && (B = Vector.Get_Length()) > 0.0 ) { for(i=0, z=0.0; i<Get_N(); i++) { z += Vector[i] * Z[i]; } for(i=Get_N(); i<Vector.Get_N(); i++) { z += Vector[i]; } return( acos(z / (A * B)) ); } return( 0.0 ); }
//--------------------------------------------------------- void CFlow_Distance::Set_Length_MFD(int x, int y) { int i, ix, iy; double z, d, dzSum, dz[8]; if( m_pDTM->is_InGrid(x, y) ) { z = m_pDTM->asDouble(x, y); dzSum = 0.0; for(i=0; i<8; i++) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( m_pDTM->is_InGrid(ix, iy) && (d = z - m_pDTM->asDouble(ix, iy)) > 0.0 ) { dz[i] = pow(d / Get_Length(i), m_Converge); dzSum += dz[i]; } else { dz[i] = 0.0; } } if( dzSum > 0.0 ) { d = m_pLength->asDouble(x, y); for(i=0; i<8; i++) { if( dz[i] > 0.0 ) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); dz[i] /= dzSum; m_pLength->Add_Value(ix, iy, dz[i] * (d + Get_Length(i))); m_pWeight->Add_Value(ix, iy, dz[i]); } } } } }
//--------------------------------------------------------- bool CChannelNetwork_Distance::Get_MFD(int x, int y, CSG_Vector &Flow) { const double MFD_Convergence = 1.1; double dz, Sum = 0.0, z = m_pDEM->asDouble(x, y); if( m_pRoute ) { for(int i=0; i<8; i++) { int ix = Get_xTo(i, x), iy = Get_yTo(i, y); if( m_pDEM->is_InGrid(ix, iy) && !m_pRoute->is_NoData(ix, iy) && (dz = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { Sum += (Flow[i] = pow(dz / Get_Length(i), MFD_Convergence)); } } if( Sum > 0.0 ) { Flow *= 1. / Sum; return( true ); } } for(int i=0; i<8; i++) { int ix = Get_xTo(i, x), iy = Get_yTo(i, y); if( m_pDEM->is_InGrid(ix, iy) && !m_pDistance->is_NoData(ix, iy) && (dz = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { Sum += (Flow[i] = pow(dz / Get_Length(i), MFD_Convergence)); } } if( Sum > 0.0 ) { Flow *= 1. / Sum; return( true ); } return( false ); }
//--------------------------------------------------------- void CChannelNetwork_Distance::Execute_MFD(int x, int y) { double df = m_Flow[8].asDouble(x, y); if( df > 0.0 ) { if( m_pDistance ) m_pDistance->Mul_Value(x, y, 1.0 / df); if( m_pDistVert ) m_pDistVert->Mul_Value(x, y, 1.0 / df); if( m_pDistHorz ) m_pDistHorz->Mul_Value(x, y, 1.0 / df); if( m_pTime ) m_pTime ->Mul_Value(x, y, 1.0 / df); if( m_pSDR ) m_pSDR ->Mul_Value(x, y, 1.0 / df); } 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_xTo(i, x); int iy = Get_yTo(i, y); if( m_pDEM->is_InGrid(ix, iy) && (df = m_Flow[(i + 4) % 8].asDouble(ix, iy)) > 0.0 ) { double dz = m_pDEM->asDouble(ix, iy) - m_pDEM->asDouble(x, y); double dx = Get_Length(i); double dt = m_pTime || m_pSDR ? Get_Travel_Time(x, y, i) : 1.0; if( m_pDistance->is_NoData(ix, iy) ) { m_Flow[8].Set_Value(ix, iy, df); if( m_pDistVert ) m_pDistVert->Set_Value(ix, iy, df * (sz + dz)); if( m_pDistHorz ) m_pDistHorz->Set_Value(ix, iy, df * (sx + dx)); if( m_pDistance ) m_pDistance->Set_Value(ix, iy, df * (sd + sqrt(dz*dz + dx*dx))); if( m_pTime ) m_pTime ->Set_Value(ix, iy, df * (m_pTime->asDouble(x, y) + dt)); if( m_pSDR ) m_pSDR ->Set_Value(ix, iy, df * (m_pSDR ->asDouble(x, y) + dt)); } else { m_Flow[8].Add_Value(ix, iy, df); if( m_pDistVert ) m_pDistVert->Add_Value(ix, iy, df * (sz + dz)); if( m_pDistHorz ) m_pDistHorz->Add_Value(ix, iy, df * (sx + dx)); if( m_pDistance ) m_pDistance->Add_Value(ix, iy, df * (sd + sqrt(dz*dz + dx*dx))); if( m_pTime ) m_pTime ->Add_Value(ix, iy, df * (m_pTime->asDouble(x, y) + dt)); if( m_pSDR ) m_pSDR ->Add_Value(ix, iy, df * (m_pSDR ->asDouble(x, y) + dt)); } } } if( m_pSDR ) { m_pSDR->Set_Value(x, y, exp(-m_Flow_B * m_pSDR->asDouble(x, y))); } }
//--------------------------------------------------------- inline double CChannelNetwork_Distance::Get_Travel_Time(int x, int y, int i) { double dz = m_pDEM->asDouble(Get_xTo(i, x), Get_yTo(i, y)) - m_pDEM->asDouble(x, y); double dx = Get_Length(i); double k = m_pFlow_K && !m_pFlow_K->is_NoData(x, y) ? m_pFlow_K->asDouble(x, y) : m_Flow_K; double R = m_pFlow_R && !m_pFlow_R->is_NoData(x, y) ? m_pFlow_R->asDouble(x, y) : m_Flow_R; double v = k * pow(R, 2.0 / 3.0) * sqrt(dz / dx); // [m / s], simplified Manning equation return( dx / (v * 3600.0) ); // return travel time in hours }
//--------------------------------------------------------- double CSG_Shape_Line::Get_Length(void) { int iPart; double Length; for(iPart=0, Length=0.0; iPart<m_nParts; iPart++) { Length += Get_Length(iPart); } return( Length ); }
//--------------------------------------------------------- bool CKinWav_D8::Initialize(double Roughness) { m_Flow_Last .Create(*Get_System(), SG_DATATYPE_Float); m_Alpha .Create(*Get_System(), SG_DATATYPE_Float); m_Direction .Create(*Get_System(), SG_DATATYPE_Char); m_Direction .Set_NoData_Value(-1); m_pFlow->Assign(0.0); DataObject_Set_Colors(m_pFlow, 100, SG_COLORS_WHITE_BLUE); DataObject_Update(m_pFlow, 0.0, 100.0, SG_UI_DATAOBJECT_SHOW); //----------------------------------------------------- for(int y=0; y<Get_NY() && Set_Progress(y); y++) { for(int x=0; x<Get_NX(); x++) { if( !m_pDEM->is_NoData(x, y) ) { int i, ix, iy, iMax; double z, d, dMax; for(i=0, iMax=-1, dMax=0.0, z=m_pDEM->asDouble(x, y); i<8; i++) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( is_InGrid(ix, iy) && (d = (z - m_pDEM->asDouble(ix, iy)) / Get_Length(i)) > dMax ) { dMax = d; iMax = i; } } if( iMax < 0 ) { m_Direction .Set_NoData(x, y); } else { m_Direction .Set_Value(x, y, iMax); m_Alpha .Set_Value(x, y, pow(Roughness / sqrt(dMax), Beta_0)); if( m_Alpha.asDouble(x, y) > 10 ) m_Alpha.Set_Value(x, y, 10); } } } } return( true ); }
//--------------------------------------------------------- bool CSlopeLength::On_Execute(void) { int x, y; //----------------------------------------------------- m_pDEM = Parameters("DEM" )->asGrid(); m_pLength = Parameters("LENGTH")->asGrid(); if( !m_pDEM->Set_Index() ) { Error_Set(_TL("index creation failed")); return( false ); } //----------------------------------------------------- m_Slope.Create(*Get_System()); for(y=0; y<Get_NY() && Set_Progress(y); y++) { #pragma omp parallel for private(x) for(x=0; x<Get_NX(); x++) { double Slope, Aspect; if( m_pDEM->Get_Gradient(x, y, Slope, Aspect) ) { m_Slope .Set_Value(x, y, Slope); m_pLength->Set_Value(x, y, 0.0); } else { m_Slope .Set_NoData(x, y); m_pLength->Set_NoData(x, y); } } } //----------------------------------------------------- for(sLong n=0; n<Get_NCells() && Set_Progress_NCells(n); n++) { if( m_pDEM->Get_Sorted(n, x, y) ) { Get_Length(x, y); } } //----------------------------------------------------- m_Slope.Destroy(); return( true ); }
//--------------------------------------------------------- void CFlow_Parallel::Set_MFD(int x, int y) { int i, ix, iy; double z, d, dzSum, dz[8]; //----------------------------------------------------- for(i=0, dzSum=0.0, z=m_pDTM->asDouble(x, y); i<8; i++) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( m_pDTM->is_InGrid(ix, iy) ) { d = z - m_pDTM->asDouble(ix, iy); } else { ix = Get_xTo(i + 4, x); iy = Get_yTo(i + 4, y); if( m_pDTM->is_InGrid(ix, iy) ) { d = m_pDTM->asDouble(ix, iy) - z; } else { d = 0.0; } } if( d > 0.0 ) { dzSum += (dz[i] = pow(d / Get_Length(i), m_Converge)); } else { dz[i] = 0.0; } } //----------------------------------------------------- if( dzSum > 0.0 ) { for(i=0; i<8; i++) { if( dz[i] > 0.0 ) { Add_Fraction(x, y, i, dz[i] / dzSum); } } } }
//--------------------------------------------------------- bool CChannelNetwork_Distance::Set_MFD(int x, int y) { CSG_Vector Flow(8); if( !Get_MFD(x, y, Flow) ) { return( false ); } double Distance = 0.0, DistVert = 0.0, DistHorz = 0.0, Time = 0.0, SDR = 0.0; double z = m_pDEM->asDouble(x, y); for(int i=0; i<8; i++) { if( Flow[i] > 0.0 ) { int ix = Get_xTo(i, x), iy = Get_yTo(i, y); double dz = z - m_pDEM->asDouble(ix, iy); double dx = Get_Length(i); Distance += Flow[i] * (m_pDistance->asDouble(ix, iy) + sqrt(dz*dz + dx*dx)); DistVert += Flow[i] * (m_pDistVert->asDouble(ix, iy) + dz); DistHorz += Flow[i] * (m_pDistHorz->asDouble(ix, iy) + dx); if( m_pTime ) { double dt = Get_Travel_Time(x, y, i); Time += Flow[i] * (m_pTime->asDouble(ix, iy) + dt); } } } if( Distance > 0.0 ) { m_pDistance->Set_Value(x, y, Distance); m_pDistVert->Set_Value(x, y, DistVert); m_pDistHorz->Set_Value(x, y, DistHorz); if( m_pTime ) { m_pTime->Set_Value(x, y, Time); } } return( true ); }
//--------------------------------------------------------- void CConvergence::Do_Gradient(void) { int x, y, i, ix, iy, n; double z, Slope, Aspect, iSlope, iAspect, d, dSum; for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX(); x++) { if( pDTM->is_InGrid(x, y) ) { z = pDTM->asDouble(x, y); for(i=0, n=0, dSum=0.0, iAspect=-M_PI_180; i<8; i++, iAspect+=M_PI_045) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( pDTM->is_InGrid(ix, iy) && pDTM->Get_Gradient(ix, iy, Slope, Aspect) && Aspect >= 0.0 ) { iSlope = atan((pDTM->asDouble(ix, iy) - z) / Get_Length(i)); // Nach dem Seiten-Kosinus-Satz... d = acos(sin(Slope) * sin(iSlope) + cos(Slope) * cos(iSlope) * cos(iAspect - Aspect)); //--------------------------------- d = fmod(d, M_PI_360); if( d < -M_PI_180 ) { d += M_PI_360; } else if( d > M_PI_180 ) { d -= M_PI_360; } //--------------------------------- dSum += fabs(d); n++; } } pConvergence->Set_Value(x, y, n > 0 ? (dSum / (double)n - M_PI_090) * 100.0 / M_PI_090 : 0.0); } } } }
//--------------------------------------------------------- bool CSG_Vector::Set_Unity(void) { double Length; if( (Length = Get_Length()) > 0.0 ) { for(int i=0; i<Get_N(); i++) { Get_Data()[i] /= Length; } return( true ); } return( false ); }
//--------------------------------------------------------- void CFlow_Distance::Set_Length_D8(int x, int y) { int i, ix, iy; if( m_pDTM->is_InGrid(x, y) && (i = m_pDTM->Get_Gradient_NeighborDir(x, y, true)) >= 0 ) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( m_pDTM->is_InGrid(ix, iy) ) { m_pLength->Add_Value(ix, iy, m_pLength->asDouble(x, y) + Get_Length(i)); m_pWeight->Add_Value(ix, iy, 1.0); } } }
//--------------------------------------------------------- void CCellBalance::Set_MFD(int x, int y, double Weight) { const double MFD_Converge = 1.1; int i, ix, iy; double z, d, dzSum, dz[8]; z = m_pDEM->asDouble(x, y); dzSum = 0.0; for(i=0; i<8; i++) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( m_pDEM->is_InGrid(ix, iy) && (d = z - m_pDEM->asDouble(ix, iy)) > 0.0 ) { dz[i] = pow(d / Get_Length(i), MFD_Converge); dzSum += dz[i]; } else { dz[i] = 0.0; } } if( dzSum > 0.0 ) { d = Weight / dzSum; for(i=0; i<8; i++) { if( dz[i] > 0.0 ) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); m_pBalance->Add_Value(ix, iy, dz[i] * d); } } } }
//--------------------------------------------------------- void CFlow::Add_Fraction(int x, int y, int Direction, double Fraction) { int ix, iy; if( is_InGrid(x, y) ) { ix = Get_xTo(Direction, x); iy = Get_yTo(Direction, y); if( is_InGrid(ix, iy) ) { if( pCatch ) { pCatch ->Add_Value(ix, iy, Fraction * pCatch ->asDouble(x, y)); } if( pCatch_Height ) { pCatch_Height ->Add_Value(ix, iy, Fraction * pCatch_Height ->asDouble(x, y)); } if( pCatch_Slope ) { pCatch_Slope ->Add_Value(ix, iy, Fraction * pCatch_Slope ->asDouble(x, y)); } if( pFlowPath ) { pFlowPath ->Add_Value(ix, iy, Fraction * (pFlowPath ->asDouble(x, y) + Get_Length(Direction))); } if( pCatch_Aspect && pCatch_AspectY ) { pCatch_Aspect ->Add_Value(ix, iy, Fraction * pCatch_Aspect ->asDouble(x, y)); pCatch_AspectY ->Add_Value(ix, iy, Fraction * pCatch_AspectY ->asDouble(x, y)); } } } }
//--------------------------------------------------------- double CConvergence::Get_9x9(int x, int y, bool bGradient) { int i, ix, iy, n; double Slope, Aspect, iSlope, iAspect, d, dSum; for(i=0, n=0, dSum=0.0, iAspect=-M_PI_180; i<8; i++, iAspect+=M_PI_045) { ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( m_pDTM->is_InGrid(ix, iy) && m_pDTM->Get_Gradient(ix, iy, Slope, Aspect) && Aspect >= 0.0 ) { d = Aspect - iAspect; if( bGradient ) { iSlope = atan((m_pDTM->asDouble(ix, iy) - m_pDTM->asDouble(x, y)) / Get_Length(i)); d = acos(sin(Slope) * sin(iSlope) + cos(Slope) * cos(iSlope) * cos(d)); // Nach dem Seiten-Kosinus-Satz... } d = fmod(d, M_PI_360); if( d < -M_PI_180 ) { d += M_PI_360; } else if( d > M_PI_180 ) { d -= M_PI_360; } dSum += fabs(d); n++; } } return( n > 0 ? (dSum / (double)n - M_PI_090) * 100.0 / M_PI_090 : 0.0 ); }
//--------------------------------------------------------- bool CDiffuse_Pollution_Risk::Get_Flow_Proportions(int x, int y, double Proportion[8]) { if( m_pDEM->is_InGrid(x, y) ) { double Sum = 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_pDEM->asDouble(x, y) > m_pDEM->asDouble(ix, iy) ) { Sum += (Proportion[i] = ((m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy)) / Get_Length(i))); } else { Proportion[i] = 0.0; } } if( Sum > 0.0 ) { for(int i=0; i<8; i++) { if( Proportion[i] > 0.0 ) { Proportion[i] /= Sum; } } return( true ); } } return( false ); }
//--------------------------------------------------------- void CChannelNetwork::Set_Vector(int x, int y, int ID) { bool bContinue; int i, ix, iy, j, Order; double xMin, yMin, Length; CSG_Shape *pShape; //----------------------------------------------------- if( (Order = pChannels->asInt(x,y)) > 0 ) { bContinue = true; for(i=0, j=4; i<8 && bContinue; i++, j=(j+1)%8) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( pDTM->is_InGrid(ix,iy) && pChannels->asInt(ix,iy) == Order && pChannelRoute->asChar(ix,iy) && j == pChannelRoute->asChar(ix,iy) % 8 ) { bContinue = false; } } //------------------------------------------------- if( bContinue ) // Startpunkt gefunden... { xMin = pDTM->Get_XMin(), yMin = pDTM->Get_YMin(); ID = 1; pShape = pShapes->Add_Shape(); do { bContinue = false; Length = 0; Lock_Set(x,y); pShape->Add_Point(xMin + x * Get_Cellsize(), yMin + y * Get_Cellsize()); i = pChannelRoute->asChar(x,y); if( i > 0 ) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); Length += Get_Length(i); if( pDTM->is_InGrid(ix,iy) ) { if( !is_Locked(ix,iy) && ( pChannels->asInt(ix,iy) == Order || pChannels->asInt(ix,iy) < 0) ) { x = ix; y = iy; bContinue = true; } else { pShape->Add_Point(xMin + ix * Get_Cellsize(), yMin + iy * Get_Cellsize()); } } } } while( bContinue ); pShape->Set_Value(0, ID ); pShape->Set_Value(1, Order ); pShape->Set_Value(2, Length ); } } }
//--------------------------------------------------------- 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); } } } }