X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_LandCoverMap.cxx;h=c582b16fcc4143a2842f97b97fa89f57f3de270b;hb=a95289fabbb6fbf6f32c06207422c65aafd5bd65;hp=1187916c6dbf3742c3dd1183261a87c6154a517d;hpb=2226b7cf9e77d4bfa79c75a5e7037bb3df846268;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_LandCoverMap.cxx b/src/HYDROData/HYDROData_LandCoverMap.cxx index 1187916c..c582b16f 100644 --- a/src/HYDROData/HYDROData_LandCoverMap.cxx +++ b/src/HYDROData/HYDROData_LandCoverMap.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -48,18 +49,29 @@ #include #include #include -#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include + +#define _DEVDEBUG_ +#include "HYDRO_trace.hxx" const char TELEMAC_FORMAT = 'f'; const int TELEMAC_PRECISION = 3; @@ -367,7 +379,7 @@ bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName, aTypesMap.insert( anIt.Face().TShape(), anIt.StricklerType() ); } - TopoDS_Shape aShape = MergeFaces( aListOfFaces, false ); + TopoDS_Shape aShape = MergeFaces( aListOfFaces, false, NULL ); NCollection_IndexedMap aVerticesMap; NCollection_IndexedDataMap< TopoDS_Edge, QList > anEdgesMap; @@ -465,10 +477,25 @@ bool HYDROData_LandCoverMap::Add( const Handle( HYDROData_Object )& theObject, c return false; TopoDS_Shape aShape = theObject->GetTopShape(); - if( aShape.ShapeType()!=TopAbs_FACE ) - return false; + TopoDS_Face aFace; - TopoDS_Face aFace = TopoDS::Face( aShape ); + if( aShape.ShapeType() ==TopAbs_FACE ) + { + aFace = TopoDS::Face(aShape); + } + else if ( aShape.ShapeType() ==TopAbs_COMPOUND ) + { + TopoDS_Iterator It(aShape); + for (; It.More(); It.Next()) + if (It.Value().ShapeType() == TopAbs_FACE) + { + aFace = TopoDS::Face(It.Value()); + break; + } + } + + if (aFace.IsNull()) + return false; return LocalPartition( aFace, theType ); } @@ -573,7 +600,9 @@ bool HYDROData_LandCoverMap::Split( const Handle( HYDROData_PolylineXY )& thePol */ bool HYDROData_LandCoverMap::Split( const TopoDS_Shape& theShape ) { - return LocalPartition( theShape, "" ); + int aNbCL = GetLCCount(); + bool aResult = LocalPartition( theShape, "" ); + return aResult && aNbCL != GetLCCount(); } @@ -586,16 +615,23 @@ bool HYDROData_LandCoverMap::Split( const TopoDS_Shape& theShape ) bool HYDROData_LandCoverMap::Merge( const TopTools_ListOfShape& theFaces, const QString& theType ) { // 1. to fuse the faces into the new face - TopoDS_Shape aMergedFace = MergeFaces( theFaces, true ); - if( !aMergedFace.IsNull() && aMergedFace.ShapeType()==TopAbs_FACE ) - { + TopoDS_Shape aMergedFace = MergeFaces( theFaces, true, NULL ); + bool aStat = true; + if( !aMergedFace.IsNull() ) + { // 2. to remove the merged faces from the current map Remove( theFaces ); - - // 3. to add the face into the map - return LocalPartition( TopoDS::Face( aMergedFace ), theType ); + TopExp_Explorer Exp(aMergedFace, TopAbs_FACE); + for( ; Exp.More(); Exp.Next() ) + { + const TopoDS_Face& aCF = TopoDS::Face(Exp.Current()); + // 3. to add the face into the map + aStat = aStat && LocalPartition( aCF, theType ); + } } - return false; + else + aStat = false; + return aStat; } /** @@ -605,9 +641,13 @@ bool HYDROData_LandCoverMap::Merge( const TopTools_ListOfShape& theFaces, const @param theTolerance the operation's tolerance @return result shape (face or shell) */ + TopoDS_Shape HYDROData_LandCoverMap::MergeFaces( const TopTools_ListOfShape& theFaces, - bool IsToUnify, double theTolerance ) + bool IsToUnify, + TopTools_IndexedDataMapOfShapeListOfShape* theShHistory, + double theTolerance) { + //DEBTRACE("MergeFaces"); int anError; TopTools_ListIteratorOfListOfShape anIt; BOPCol_ListOfShape aLC; @@ -641,6 +681,19 @@ TopoDS_Shape HYDROData_LandCoverMap::MergeFaces( const TopTools_ListOfShape& the const TopoDS_Shape& aMergedShape = anAlgo.Shape(); + // retrieve history of modifications + if (theShHistory) + { + theShHistory->Clear(); + anIt.Initialize(theFaces); + for( ; anIt.More(); anIt.Next() ) + { + const TopTools_ListOfShape aMLS = anAlgo.Modified( anIt.Value() ); + theShHistory->Add(anIt.Value(), aMLS); + } + } + // + BRep_Builder aBuilder; TopoDS_Shell aShell; aBuilder.MakeShell( aShell ); @@ -690,7 +743,6 @@ TopoDS_Shape HYDROData_LandCoverMap::MergeFaces( const TopTools_ListOfShape& the return aResult; } - /** Change Strickler type for the list of faces to the given one @param theFaces the faces to change type @@ -780,6 +832,7 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co aShapesList.Append( anIt.Face() ); aShapesList.Append( theNewShape ); + //DEBTRACE("theNewType " << theNewType); if( aShapesList.Size()==1 && theNewShape.ShapeType()==TopAbs_FACE ) { aNewFaces.Add( TopoDS::Face( theNewShape ), theNewType ); @@ -817,6 +870,7 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co for( ; aMIt.More(); aMIt.Next() ) { //std::cout << " " << aMIt.Value() << std::endl; + //DEBTRACE(aMIt.Value()); int aKey = (int)(uintptr_t)aMIt.Value().TShape().operator->(); aShapesFromNewFace.Add( aKey ); } @@ -826,10 +880,13 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co for( ; anIt.More(); anIt.Next() ) { QString aSType = anIt.StricklerType(); + //DEBTRACE(anIt.StricklerType() << " " << anIt.Face()); //std::cout << "from " << anIt.Face() << ": " << anIt.StricklerType() << std::endl; TopTools_ListOfShape aModified = aBuilder.Modified( anIt.Face() ); + // if( aModified.Extent() == 0 ) aModified.Append( anIt.Face() ); + //DEBTRACE(anIt.StricklerType() << " " << anIt.Face()); TopTools_ListIteratorOfListOfShape aMIt( aModified ); for( ; aMIt.More(); aMIt.Next() ) @@ -842,14 +899,21 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co if( isFace && !isAlsoFromNew ) aNewFaces.Add( TopoDS::Face( aShape ), aSType ); } + //DEBTRACE(anIt.StricklerType() << " " << anIt.Face()); } - // c. add the new shape if it is face with its type if( theNewShape.ShapeType()==TopAbs_FACE ) aNewFaces.Add( TopoDS::Face( theNewShape ), theNewType ); + //DEBTRACE(theNewShape << " " << theNewType); // convert map of shape to type to compound and list of types StoreLandCovers( aNewFaces ); + +// anIt.Init( *this ); +// for( ; anIt.More(); anIt.Next() ) +// { +// DEBTRACE(anIt.StricklerType() << " " << anIt.Face()); +// } return true; } @@ -861,31 +925,119 @@ void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfFaceToStrickl { TopTools_ListOfShape aListOfFaces; - int n = theMap.Size(); - - Handle( TDataStd_ExtStringArray ) aTypes = - TDataStd_ExtStringArray::Set( myLab.FindChild( DataTag_Types ), 0, n-1, Standard_True ); - - HYDROData_MapOfFaceToStricklerType::Iterator aNFIt( theMap ); - for( int i=0; aNFIt.More(); aNFIt.Next(), i++ ) + //DEBTRACE("theMap.Extent() " << theMap.Extent()); + for( int i = 1; i <= theMap.Extent(); i++ ) { - TopoDS_Face aFace = aNFIt.Key(); + TopoDS_Face aFace = theMap.FindKey(i); if( aFace.IsNull() ) continue; - QString aType = aNFIt.Value(); aListOfFaces.Append(aFace); - aTypes->SetValue( i, HYDROData_Tool::toExtString( aType ) ); } + TopTools_IndexedDataMapOfShapeListOfShape ShHistory; + ShHistory.Clear(); + TopoDS_Shape aResult; if( aListOfFaces.Extent() == 1 ) aResult = aListOfFaces.First(); else if( aListOfFaces.Extent() > 1 ) - aResult = MergeFaces( aListOfFaces, false ); + aResult = MergeFaces( aListOfFaces, false, &ShHistory ); //remove internal edges - aResult = RemoveInternal(aResult); + //if nothing changes => the result shape should be the same + //hence the map will be empty + + NCollection_IndexedDataMap ShF2FHistory; + RemoveInternal(aResult, &ShF2FHistory); + + //one face => mark as unchanged + if( aListOfFaces.Extent() == 1 ) + ShHistory.Add(aResult, TopTools_ListOfShape()); + + NCollection_IndexedDataMap aChF2ST; + QStringList aSTypes; + // + for( int i = 1; i <= theMap.Extent(); i++ ) + { + TopoDS_Face aFF = theMap.FindKey(i); + //DEBTRACE(" --- " << aFF); + if( aFF.IsNull() ) + continue; + //DEBTRACE(ShHistory.IsEmpty()); + //DEBTRACE(aFF.Checked()); + TopTools_ListOfShape aLS; + try + { + aLS = ShHistory.FindFromKey(aFF); //TODO: bug to fix. Observed on an incomplete split of a face + } + catch (...) + { + DEBTRACE("TODO: bug to fix. Observed on an incomplete split of a face"); + //continue; // No, keep aLS empty and propagate the type of the original face + } + if (aLS.IsEmpty()) + { + //DEBTRACE("--- aLS.IsEmpty()"); + QString aSType = theMap.FindFromKey(aFF); + //DEBTRACE(" --- " << aSType.toStdString()); + if (ShF2FHistory.Contains(aFF)) + { + //DEBTRACE("ShF2FHistory.FindFromKey(aFF) " << ShF2FHistory.FindFromKey(aFF)); + aChF2ST.Add(ShF2FHistory.FindFromKey(aFF), aSType); + } + else + { + //DEBTRACE("aFF " << aFF); + aChF2ST.Add(aFF, aSType); + } + } + else + { + //DEBTRACE("--- !aLS.IsEmpty()"); + TopTools_ListIteratorOfListOfShape anIt(aLS); + for (; anIt.More(); anIt.Next()) + { + QString aSType = theMap.FindFromKey(aFF); + //DEBTRACE(" --- " << aSType.toStdString()); + const TopoDS_Face& aMF = TopoDS::Face(anIt.Value()); + //if (ShF2FHistory.Contains(aFF)) + if (ShF2FHistory.Contains(aMF)) + { + //DEBTRACE("ShF2FHistory.FindFromKey(aMF) " << ShF2FHistory.FindFromKey(aFF)); + aChF2ST.Add(ShF2FHistory.FindFromKey(aMF), aSType); + } + else + { + //DEBTRACE("aMF " << aMF); + aChF2ST.Add(aMF, aSType); + } + } + } + } + // SetShape( aResult ); + // + //Explorer Exp(*this); + TopExp_Explorer FExp(aResult, TopAbs_FACE); + for( ; FExp.More(); FExp.Next() ) + { + TopoDS_Face aFace = TopoDS::Face(FExp.Current()); + QString aST = ""; + if (aChF2ST.Contains(aFace)) + aST = aChF2ST.FindFromKey(aFace); + //DEBTRACE("aFace " << aFace << " aST " << aST.toStdString()); + aSTypes << aST; + } + + Handle( TDataStd_ExtStringArray ) aTypes = TDataStd_ExtStringArray::Set( myLab.FindChild( DataTag_Types ), 0, aSTypes.size() - 1, Standard_True ); + int k = 0; + foreach (QString aST, aSTypes) + { + //DEBTRACE("aST " << aST.toStdString()); + aTypes->SetValue( k, HYDROData_Tool::toExtString( aST ) ); + k++; + } + } /** @@ -939,7 +1091,7 @@ QStringList HYDROData_LandCoverMap::DumpToPython( const QString& thePyScri QString aDbfFileName = thePyScriptPath; aDbfFileName.replace( ".py", ".dbf" ); - ExportSHP( aShpFileName, true, 1 ); + ExportSHP( aShpFileName, true, 0.1 ); QString anAttr = "CODE_06"; //TODO: some custom choice QStringList anAttrValues, aTypes; @@ -947,61 +1099,76 @@ QStringList HYDROData_LandCoverMap::DumpToPython( const QString& thePyScri ExportDBF( aDbfFileName, anAttr, anAttrValues, aTypes ); aResList << QString( "%1.ImportSHP( '%2' )" ). - arg( aName ).arg( aShpFileName ); + arg( aName ).arg( QFileInfo( aShpFileName ).fileName() ); Dump( "attr_values", anAttrValues, aResList ); Dump( "types", aTypes, aResList ); aResList << QString( "%1.ImportDBF( '%2', '%3', attr_values, types )" ). - arg( aName ).arg( aDbfFileName ).arg( anAttr ); + arg( aName ).arg( QFileInfo( aDbfFileName ).fileName() ).arg( anAttr ); return aResList; } -TopoDS_Shape HYDROData_LandCoverMap::RemoveInternal(const TopoDS_Shape& InSh) +void HYDROData_LandCoverMap::RemoveInternal(TopoDS_Shape& ShToRebuild, NCollection_IndexedDataMap* aF2FReplace) { + //DEBTRACE("RemoveInternal"); //Shape must be topologically correct - TopExp_Explorer anExp(InSh, TopAbs_EDGE); - TopTools_ListOfShape anEdgesToRemove; - - for(; anExp.More(); anExp.Next() ) + TopExp_Explorer anExpF(ShToRebuild, TopAbs_FACE); + // + for(; anExpF.More(); anExpF.Next() ) { - TopoDS_Edge CurEdge = TopoDS::Edge(anExp.Current()); - if (CurEdge.Orientation() == TopAbs_INTERNAL) - anEdgesToRemove.Append(CurEdge); + TopoDS_Face CurFace = TopoDS::Face(anExpF.Current()); + // + TopExp_Explorer anExp(CurFace, TopAbs_EDGE); + TopTools_ListOfShape anEdgesToRemove; + // + for(; anExp.More(); anExp.Next() ) + { + TopoDS_Edge CurEdge = TopoDS::Edge(anExp.Current()); + if (CurEdge.Orientation() == TopAbs_INTERNAL) + anEdgesToRemove.Append(CurEdge); + } + // + if (!anEdgesToRemove.IsEmpty()) + { + Handle_ShapeBuild_ReShape aReshape = new ShapeBuild_ReShape(); + TopoDS_Shape OutF = aReshape->Apply(CurFace); + TopTools_ListIteratorOfListOfShape aIt(anEdgesToRemove); + for (; aIt.More(); aIt.Next()) + aReshape->Remove(aIt.Value()); + OutF = aReshape->Apply(CurFace); + + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(OutF); + sfs->Perform(); + OutF = sfs->Shape(); + aF2FReplace->Add(CurFace, TopoDS::Face(OutF)); + } } - - Handle_ShapeBuild_ReShape aReshape = new ShapeBuild_ReShape(); - TopoDS_Shape OutSh = aReshape->Apply(InSh); - TopTools_ListIteratorOfListOfShape aIt(anEdgesToRemove); - for (; aIt.More(); aIt.Next()) - aReshape->Remove(aIt.Value()); - OutSh = aReshape->Apply(InSh); - - Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; - sfs->Init(OutSh); - sfs->Perform(); - return sfs->Shape(); + // + Handle_ShapeBuild_ReShape anExtReshape = new ShapeBuild_ReShape(); + for (int i = 1; i <= aF2FReplace->Extent(); i++) + { + TopoDS_Face aFK = aF2FReplace->FindKey(i); + TopoDS_Face aFV = aF2FReplace->FindFromIndex(i); + anExtReshape->Replace(aFK, aFV); + ShToRebuild = anExtReshape->Apply(ShToRebuild); + } +// for (int i = 1; i <= aF2FReplace->Extent(); i++) +// { +// DEBTRACE("aF2FReplace key,value " << aF2FReplace->FindKey(i) << " " << aF2FReplace->FindFromIndex(i)); +// } } void HYDROData_LandCoverMap::SetTransparency( double theTransparency ) { - Handle(TDataStd_Real) anAttr; - TDF_Label aLabel = myLab.FindChild( DataTag_Transparency ); - if( !aLabel.FindAttribute( TDataStd_Real::GetID(), anAttr ) ) - aLabel.AddAttribute( anAttr = new TDataStd_Real() ); - anAttr->Set( theTransparency ); + SetDouble( DataTag_Transparency, theTransparency ); } double HYDROData_LandCoverMap::GetTransparency() const { - Handle(TDataStd_Real) anAttr; - TDF_Label aLabel = myLab.FindChild( DataTag_Transparency ); - if( !aLabel.FindAttribute( TDataStd_Real::GetID(), anAttr ) ) - return 0.5; - - return anAttr->Get(); - + return GetDouble( DataTag_Transparency, 0.5 ); } bool HYDROData_LandCoverMap::ImportSHP( const QString& theSHPFileName, @@ -1011,7 +1178,7 @@ bool HYDROData_LandCoverMap::ImportSHP( const QString& theSHPFileName, QStringList aPolyList; TopTools_SequenceOfShape aFaces; int aSHapeType = -1; - int Stat = anImporter.ImportPolygons(theSHPFileName, aPolyList, aFaces, aSHapeType); + int Stat = anImporter.ImportPolygons(HYDROData_Document::Document(1), theSHPFileName, aPolyList, aFaces, aSHapeType); // if (Stat != 1) return false; @@ -1052,10 +1219,77 @@ bool HYDROData_LandCoverMap::ExportSHP( const QString& theSHPFileName, bool bUse { HYDROData_ShapeFile anExporter; QStringList aList; - anExporter.Export(theSHPFileName, this, aList, bUseDiscr, theDefl ); + anExporter.Export(HYDROData_Document::Document(1), theSHPFileName, this, aList, bUseDiscr, theDefl ); if (aList.empty()) return true; else return false; } +bool HYDROData_LandCoverMap::CheckLinear() +{ + TopoDS_Shape InpShape = GetShape(); + TopExp_Explorer anEdgeEx(InpShape, TopAbs_EDGE); + for (; anEdgeEx.More(); anEdgeEx.Next()) + { + TopoDS_Edge E = TopoDS::Edge(anEdgeEx.Current()); + double aFP, aLP; + Handle_Geom_Curve aCur = BRep_Tool::Curve(E, aFP, aLP); + Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCur); + if (aLine.IsNull()) + { + Handle(Geom_TrimmedCurve) aTC = Handle(Geom_TrimmedCurve)::DownCast(aCur); + if (!aTC.IsNull()) + { + Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aTC->BasisCurve()); + if (aLine.IsNull()) + return false; + } + else + return false; + } + } + return true; +} + +void HYDROData_LandCoverMap::UpdateLocalCS( double theDx, double theDy ) +{ + TopoDS_Shape aShape = GetShape(); + TopoDS_Shape aLocatedShape = HYDROData_ShapesTool::Translated( aShape, theDx, theDy, 0 ); + SetShape( aLocatedShape ); +} + +void HYDROData_LandCoverMap::ClassifyPoints( const std::vector& thePoints, std::vector >& theTypes ) const +{ + HYDROData_LCM_FaceClassifier FC(this); + FC.Classify(thePoints, theTypes, NULL); +} + +void HYDROData_LandCoverMap::ClassifyPoints( const std::vector& thePoints, + Handle(HYDROData_StricklerTable) theTable, + std::vector& theCoeffs, double DefValue, bool UseMax ) const +{ + std::vector > Types; + HYDROData_LCM_FaceClassifier FC(this); + FC.Classify(thePoints, Types, NULL); + theCoeffs.resize(thePoints.size()); + for (size_t i = 0; i < Types.size(); i++) + { + const std::set& SStr = Types[i]; + if (SStr.empty()) + theCoeffs[i] = DefValue; + else + { + std::set::const_iterator it; + std::vector C1(SStr.size()); + for (it = SStr.begin(); it != SStr.end(); ++it) + C1.push_back(theTable->Get( *it, DefValue )); + double Val; + if (UseMax) + Val = *(std::max_element( C1.begin(), C1.end() ) ); + else + Val = *(std::min_element( C1.begin(), C1.end() ) ); + theCoeffs[i] = Val; + } + } +}