X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_LandCoverMap.cxx;h=c582b16fcc4143a2842f97b97fa89f57f3de270b;hb=a95289fabbb6fbf6f32c06207422c65aafd5bd65;hp=d3d690c4a3c110d480d7f0f2cbd7e7313d25edc5;hpb=743e3da9cea294eb30ea8b16e7f6992a39a8a50a;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_LandCoverMap.cxx b/src/HYDROData/HYDROData_LandCoverMap.cxx index d3d690c4..c582b16f 100644 --- a/src/HYDROData/HYDROData_LandCoverMap.cxx +++ b/src/HYDROData/HYDROData_LandCoverMap.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -42,22 +43,35 @@ #include #include #include +#include #include #include #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; @@ -357,7 +371,7 @@ bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName, { TopoDS_Shape aLandCoverMapShape = GetShape(); TopTools_ListOfShape aListOfFaces; - Iterator anIt( *this ); + Explorer anIt( *this ); QMap aTypesMap; for( ; anIt.More(); anIt.Next() ) { @@ -365,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; @@ -463,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 ); } @@ -571,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(); } @@ -584,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; } /** @@ -603,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; @@ -639,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 ); @@ -688,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 @@ -778,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 ); @@ -815,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 ); } @@ -824,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() ) @@ -840,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; } @@ -859,38 +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 ) - { - /*TopoDS_Shell aShell; - BRep_Builder aShellBuilder; - aShellBuilder.MakeShell( aShell ); - aShell.Closed( Standard_False ); - aShellBuilder.Add( aShell, aListOfFaces.First() );*/ - aResult = aListOfFaces.First(); //aShell; - } + 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,71 +1086,210 @@ QStringList HYDROData_LandCoverMap::DumpToPython( const QString& thePyScri QStringList aResList = dumpObjectCreation( theTreatedObjects ); QString aName = GetObjPyName(); - QString aShapeFileName = thePyScriptPath; - aShapeFileName.replace( ".py", ".shp" ); + QString aShpFileName = thePyScriptPath; + aShpFileName.replace( ".py", ".shp" ); QString aDbfFileName = thePyScriptPath; aDbfFileName.replace( ".py", ".dbf" ); - //TODO: export shape file + ExportSHP( aShpFileName, true, 0.1 ); QString anAttr = "CODE_06"; //TODO: some custom choice QStringList anAttrValues, aTypes; HYDROData_Document::Document( myLab )->CollectQGISValues( anAttr, anAttrValues, aTypes ); ExportDBF( aDbfFileName, anAttr, anAttrValues, aTypes ); - //TODO: insert command to import shape file + aResList << QString( "%1.ImportSHP( '%2' )" ). + 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 GetDouble( DataTag_Transparency, 0.5 ); +} - return anAttr->Get(); - +bool HYDROData_LandCoverMap::ImportSHP( const QString& theSHPFileName, + const QList& theIndices ) +{ + HYDROData_ShapeFile anImporter; + QStringList aPolyList; + TopTools_SequenceOfShape aFaces; + int aSHapeType = -1; + int Stat = anImporter.ImportPolygons(HYDROData_Document::Document(1), theSHPFileName, aPolyList, aFaces, aSHapeType); + // + if (Stat != 1) + return false; + // + HYDROData_MapOfFaceToStricklerType aMapFace2ST; + int maxInd = *std::max_element(theIndices.begin(), theIndices.end()); + if (maxInd > aPolyList.length()) + return false; + // + if (theIndices.empty()) + { + //import all shapes + for ( int i = 1; i <=aFaces.Length(); i++ ) + { + TopoDS_Shape aShape = aFaces(i); + if ( aShape.IsNull() ) + continue; + aMapFace2ST.Add( TopoDS::Face( aShape ), "" ); + } + } + else + { + //import given indices + foreach ( int Ind, theIndices ) + { + TopoDS_Shape aShape = aFaces(Ind + 1); + if ( aShape.IsNull() ) + continue; + aMapFace2ST.Add( TopoDS::Face( aShape ), "" ); + } + } + // + StoreLandCovers(aMapFace2ST); + return true; +} + +bool HYDROData_LandCoverMap::ExportSHP( const QString& theSHPFileName, bool bUseDiscr, double theDefl) const +{ + HYDROData_ShapeFile anExporter; + QStringList aList; + 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; + } + } }