//--------------------------------------------------------- bool CHillslope_Evolution_FTCS::On_Execute(void) { //----------------------------------------------------- CSG_Grid DEM(Get_System()); m_pDEM_Old = &DEM; m_pDEM = Parameters("MODEL")->asGrid(); m_pDEM->Assign(Parameters("DEM")->asGrid()); DataObject_Set_Colors(Parameters("DIFF")->asGrid(), 10, SG_COLORS_RED_GREY_BLUE, true); //----------------------------------------------------- double k, dTime, nTime; k = Parameters("KAPPA" )->asDouble(); nTime = Parameters("DURATION")->asDouble(); if( Parameters("TIMESTEP")->asInt() == 0 ) { dTime = Parameters("DTIME")->asDouble(); } else { dTime = 0.5 * Get_Cellarea() / (2.0 * k); if( Parameters("NEIGHBOURS")->asInt() == 1 ) { dTime /= sqrt(2.0); } } if( dTime > nTime ) { Message_Fmt("\n%s: %s [%f]", _TL("Warning"), _TL("Time step exceeds duration"), dTime); dTime = nTime; } Message_Fmt("\n%s: %f", _TL("Time Step"), dTime); Message_Fmt("\n%s: %d", _TL("Steps"), (int)(nTime / dTime)); //----------------------------------------------------- for(double iTime=dTime; iTime<=nTime && Set_Progress(iTime, nTime); iTime+=dTime) { Process_Set_Text("%s: %.2f [%.2f]", _TL("Simulation Time"), iTime, nTime); SG_UI_Progress_Lock(true); Set_Diffusion(dTime * k / Get_Cellarea()); Set_Difference(); SG_UI_Progress_Lock(false); } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CFlow_by_Slope::On_Execute(void) { m_Slope_Min = Parameters("SLOPE_MIN")->asDouble() * M_DEG_TO_RAD; m_Slope_Max = Parameters("SLOPE_MAX")->asDouble() * M_DEG_TO_RAD; if( m_Slope_Max <= 0.0 ) { Error_Set(_TL("slope threshold must not be zero!")); return( false ); } if( Parameters("B_FLOW")->asBool() ) { m_Flow_Min = Parameters("T_FLOW")->asRange()->Get_LoVal() * Get_Cellarea(); m_Flow_Max = Parameters("T_FLOW")->asRange()->Get_HiVal() * Get_Cellarea(); } else { m_Flow_Min = m_Flow_Max = 0.0; } //----------------------------------------------------- m_pDEM = Parameters("DEM" )->asGrid(); m_pFlow = Parameters("FLOW" )->asGrid(); m_pFlow->Assign(Get_Cellarea()); if( Parameters("WEIGHT")->asGrid() ) { m_pFlow->Multiply(*Parameters("WEIGHT")->asGrid()); } DataObject_Set_Colors(m_pFlow, 11, SG_COLORS_WHITE_BLUE, false); //----------------------------------------------------- for(sLong i=0; i<Get_NCells() && Set_Progress_NCells(i); i++) { int x, y; if( !m_pDEM->Get_Sorted(i, x, y, true) || m_pDEM->is_NoData(x, y) ) { m_pFlow->Set_NoData(x, y); } else { Set_Area(x, y); } } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CDiffuse_Pollution_Risk::Set_Flow(int x, int y, double Rain) { //----------------------------------------------------- if( m_pDEM->is_NoData(x, y) ) { return( false ); } double d[8]; m_FlowDir.Set_Value(x, y, m_pDEM->Get_Gradient_NeighborDir(x, y)); m_RainAcc.Set_Value(x, y, Rain = Rain * Get_Cellarea() + m_RainAcc.asDouble(x, y)); //----------------------------------------------------- if( m_bSingle ) { if( Get_System()->Get_Neighbor_Pos(m_FlowDir.asInt(x, y), x, y, x, y) && m_pDEM->is_InGrid(x, y) ) { m_RainAcc.Add_Value(x, y, Rain); } } else if( Get_Flow_Proportions(x, y, d) ) { for(int i=0; i<8; i++) { if( d[i] > 0.0 ) { m_RainAcc.Add_Value(Get_xTo(i, x), Get_yTo(i, y), Rain * d[i]); } } } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- double CGrid_Class_Statistics_For_Polygons::Get_Intersection(CSG_Shape_Polygon *pPolygon, TSG_Point p, bool bCenter) { //----------------------------------------------------- if( bCenter ) { return( pPolygon->Contains(p) ? Get_Cellarea() : 0.0 ); } //----------------------------------------------------- CSG_Shapes Cells(SHAPE_TYPE_Polygon); CSG_Shape *pCell = Cells.Add_Shape(); CSG_Shape *pArea = Cells.Add_Shape(); pCell->Add_Point(p.x - 0.5 * Get_Cellsize(), p.y - 0.5 * Get_Cellsize()); pCell->Add_Point(p.x - 0.5 * Get_Cellsize(), p.y + 0.5 * Get_Cellsize()); pCell->Add_Point(p.x + 0.5 * Get_Cellsize(), p.y + 0.5 * Get_Cellsize()); pCell->Add_Point(p.x + 0.5 * Get_Cellsize(), p.y - 0.5 * Get_Cellsize()); if( SG_Polygon_Intersection(pPolygon, pCell, pArea) ) { return( ((CSG_Shape_Polygon *)pArea)->Get_Area() ); } return( 0.0 ); }
//--------------------------------------------------------- bool CDiversity_Analysis::Get_Diversity(int x, int y) { if( m_pClasses->is_NoData(x, y) ) { return( false ); } //----------------------------------------------------- CCounter *Counters = new CCounter[m_Radius + 1]; int iRadius = 0; CSG_Class_Statistics Classes; for(int iCell=0; iCell<m_Search.Get_Count(); iCell++) { if( iRadius < m_Search.Get_Distance(iCell) ) { Counters[iRadius++].m_nClasses = Classes.Get_Count(); } int ix = m_Search.Get_X(iCell, x); int iy = m_Search.Get_Y(iCell, y); if( m_pClasses->is_InGrid(ix, iy) ) { double iz = m_pClasses->asDouble(ix, iy); Classes.Add_Value(iz); Counters[iRadius].m_nCells++; for(int jCell=0; jCell<8; jCell+=m_NB_Step) { int jx = Get_xTo(jCell, ix); int jy = Get_yTo(jCell, iy); if( m_pClasses->is_InGrid(jx, jy) ) { Counters[iRadius].m_nNeighbours++; if( m_pClasses->asDouble(jx, jy) == iz ) { Counters[iRadius].m_nConnections++; } } } } } //----------------------------------------------------- int nCells = 0, nNeighbours = 0, nConnections = 0; CSG_Simple_Statistics sClasses, sConnectivity; for(iRadius=0; iRadius<=m_Radius; iRadius++) { if( Counters[iRadius].m_nClasses > 0 ) { nCells += Counters[iRadius].m_nCells; nConnections += Counters[iRadius].m_nConnections; nNeighbours += Counters[iRadius].m_nNeighbours; double w = m_Search.Get_Weighting().Get_Weight(iRadius); if( nNeighbours > 0 ) { sConnectivity.Add_Value(nConnections / (double)nNeighbours, w); } sClasses.Add_Value(Counters[iRadius].m_nClasses, w); } } m_pCount ->Set_Value(x, y, Classes.Get_Count()); m_pDiversity ->Set_Value(x, y, sClasses.Get_Mean() / (m_Normalize == 0 ? 1.0 : m_Normalize == 1 ? nCells : nCells * Get_Cellarea())); m_pConnectivity->Set_Value(x, y, nNeighbours > 0 ? nConnections / (double)nNeighbours : 0.0); m_pConnectedAvg->Set_Value(x, y, sConnectivity.Get_Mean()); //----------------------------------------------------- delete[](Counters); return( true ); }
//--------------------------------------------------------- double CErosion_LS_Fields::Get_LS(int x, int y) { double LS, Slope, Aspect, Area, sin_Slope; //----------------------------------------------------- if( m_Fields.is_NoData(x, y) ) { return( -1.0 ); } if( !m_pDEM->Get_Gradient(x, y, Slope, Aspect) ) { return( -1.0 ); } if( m_Method_Slope == 1 ) // distance weighted average up-slope slope { Slope = m_pUp_Slope->asDouble(x, y); } if( Slope <= 0.0 ) Slope = 0.000001; if( Aspect < 0.0 ) Aspect = 0.0; sin_Slope = sin(Slope); Area = m_pUp_Area->asDouble(x, y); //----------------------------------------------------- switch( m_Method ) { //----------------------------------------------------- default: // Moore and Nieber { LS = (0.4 + 1) * pow(Area / 22.13, 0.4) * pow(sin_Slope / 0.0896, 1.3); } break; //----------------------------------------------------- case 1: // Desmet and Govers { double L, S, m, x; m = m_Erosivity * (sin_Slope / 0.0896) / (3.0 * pow(sin_Slope, 0.8) + 0.56); m = m / (1.0 + m); x = fabs(sin(Aspect)) + fabs(cos(Aspect)); // x: coefficient that adjusts for width of flow at the center of the cell. // It has a value of 1.0 when the flow is toward a side and sqrt(2.0) when // the flow is toward a corner (Kinnel 2005). L = (pow(Area + Get_Cellarea(), m + 1.0) - pow(Area, m + 1.0)) / (pow(Get_Cellsize(), m + 2.0) * pow(22.13, m) * pow(x, m)); //----------------------------------------------------- if( Slope < 0.08975817419 ) // < 9% (= atan(0.09)), ca. 5 Degree { S = 10.8 * sin_Slope + 0.03; } else if( m_Stability == 0 ) // >= 9%, stable { S = 16.8 * sin_Slope - 0.5; } else // >= 9%, thawing, unstable { S = pow(sin_Slope / 0.896, 0.6); } LS = L * S; } break; //----------------------------------------------------- case 2: // Wischmeier and Smith { if( Slope > 0.0505 ) // > ca. 3° { LS = sqrt(Area / 22.13) * (65.41 * sin_Slope * sin_Slope + 4.56 * sin_Slope + 0.065); } else // <= ca. 3° { LS = pow (Area / 22.13, 3.0 * pow(Slope, 0.6)) * (65.41 * sin_Slope * sin_Slope + 4.56 * sin_Slope + 0.065); } } break; } return( LS ); }
//--------------------------------------------------------- bool CErosion_LS_Fields::Get_Flow(void) { //----------------------------------------------------- if( !m_pDEM->Set_Index() ) // create index ... { return( false ); } Process_Set_Text(_TL("Flow Accumulation")); m_pUp_Area ->Assign(0.0); m_pUp_Length->Assign(0.0); m_pUp_Slope ->Assign(0.0); for(sLong n=0; n<Get_NCells() && Set_Progress_NCells(n); n++) { int x, y; double dzSum, dz[8], Slope, Aspect; if( m_pDEM->Get_Sorted(n, x, y) && !m_Fields.is_NoData(x, y) && m_pDEM->Get_Gradient(x, y, Slope, Aspect) ) { double Up_Area = m_pUp_Area ->asDouble(x, y) + Get_Cellarea(); double Up_Length = m_pUp_Length->asDouble(x, y) + log(Up_Area); double Up_Slope = m_pUp_Slope ->asDouble(x, y) + log(Up_Area) * Slope; //--------------------------------------------- if( (dzSum = Get_Flow(x, y, dz)) > 0.0 ) { for(int i=0; i<8; i++) { if( dz[i] > 0.0 ) { int ix = Get_xTo(i, x); int iy = Get_yTo(i, y); m_pUp_Area ->Add_Value(ix, iy, Up_Area * dz[i] / dzSum); m_pUp_Length->Add_Value(ix, iy, Up_Length * dz[i] / dzSum); m_pUp_Slope ->Add_Value(ix, iy, Up_Slope * dz[i] / dzSum); } } } //--------------------------------------------- switch( m_Method_Area ) { case 0: // specific catchment area (contour length simply as cell size) m_pUp_Area->Set_Value(x, y, Up_Area / (Get_Cellsize())); break; case 1: // specific catchment area (contour length dependent on aspect) m_pUp_Area->Set_Value(x, y, Up_Area / (Get_Cellsize() * (fabs(sin(Aspect)) + fabs(cos(Aspect))))); break; case 2: // catchment length (square root of catchment area) m_pUp_Area->Set_Value(x, y, sqrt(Up_Area)); break; case 3: // effective flow length m_pUp_Area->Set_Value(x, y, Up_Length); break; case 4: // total catchment area m_pUp_Area->Set_Value(x, y, Up_Area); break; } m_pUp_Length->Set_Value(x, y, Up_Length); m_pUp_Slope ->Set_Value(x, y, Up_Slope / (Up_Length > M_ALMOST_ZERO ? Up_Length : M_ALMOST_ZERO)); } } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- void CFlow_Parallel::Set_MDInf(int x, int y) { int i, ix, iy; double dz[8], s_facet[8], r_facet[8], valley[8], portion[8]; bool bInGrid[8]; //----------------------------------------------------- double z = m_pDTM->asDouble(x, y); for(i=0; i<8; i++) { s_facet[i] = r_facet[i] = -999.0; ix = Get_xTo(i, x); iy = Get_yTo(i, y); if( (bInGrid[i] = m_pDTM->is_InGrid(ix, iy)) ) { dz[i] = z - m_pDTM->asDouble(ix, iy); } else { dz[i] = 0.0; } } //----------------------------------------------------- for(i=0; i<8; i++) { double hs = -999.; double hr = -999.; if( bInGrid[i] ) { int j = i < 7 ? i + 1 : 0; if( bInGrid[j] ) { double nx = (dz[j] * Get_yTo(i) - dz[i] * Get_yTo(j)) * Get_Cellsize(); // vb-code: nx = (z1 * yd(j) - z2 * yd(i)) * gridsize /*ERROR?*/ double ny = (dz[i] * Get_xTo(j) - dz[j] * Get_xTo(i)) * Get_Cellsize(); // vb-code: ny = (z1 * xd(j) - z2 * xd(i)) * gridsize double nz = (Get_xTo(i) * Get_yTo(j) - Get_xTo(j) * Get_yTo(i)) * Get_Cellarea(); // vb-code: nz = (xd(j) * yd(i) - xd(i) * yd(j)) * gridsize ^ 2 double n_norm = sqrt(nx*nx + ny*ny +nz*nz); /* if( nx == 0.0 ) { hr = (ny >= 0.0)? 0.0 : M_PI; } else if( nx > 0.0 ) { hr = M_PI_090 - atan(ny / nx); } else { hr = M_PI_270 - atan(ny / nx); } */ if( nx == 0.0 ) { hr = (ny >= 0.0)? 0.0 : M_PI; } else if( nx < 0.0 ) { hr = M_PI_270 - atan(ny / nx); } else { hr = M_PI_090 - atan(ny / nx); } hs = -tan( acos( nz/n_norm ) ); // vb-code: hs = -Tan(arccos(nz / betrag_n)) // vb-code: If hr <= (i - 1) * PI / 4 Or hr >= i * PI / 4 Then //SHOULD IT BE LIKE THIS: (( hr <= i * M_PI_045 || hr >= j * M_PI_045 ) OR AS BELOW??? if( hr < i * M_PI_045 || hr > (i+1) * M_PI_045 ) { if( dz[i] > dz[j] ) { hr = i * M_PI_045; hs = dz[i] / Get_Length(i); } else { hr = j * M_PI_045; hs = dz[j] / Get_Length(j); } } } else if( dz[i] > 0.0 ) { hr = i * M_PI_045; hs = dz[i] / Get_Length(i); } s_facet[i] = hs; r_facet[i] = hr; } } //----------------------------------------------------- double dzSum = 0.0; for(i=0; i<8; i++) { valley[i] = 0.0; int j = i < 7 ? i + 1 : 0; if( s_facet[i] > 0.0 ) { if( r_facet[i] > i * M_PI_045 && r_facet[i] < (i+1) * M_PI_045 ) { valley[i] = s_facet[i]; } else if( r_facet[i] == r_facet[j] ) { valley[i] = s_facet[i]; } else if( s_facet[j] == -999.0 && r_facet[i] == (i+1) * M_PI_045 ) { valley[i] = s_facet[i]; } else { j = i > 0 ? i - 1 : 7; if( s_facet[j] == -999.0 && r_facet[i] == i * M_PI_045 ) { valley[i] = s_facet[i]; } } valley[i] = pow(valley[i], m_Converge); dzSum += valley[i]; } portion[i] = 0.0; } //----------------------------------------------------- if( dzSum ) { for(i=0; i<8; i++) { int j = i < 7 ? i + 1 : 0; if( i >= 7 && r_facet[i] == 0.0 ) { r_facet[i] = M_PI_360; } if( valley[i] ) { valley[i] /= dzSum; portion[i] += valley[i] * ((i+1) * M_PI_045 - r_facet[i]) / M_PI_045; // vb-code: portion(i) = portion(i) + valley(i) * (i * PI / 4 - r_facet(i)) / (PI / 4) portion[j] += valley[i] * (r_facet[i] - (i ) * M_PI_045) / M_PI_045; // vb-code: portion(j) = portion(j) + valley(i) * (r_facet(i) - (i - 1) * PI / 4) / (PI / 4) } } for(i=0; i<8; i++) { Add_Fraction(x, y, i, portion[i]); } } }