//--------------------------------------------------------- bool Trace_Polygon(CSG_Shape *pPolygon, CSG_Network &Network, int iEdge) { bool bAscending = true; CSG_Shape *pEdge = Network.Get_Edges().Get_Shape(iEdge); if( pEdge->asInt(3) == SHAPE_TYPE_Polygon ) { if( pEdge->asInt(4) ) { return( false ); } bAscending = true; } else if( (pEdge->asInt(4) & 0x1) == 0 ) { bAscending = true; } else if( (pEdge->asInt(4) & 0x2) == 0 ) { bAscending = false; } else { return( false ); } while( pEdge != NULL ) { pEdge->Set_Value(4, pEdge->asInt(4) | (bAscending ? 0x1 : 0x2)); for(int iPoint=0; iPoint<pEdge->Get_Point_Count(0); iPoint++) { pPolygon->Add_Point(pEdge->Get_Point(iPoint, 0, bAscending)); } int End_Node = pEdge->asInt(bAscending ? 2 : 1); iEdge = Network.Get_Node(End_Node).Get_Edge_Next(iEdge, false); pEdge = Network.Get_Edges().Get_Shape(iEdge); if( pEdge ) { bAscending = pEdge->asInt(3) == SHAPE_TYPE_Polygon || End_Node == pEdge->asInt(1); if( (pEdge->asInt(4) & (bAscending ? 0x1 : 0x2)) ) { pEdge = NULL; } } } return( pPolygon->is_Valid() ); }
//--------------------------------------------------------- bool CWatershed_Segmentation::Segment_Change(int ID, int new_ID) { bool bContinue; int ax, ay, bx, by; //----------------------------------------------------- CSG_Shape *pSeed = m_pSeeds->Get_Shape(ID); pSeed->Set_Value(SEED_JOIN, new_ID); ax = bx = pSeed->asInt(SEED_X); ay = by = pSeed->asInt(SEED_Y); do { bContinue = false; for(int x=ax; x<=bx; x++) { if( m_pSegments->asInt( x, ay) == ID ) { m_pSegments->Set_Value( x, ay, new_ID); bContinue = true; } if( m_pSegments->asInt( x, by) == ID ) { m_pSegments->Set_Value( x, by, new_ID); bContinue = true; } } for(int y=ay; y<=by; y++) { if( m_pSegments->asInt(ax, y) == ID ) { m_pSegments->Set_Value(ax, y, new_ID); bContinue = true; } if( m_pSegments->asInt(bx, y) == ID ) { m_pSegments->Set_Value(bx, y, new_ID); bContinue = true; } } if( ax > 0 ) ax--; if( ay > 0 ) ay--; if( bx < Get_NX() - 1 ) bx++; if( by < Get_NY() - 1 ) by++; } while( bContinue ); return( true ); }
//--------------------------------------------------------- bool COGR_DataSource::Write_Shapes(CSG_Shapes *pShapes) { OGRLayer *pLayer; //----------------------------------------------------- if( m_pDataSource && pShapes && pShapes->is_Valid() && (pLayer = m_pDataSource->CreateLayer(SG_STR_SGTOMB(pShapes->Get_Name()), NULL, g_OGR_Driver.Get_Type(pShapes->Get_Type()))) != NULL ) { bool bResult = true; int iField; //------------------------------------------------- for(iField=0; iField<pShapes->Get_Field_Count() && bResult; iField++) { OGRFieldDefn DefField(SG_STR_SGTOMB(pShapes->Get_Field_Name(iField)), g_OGR_Driver.Get_Type(pShapes->Get_Field_Type(iField))); // DefField.SetWidth(32); if( pLayer->CreateField(&DefField) != OGRERR_NONE ) { bResult = false; } } //------------------------------------------------- for(int iShape=0; iShape<pShapes->Get_Count() && bResult && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++) { CSG_Shape *pShape = pShapes->Get_Shape(iShape); OGRFeature *pFeature = OGRFeature::CreateFeature(pLayer->GetLayerDefn()); for(iField=0; iField<pShapes->Get_Field_Count(); iField++) { switch( pShapes->Get_Field_Type(iField) ) { default: case SG_DATATYPE_Char: case SG_DATATYPE_String: case SG_DATATYPE_Date: pFeature->SetField(iField, SG_STR_SGTOMB(pShape->asString(iField))); break; case SG_DATATYPE_Short: case SG_DATATYPE_Int: case SG_DATATYPE_Long: case SG_DATATYPE_Color: pFeature->SetField(iField, pShape->asInt(iField)); break; case SG_DATATYPE_Float: case SG_DATATYPE_Double: pFeature->SetField(iField, pShape->asDouble(iField)); break; } } if( !_Write_Geometry(pShape, pFeature) || pLayer->CreateFeature(pFeature) != OGRERR_NONE ) { bResult = false; } OGRFeature::DestroyFeature(pFeature); } //------------------------------------------------- return( bResult ); } return( false ); }
//--------------------------------------------------------- bool CPolygon_Line_Intersection::Get_Intersection(CSG_Shape_Polygon *pPolygon) { CSG_Network Network; for(int iLine=0; iLine<m_pLines->Get_Count(); iLine++) { CSG_Shape *pLine = m_pLines->Get_Shape(iLine); if( pLine->Intersects(pPolygon) ) { Network.Add_Shape(pLine); } } if( Network.Get_Edges().Get_Count() == 0 ) { return( false ); } Network.Add_Shape(pPolygon); Network.Update(); Network.Remove_End_Nodes(); //----------------------------------------------------- int iEdge, iPolygon; CSG_Shapes Intersection(SHAPE_TYPE_Polygon); Intersection.Add_Field(SG_T("ID"), SG_DATATYPE_Int); for(iEdge=0; iEdge<Network.Get_Edges().Get_Count(); iEdge++) { CSG_Shape *pEdge = Network.Get_Edges().Get_Shape(iEdge); if( pEdge->asInt(3) == SHAPE_TYPE_Polygon ) { Trace_Polygon(Intersection.Add_Shape(), Network, iEdge); } else if( pPolygon->Contains(pEdge->Get_Point(0)) && pPolygon->Contains(pEdge->Get_Point(pEdge->Get_Point_Count(0) - 1)) ) { Trace_Polygon(Intersection.Add_Shape(), Network, iEdge); Trace_Polygon(Intersection.Add_Shape(), Network, iEdge); } } //----------------------------------------------------- for(iPolygon=0; iPolygon<Intersection.Get_Count(); iPolygon++) // 1. outer rings { CSG_Shape *pIntersect = Intersection.Get_Shape(iPolygon); if( pIntersect->Get_Point_Count() > 0 && ((CSG_Shape_Polygon *)pIntersect)->is_Clockwise(0) == true ) { pIntersect->Set_Value(0, m_pIntersection->Get_Count()); ((CSG_Table_Record *)m_pIntersection->Add_Shape(pIntersect, SHAPE_COPY_GEOM))->Assign(pPolygon); } } for(iPolygon=0; iPolygon<Intersection.Get_Count(); iPolygon++) // 2. inner rings { CSG_Shape *pIntersect = Intersection.Get_Shape(iPolygon); if( pIntersect->Get_Point_Count() > 0 && ((CSG_Shape_Polygon *)pIntersect)->is_Clockwise(0) == false ) { for(int j=0; j<Intersection.Get_Count(); j++) { if( ((CSG_Shape_Polygon *)Intersection.Get_Shape(j))->Contains(pIntersect->Get_Point(0)) ) { CSG_Shape *pShape = m_pIntersection->Get_Shape(Intersection[j].asInt(0)); for(int iPoint=0, iPart=pShape->Get_Part_Count(); iPoint<pIntersect->Get_Point_Count(0); iPoint++) { pShape->Add_Point(pIntersect->Get_Point(iPoint), iPart); } break; } } } } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CSG_Network::Remove_End_Nodes(void) { int iEdge, n; //----------------------------------------------------- for(iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++) { CSG_Shape *pEdge = m_Edges.Get_Shape(iEdge); if( pEdge->asInt(3) == SHAPE_TYPE_Line ) { bool bRemove = false; for(int iNode=1; iNode<=2 && !bRemove; iNode++) { CSG_Network_Node &Node = Get_Node(pEdge->asInt(iNode)); CSG_Point Point = Node.Get_Point(); CSG_Shape *pNext; if( ( (pNext = m_Edges.Get_Shape(Node.Get_Edge_Next(pEdge->asInt(0), true))) != NULL && pNext->asInt(3) == SHAPE_TYPE_Polygon && !Point.is_Equal(pNext->Get_Point(0, 0, false)) ) || ( (pNext = m_Edges.Get_Shape(Node.Get_Edge_Next(pEdge->asInt(0), false))) != NULL && pNext->asInt(3) == SHAPE_TYPE_Polygon && !Point.is_Equal(pNext->Get_Point(0, 0, true)) ) ) { bRemove = true; } } if( bRemove ) { Get_Node(pEdge->asInt(1)).Del_Edge(pEdge->asInt(0)); Get_Node(pEdge->asInt(2)).Del_Edge(pEdge->asInt(0)); pEdge->Set_Value(4, 1); } } } //----------------------------------------------------- do { for(n=0, iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++) { CSG_Shape *pEdge = m_Edges.Get_Shape(iEdge); if( pEdge->asInt(3) == SHAPE_TYPE_Line && pEdge->asInt(4) == 0 ) { if( Get_Node(pEdge->asInt(1)).Get_Edge_Count() <= 1 || Get_Node(pEdge->asInt(2)).Get_Edge_Count() <= 1 ) { Get_Node(pEdge->asInt(1)).Del_Edge(pEdge->asInt(0)); Get_Node(pEdge->asInt(2)).Del_Edge(pEdge->asInt(0)); pEdge->Set_Value(4, 1); n++; } } } } while( n > 0 ); //----------------------------------------------------- for(iEdge=m_Edges.Get_Count()-1; iEdge>=0; iEdge--) { if( m_Edges[iEdge][4] ) { m_Edges.Del_Shape(iEdge); } } //----------------------------------------------------- return( Update() ); }
//--------------------------------------------------------- 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 ); }