//--------------------------------------------------------- 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))); } }
//--------------------------------------------------------- double CExercise_09::Get_Area(int x, int y) { int i, ix, iy; double area; //----------------------------------------------------- area = m_pArea->asDouble(x, y); if( area <= 0.0 ) // cell has not been processed yet... { m_pArea->Set_Value(x, y, 1.0); // Very important: mark this cell as processed to prevent endless loops... area = Get_Cellsize() * Get_Cellsize(); // initialize the cell's area with its own cell size... for(i=0; i<8; i++) { ix = Get_xFrom(i, x); iy = Get_yFrom(i, y); if( is_InGrid(ix, iy) && i == m_pDir->asInt(ix, iy) ) // drains ith neigbour into this cell ???... { area += Get_Area(ix, iy); // ...then add its area (recursive call of this function!)... } } m_pArea->Set_Value(x, y, area); } //----------------------------------------------------- return( area ); }
//--------------------------------------------------------- bool CWatersheds_ext::Get_Basin(CSG_Grid *pBasins, CSG_Shapes *pPolygons, int xMouth, int yMouth, int Main_ID) { int x, y, Basin_ID = 1 + pPolygons->Get_Count(); CSG_Shape *pPolygon; CSG_Grid_Stack Stack; CSG_Simple_Statistics s_Height, s_Distance; //----------------------------------------------------- Stack.Push(x = xMouth, y = yMouth); pBasins ->Set_Value(x, y, Basin_ID); m_Distance .Set_Value(x, y, 0.0); s_Height += m_pDEM->asDouble(x, y); s_Distance += 0.0; //----------------------------------------------------- while( Stack.Get_Size() > 0 && Process_Get_Okay() ) { Stack.Pop(x, y); double d = m_Distance.asDouble(x, y); //------------------------------------------------- for(int i=0; i<8; i++) { int ix = Get_xFrom(i, x); int iy = Get_yFrom(i, y); if( is_InGrid(ix, iy) && pBasins->is_NoData(ix, iy) && i == m_Direction.asInt(ix, iy) ) { Stack.Push(ix, iy); pBasins ->Set_Value(ix, iy, Basin_ID); m_Distance .Set_Value(ix, iy, d + Get_Length(i)); s_Height += m_pDEM->asDouble(ix, iy); s_Distance += d + Get_Length(i); } } } //----------------------------------------------------- if( s_Height.Get_Count() > 1 && (pPolygon = Get_Basin(pBasins, pPolygons)) != NULL ) { double d, Area, Perimeter, Side_A, Side_B; CSG_String Gravelius; // Area = s_Height.Get_Count() * Get_System()->Get_Cellarea(); Area = ((CSG_Shape_Polygon*)pPolygon)->Get_Area(); Perimeter = ((CSG_Shape_Polygon*)pPolygon)->Get_Perimeter(); d = 0.28 * Perimeter / sqrt(Area); Gravelius = d > 1.75 ? _TL("rectangular") : d > 1.5 ? _TL("ovalooblonga-rectangularoblonga") : d > 1.25 ? _TL("ovaloredonda-ovalooblonga") : _TL("redonda-ovaloredonda"); d = pow(Perimeter, 2.0) - 8.0 * Area; Side_A = d > 0.0 ? (Perimeter + sqrt(d)) / 4.0 : -1.0; Side_B = d > 0.0 ? (Perimeter - 2.0 * Side_A) / 2.0 : -1.0; pPolygon->Set_Value(FIELD_ID , Basin_ID); pPolygon->Set_Value(FIELD_ID_MAIN , Main_ID); pPolygon->Set_Value(FIELD_MOUTH_X , Get_System()->Get_xGrid_to_World(xMouth)); pPolygon->Set_Value(FIELD_MOUTH_Y , Get_System()->Get_yGrid_to_World(yMouth)); pPolygon->Set_Value(FIELD_PERIMETER , Perimeter); pPolygon->Set_Value(FIELD_AREA , Area); pPolygon->Set_Value(FIELD_CENTROID_X , ((CSG_Shape_Polygon*)pPolygon)->Get_Centroid().x); pPolygon->Set_Value(FIELD_CENTROID_Y , ((CSG_Shape_Polygon*)pPolygon)->Get_Centroid().y); pPolygon->Set_Value(FIELD_Z_MEAN , s_Height .Get_Mean()); pPolygon->Set_Value(FIELD_Z_RANGE , s_Height .Get_Range()); pPolygon->Set_Value(FIELD_DIST_MEAN , s_Distance.Get_Mean()); pPolygon->Set_Value(FIELD_DIST_MAX , s_Distance.Get_Maximum()); pPolygon->Set_Value(FIELD_CONCTIME , s_Height.Get_Range() <= 0.0 ? -1.0 : pow(0.87 * pow(s_Distance.Get_Maximum() / 1000.0, 3.0) / s_Height.Get_Range(), 0.385) ); pPolygon->Set_Value(FIELD_BASIN_TYPE , Gravelius); pPolygon->Set_Value(FIELD_EQVRECT_A , Side_A); pPolygon->Set_Value(FIELD_EQVRECT_B , Side_B); pPolygon->Set_Value(FIELD_OROG_IDX , SG_Get_Square(s_Height.Get_Mean()) / (0.0001 * Area)); // Orographic index, defined as the mean catchment altitude times the ratio of the mean catchment altitude to the orthogonal projection of drainage area (Alcázar, Palau (2010): Establishing environmental flow regimes in a Mediterranean watershed based on a regional classification. Journal of Hydrology, V. 388 pPolygon->Set_Value(FIELD_MASS_IDX , Perimeter / (0.0001 * Area)); // Perimeter / (0.0001 * Area) ??!! pPolygon->Set_Value(FIELD_BASINS_UP , 0.0); // Upslope Basins pPolygon->Set_Value(FIELD_BASINS_DOWN , 0.0); // Downslope Basins return( true ); } return( false ); }
//--------------------------------------------------------- bool CTIN_From_Grid_Specific_Points::Get_OppositeNB(CSG_Grid *pResult, CSG_Grid *pGrid, int Threshold) { int i, x, y, ix, iy, jx, jy; double z, iz, jz; CSG_Grid *clo, *chi; clo = SG_Create_Grid(pGrid, SG_DATATYPE_Char); chi = SG_Create_Grid(pGrid, SG_DATATYPE_Char); // Pass 1: Auszaehlen... for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX()-1; x++) { z = pGrid->asDouble(x,y); for(i=0; i<4; i++) { ix = Get_xTo(i,x); iy = Get_yTo(i,y); if( is_InGrid(ix,iy) ) { jx = Get_xFrom(i,x); jy = Get_yFrom(i,y); if( is_InGrid(jx,jy) ) { iz = pGrid->asDouble(ix,iy); jz = pGrid->asDouble(jx,jy); if( iz>z && jz>z ) chi->Add_Value(x,y,1); else if( iz<z && jz<z ) clo->Add_Value(x,y,1); } } } } } // Pass 2: Setzen... for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX()-1; x++) { if( chi->asChar(x,y) ) { if( clo->asChar(x,y) ) pResult->Set_Value(x,y, 5); // Sattel else pResult->Set_Value(x,y, chi->asChar(x,y) ); // Tiefenlinie } else if( clo->asChar(x,y) ) pResult->Set_Value(x,y, - clo->asChar(x,y) ); // Wasserscheide else pResult->Set_Value(x,y, 0); // Nichts... pResult->Set_Value(x, y, abs(pResult->asInt(x, y)) >= Threshold ? 1 : 0); } } delete(clo); delete(chi); return( true ); }
//--------------------------------------------------------- bool CWatersheds_ext::On_Execute(void) { int x, y; CSG_Grid *pBasins, *pSubBasins, Inflows; CSG_Shapes *pHeads, *pMouths, *pVBasins, *pVSubBasins; m_pDEM = Parameters("DEM") ->asGrid(); m_pChannels = Parameters("CHANNELS") ->asGrid(); pBasins = Parameters("BASINS") ->asGrid(); pSubBasins = Parameters("SUBBASINS") ->asGrid(); pVBasins = Parameters("V_BASINS") ->asShapes(); pVSubBasins = Parameters("V_SUBBASINS") ->asShapes(); pHeads = Parameters("HEADS") ->asShapes(); pMouths = Parameters("MOUTHS") ->asShapes(); //----------------------------------------------------- Inflows .Create(*Get_System(), SG_DATATYPE_Char); m_Direction .Create(*Get_System(), SG_DATATYPE_Char); m_Direction .Set_NoData_Value(-1); m_Distance .Create(*Get_System(), SG_DATATYPE_Float); m_Distance .Set_NoData_Value(-1); m_Distance .Assign_NoData(); pBasins ->Assign(0.0); pBasins ->Set_NoData_Value(0.0); pSubBasins ->Assign(0.0); pSubBasins ->Set_NoData_Value(0.0); pHeads ->Create(SHAPE_TYPE_Point , _TL("Heads")); pHeads ->Add_Field("ID" , SG_DATATYPE_Int); pHeads ->Add_Field("MAIN_ID" , SG_DATATYPE_Int); pHeads ->Add_Field("ELEVATION" , SG_DATATYPE_Double); pHeads ->Add_Field("DISTANCE" , SG_DATATYPE_Double); pMouths ->Create(SHAPE_TYPE_Point , _TL("Mouths")); pMouths ->Add_Field("ID" , SG_DATATYPE_Int); pMouths ->Add_Field("MAIN_ID" , SG_DATATYPE_Int); pMouths ->Add_Field("ELEVATION" , SG_DATATYPE_Double); pVBasins ->Create(SHAPE_TYPE_Polygon , _TL("Basins")); BASIN_ADD_FIELDS(pVBasins); pVSubBasins ->Create(SHAPE_TYPE_Polygon , _TL("Subbasins")); BASIN_ADD_FIELDS(pVSubBasins); //----------------------------------------------------- Process_Set_Text(_TL("flow directions...")); for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX(); x++) { int Direction = -1; if( m_pDEM->is_InGrid(x, y) ) { double dMax = 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_pChannels->is_NoData(ix, iy) ) { double dz = (m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy)) / Get_Length(i); if( dMax < dz ) { dMax = dz; Direction = i; } } } if( !m_pChannels->is_NoData(x, y) ) { if( Direction >= 0 ) { int ix = Get_xTo(Direction, x); int iy = Get_yTo(Direction, y); if( m_pDEM->is_InGrid(ix, iy) ) { Inflows.Add_Value(ix, iy, 1); } } } else if( Direction < 0 ) { Direction = m_pDEM->Get_Gradient_NeighborDir(x, y); } } m_Direction.Set_Value(x, y, Direction); } } //----------------------------------------------------- Process_Set_Text(_TL("main basins...")); for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX(); x++) { if( m_pChannels->is_InGrid(x, y) && is_Outlet(x, y) ) { Get_Basin(pBasins, pVBasins, x, y, -1); CSG_Shape *pMouth = pMouths->Add_Shape(); pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y)); pMouth->Set_Value(0, pVBasins->Get_Count()); // ID pMouth->Set_Value(1, pVBasins->Get_Count()); // MAIN_ID pMouth->Set_Value(2, m_pDEM->asDouble(x, y)); // ELEVATION } } } if( Parameters("DISTANCE")->asBool() ) { m_Distance.Set_Name(_TL("Flow Distance")); DataObject_Add(SG_Create_Grid(m_Distance)); } //----------------------------------------------------- Process_Set_Text(_TL("heads and mouths...")); for(y=0; y<Get_NY() && Set_Progress(y); y++) { for(x=0; x<Get_NX(); x++) { if( m_pChannels->is_InGrid(x, y) ) { //----------------------------------------- if( Inflows.asInt(x, y) > 1 ) // mouth, linking channels of subcatchments { CSG_Shape *pMouth = pMouths->Add_Shape(); pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y)); pMouth->Set_Value(0, pMouths->Get_Count()); // ID pMouth->Set_Value(1, pBasins->asDouble(x, y)); // MAIN_ID pMouth->Set_Value(2, m_pDEM->asDouble(x, y)); // ELEVATION } //----------------------------------------- else if( Inflows.asInt(x, y) == 0 ) // head { CSG_Shape *pHead = pHeads->Add_Shape(); pHead->Add_Point(Get_System()->Get_Grid_to_World(x, y)); pHead->Set_Value(0, pHeads->Get_Count() + 1); pHead->Set_Value(1, m_Distance.asDouble(x, y)); } } } } //----------------------------------------------------- Process_Set_Text(_TL("subbasins...")); pMouths->Set_Index(1, TABLE_INDEX_Ascending, 2, TABLE_INDEX_Descending); for(int iMouth=0; iMouth<pMouths->Get_Count() && Set_Progress(iMouth, pMouths->Get_Count()); iMouth++) { CSG_Shape *pMouth = pMouths->Get_Shape_byIndex(iMouth); if( Get_System()->Get_World_to_Grid(x, y, pMouth->Get_Point(0)) ) { if( pMouth->asInt(0) == pMouth->asInt(1) ) { Get_Basin(pSubBasins, pVSubBasins, x, y, pMouth->asInt(1)); } else { for(int i=0; i<8; i++) { int ix = Get_xFrom(i, x); int iy = Get_yFrom(i, y); if( m_pChannels->is_InGrid(ix, iy) && m_Direction.asInt(ix, iy) == i ) { Get_Basin(pSubBasins, pVSubBasins, ix, iy, pMouth->asInt(1)); } } } } } if( Parameters("DISTANCE")->asBool() ) { m_Distance.Set_Name(_TL("Subbasin Flow Distance")); DataObject_Add(SG_Create_Grid(m_Distance)); } //----------------------------------------------------- m_Distance .Destroy(); m_Direction .Destroy(); return( true ); }