Salome HOME
refs #697 (p.1)
[modules/hydro.git] / src / HYDROData / HYDROData_LandCoverMap.cxx
index acecb291048c49fb751a704701cbe9a6cba5b0d0..367f60488338e8b37d2fa308fc4373b5a70119d2 100644 (file)
@@ -21,6 +21,8 @@
 #include <HYDROData_PolylineXY.h>
 #include <HYDROData_Tool.h>
 #include <HYDROData_ShapeFile.h>
+#include <HYDROData_Document.h>
+#include <HYDROData_StricklerTable.h>
 
 #include <BOPAlgo_BOP.hxx>
 #include <BOPAlgo_Builder.hxx>
@@ -40,6 +42,7 @@
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BRepTools.hxx>
 #include <TopExp_Explorer.hxx>
 #include <ShapeFix_Shape.hxx>
 #include <BRepCheck_Shell.hxx>
 #include <BRepCheck_ListOfStatus.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <Handle_Geom_Curve.hxx>
+#include <Handle_Geom_Line.hxx>
+#include <Handle_Geom_TrimmedCurve.hxx>
+#include <Geom_TrimmedCurve.hxx>
 
 
 #include <QFile>
 #include <QString>
 #include <QTextStream>
+#include <QFileInfo>
 
 const char TELEMAC_FORMAT = 'f';
 const int TELEMAC_PRECISION = 3;
@@ -254,10 +263,14 @@ HYDROData_LandCoverMap::DBFStatus HYDROData_LandCoverMap::ImportDBF( const QStri
   for( ; anIt.More(); anIt.Next() )
   {
     int CurIndex = anIt.Index();
-    HYDROData_ShapeFile::DBF_AttrValue AValue = theAttrV[theIndices[CurIndex]];
-    int StricklerTypesInd = theDBFValues.indexOf(QString(AValue.myStrVal));
+    int anIndex = CurIndex;
+    if( !theIndices.isEmpty() )
+      anIndex = theIndices[CurIndex];
+
+    HYDROData_ShapeFile::DBF_AttrValue AValue = theAttrV[anIndex];
+    int StricklerTypesInd = theDBFValues.indexOf( QString( AValue.myStrVal ) );
     if ( StricklerTypesInd != -1)
-      anIt.SetStricklerType(theStricklerTypes[StricklerTypesInd]);
+      anIt.SetStricklerType( theStricklerTypes[StricklerTypesInd] );
     else
       allOK = false;
   }
@@ -345,19 +358,26 @@ bool EdgeDiscretization( const TopoDS_Edge& theEdge,
   @param theFileName the name of file
   @return if the export is successful
 */
-bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName, Standard_Real theDeflection ) const
+bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName,
+                                            double theDeflection,
+                                            const Handle(HYDROData_StricklerTable)& theTable ) const
 {
   TopoDS_Shape aLandCoverMapShape = GetShape();
   TopTools_ListOfShape aListOfFaces;
-  TopExp_Explorer anExp( aLandCoverMapShape, TopAbs_FACE );
-  for( ; anExp.More(); anExp.Next() )
-    aListOfFaces.Append( anExp.Current() );
+  Explorer anIt( *this );
+  QMap<Handle(TopoDS_TShape), QString> aTypesMap;
+  for( ; anIt.More(); anIt.Next() )
+  {
+    aListOfFaces.Append( anIt.Face() );
+    aTypesMap.insert( anIt.Face().TShape(), anIt.StricklerType() );
+  }
 
   TopoDS_Shape aShape = MergeFaces( aListOfFaces, false );
 
   NCollection_IndexedMap<gp_Pnt> aVerticesMap;
   NCollection_IndexedDataMap< TopoDS_Edge, QList<int> > anEdgesMap;
-  NCollection_IndexedDataMap< TopoDS_Face, QList<int> > aFacesMap;
+  typedef QPair< QString, QList<int> > FaceData;
+  NCollection_IndexedDataMap< TopoDS_Face, FaceData > aFacesMap;
 
   // add into the map all edges existing in the shell
   TopExp_Explorer anExp1( aShape, TopAbs_EDGE );
@@ -382,7 +402,11 @@ bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName, Standard
       int anEdgeId = anEdgesMap.FindIndex( anEdge );
       anEdgesIdsList.append( anEdgeId );
     }
-    aFacesMap.Add( aFace, anEdgesIdsList );
+
+    FaceData aData;
+    aData.first = aTypesMap[aFace.TShape()];
+    aData.second = anEdgesIdsList;
+    aFacesMap.Add( aFace, aData );
   }
 
   QFile aFile( theFileName );
@@ -416,10 +440,14 @@ bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName, Standard
   aStream << "\n";
 
   aStream << "# faces\n";
-  NCollection_IndexedDataMap< TopoDS_Face, QList<int> >::Iterator anIt3( aFacesMap );
+  NCollection_IndexedDataMap< TopoDS_Face, FaceData >::Iterator anIt3( aFacesMap );
   for( ; anIt3.More(); anIt3.Next() )
   {
-    QList<int> anEdgesIds = anIt3.Value();
+    QString aType = anIt3.Value().first;
+    double aCoeff = theTable->Get( aType, 0.0 );
+    QList<int> anEdgesIds = anIt3.Value().second;
+    //aStream << "\"" << aType << "\" ";
+    aStream << QString::number( aCoeff, TELEMAC_FORMAT, TELEMAC_PRECISION ) << " ";
     foreach( int anId, anEdgesIds )
       aStream << anId << " ";
     aStream << "\n";
@@ -442,10 +470,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;
+
+  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;
+      }
+  }
 
-  TopoDS_Face aFace = TopoDS::Face( aShape );
+  if (aFace.IsNull())
+    return false;
   return LocalPartition( aFace, theType );
 }
 
@@ -550,7 +593,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();
 }
 
 
@@ -563,16 +608,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 );  
+  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;
 }
 
 /**
@@ -805,6 +857,7 @@ bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, co
     QString aSType = anIt.StricklerType();
     //std::cout << "from " << anIt.Face() << ": " << anIt.StricklerType() << std::endl;
     TopTools_ListOfShape aModified = aBuilder.Modified( anIt.Face() );
+    //
     if( aModified.Extent() == 0 )
       aModified.Append( anIt.Face() );
 
@@ -856,14 +909,7 @@ void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfFaceToStrickl
 
   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 );
 
@@ -872,6 +918,14 @@ void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfFaceToStrickl
   SetShape( aResult );
 }
 
+/**
+   Checks that object has 2D presentation. Reimlemented to retun true.
+*/
+bool HYDROData_LandCoverMap::IsHas2dPrs() const
+{
+  return true;
+}
+
 /**
   Find the land cover for the given point
   @param thePoint the point laying in some land cover
@@ -893,26 +947,42 @@ TopoDS_Face HYDROData_LandCoverMap::FindByPoint( const gp_Pnt2d& thePoint, QStri
   return TopoDS_Face();
 }
 
+void Dump( const QString& theName, const QStringList& theList, QStringList& theLines )
+{
+  theLines.append( QString( "%1 = QStringList()" ).arg( theName ) );
+  foreach( QString anItem, theList )
+    theLines.append( QString( "%1.append( u\"%2\" )" ).arg( theName ).arg( anItem ) );
+}
+
 /**
   Dump to Python
   @param theTreatedObjects the map of treated objects
 */
-QStringList HYDROData_LandCoverMap::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
+QStringList HYDROData_LandCoverMap::DumpToPython( const QString&       thePyScriptPath,
+                                                  MapOfTreatedObjects& theTreatedObjects ) const
 {
   QStringList aResList = dumpObjectCreation( theTreatedObjects );
   QString aName = GetObjPyName();
 
-  //Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
-  //setPythonReferenceObject( theTreatedObjects, aResList, aHydAxis, "SetHydraulicAxis" );
+  QString aShpFileName = thePyScriptPath;
+  aShpFileName.replace( ".py", ".shp" );
+  QString aDbfFileName = thePyScriptPath;
+  aDbfFileName.replace( ".py", ".dbf" );
+
+  ExportSHP( aShpFileName, true, 0.1 );
 
-  //HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
-  //for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; ++i )
-  //{
-    //const Handle(HYDROData_Entity) aProfile = aSeqOfProfiles.Value( i );
-    //setPythonReferenceObject( theTreatedObjects, aResList, aProfile, "AddProfile" );
-  //}
+  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
+  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( QFileInfo( aDbfFileName ).fileName() ).arg( anAttr );
 
   return aResList;
 }
@@ -963,3 +1033,84 @@ double HYDROData_LandCoverMap::GetTransparency() const
   return anAttr->Get();
   
 }
+
+bool HYDROData_LandCoverMap::ImportSHP( const QString& theSHPFileName,
+                                        const QList<int>& theIndices )
+{
+  HYDROData_ShapeFile anImporter;
+  QStringList aPolyList; 
+  TopTools_SequenceOfShape aFaces;
+  int aSHapeType = -1;
+  int Stat = anImporter.ImportPolygons(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(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;
+}