Salome HOME
initial ver.
[modules/hydro.git] / src / HYDROData / HYDROData_LandCoverMap.cxx
index 7d8ee63fad28bff98380337eaddd73f261bd7ed0..c801780fd80cbb46cdd3d5aa249cecebac203bf1 100644 (file)
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include "HYDROData_LandCoverMap.h"
-#include <TDataStd_ExtStringArray.hxx>
+#include <HYDROData_LandCoverMap.h>
+#include <HYDROData_Tool.h>
+
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPCol_ListOfShape.hxx>
+#include <BRep_Builder.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shell.hxx>
+
 #include <QString>
 
-QString HYDROData_LandCoverMap::GetStricklerType( int theIndex ) const
+IMPLEMENT_STANDARD_HANDLE(HYDROData_LandCoverMap, HYDROData_Entity)
+IMPLEMENT_STANDARD_RTTIEXT(HYDROData_LandCoverMap, HYDROData_Entity)
+
+class HYDROData_MapOfShapeToStricklerType : public NCollection_IndexedDataMap<TopoDS_Shape, QString>
+{
+};
+
+/**
+  Constructor
+  @param theMap the land cover map to iterate through
+*/
+HYDROData_LandCoverMap::Iterator::Iterator( const HYDROData_LandCoverMap& theMap )
+{
+  Init( theMap );
+}
+
+/**
+  Initialize the iterator
+  @param theMap the land cover map to iterate through
+*/
+void HYDROData_LandCoverMap::Iterator::Init( const HYDROData_LandCoverMap& theMap )
+{
+  myIterator = new TopoDS_Iterator( theMap.GetShape() );
+  myIndex = 0;
+  theMap.myLab.FindChild( DataTag_Types ).FindAttribute( TDataStd_ExtStringArray::GetID(), myArray );
+}
+
+/**
+  Destructor
+*/
+HYDROData_LandCoverMap::Iterator::~Iterator()
+{
+  delete myIterator;
+}
+
+/**
+  Return if the iterator has more elements
+  @return if the iterator has more elements
+*/
+bool HYDROData_LandCoverMap::Iterator::More() const
+{
+  return !myArray.IsNull() && myIterator->More();
+}
+
+/**
+  Move iterator to the next element
+*/
+void HYDROData_LandCoverMap::Iterator::Next()
+{
+  myIterator->Next();
+}
+
+/**
+  Get the current land cover (face)
+  @return the land cover's face
+*/
+TopoDS_Face HYDROData_LandCoverMap::Iterator::Face() const
+{
+  return TopoDS::Face( myIterator->Value() );
+}
+
+/**
+  Get the current land cover's Strickler type 
+  @return the land cover's Strickler type 
+*/
+QString HYDROData_LandCoverMap::Iterator::StricklerType() const
 {
-  Handle(TDataStd_ExtStringArray) aTypesArray;
-  if( !myLab.FindChild( DataTag_Types ).FindAttribute( TDataStd_ExtStringArray::GetID(), aTypesArray ) )
+  if( myArray.IsNull() || myIndex < myArray->Lower() || myIndex > myArray->Upper() )
     return "";
+  else
+    return HYDROData_Tool::toQString( myArray->Value( myIndex ) );
+}
+
+/**
+  Constructor
+*/
+HYDROData_LandCoverMap::HYDROData_LandCoverMap()
+{
+}
+
+/**
+  Destructor
+*/
+HYDROData_LandCoverMap::~HYDROData_LandCoverMap()
+{
+}
+
+/**
+  Get object's kind
+  @return object's kind
+*/
+const ObjectKind HYDROData_LandCoverMap::GetKind() const
+{
+  return KIND_LAND_COVER_MAP;
+}
+
+/**
+  Import the land cover map from QGIS
+  @param theFileName the name of file
+  @return if the import is successful
+*/
+bool HYDROData_LandCoverMap::ImportQGIS( const QString& theFileName )
+{
+  //TODO
+  return false;
+}
 
-  TCollection_ExtendedString aType = aTypesArray->Value( theIndex );
-  TCollection_AsciiString anAscii = aType;
-  return anAscii.ToCString();
+/**
+  Export the land cover map to QGIS
+  @param theFileName the name of file
+  @return if the export is successful
+*/
+bool HYDROData_LandCoverMap::ExportQGIS( const QString& theFileName ) const
+{
+  //TODO
+  return false;
+}
+
+/**
+  Export the land cover map for the solver (Telemac)
+  @param theFileName the name of file
+  @return if the export is successful
+*/
+bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName ) const
+{
+  //TODO
+  return false;
+}
+
+/**
+  Add a new object as land cover
+  @param theObject the object to add as land cover
+  @param theType the Strickler type for the new land cover
+  @return if the addition is successful
+*/
+bool HYDROData_LandCoverMap::Add( const Handle( HYDROData_Object )& theObject, const QString& theType )
+{
+  //TODO
+  return false;
+}
+
+/**
+  Add a new polyline as land cover
+  @param thePolyline the polyline to add as land cover
+  @param theType the Strickler type for the new land cover
+  @return if the addition is successful
+*/
+bool HYDROData_LandCoverMap::Add( const Handle( HYDROData_Polyline )& thePolyline, const QString& theType )
+{
+  //TODO
+  return false;
+}
+
+/**
+  Remove the given face from land cover map
+  @param theFace the face to be removed
+  @return if the removing is successful
+*/
+bool HYDROData_LandCoverMap::Remove( const TopoDS_Face& theFace )
+{
+  //TODO
+  return false;
+}
+
+/**
+  Split the land cover map by the given polyline
+  @param thePolyline the tool polyline to split the land cover map
+  @return if the removing is successful
+*/
+bool HYDROData_LandCoverMap::Split( const Handle( HYDROData_Polyline )& thePolyline )
+{
+  //TODO
+  return false;
+}
+
+/**
+  Merge the given faces in the land cover
+  @param theFaces the faces to merge in the land cover map
+  @param theType the Strickler type for the merged land cover
+  @return if the merge is successful
+*/
+bool HYDROData_LandCoverMap::Merge( const TopTools_ListOfShape& theFaces, const QString& theType )
+{
+  //TODO
+  return false;
 }
 
-void HYDROData_LandCoverMap::SetStricklerType( int theIndex, const QString& theType )
+/**
+  Get the shape of the land cover map
+*/
+TopoDS_Shape HYDROData_LandCoverMap::GetShape() const
 {
-  Handle(TDataStd_ExtStringArray) aTypesArray;
-  if( !myLab.FindChild( DataTag_Types ).FindAttribute( TDataStd_ExtStringArray::GetID(), aTypesArray ) )
-    return;
+  TDF_Label aLabel = myLab.FindChild( DataTag_Shape, false );
+  if ( !aLabel.IsNull() )
+  {
+    Handle(TNaming_NamedShape) aNamedShape;
+    if( aLabel.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) )
+      return aNamedShape->Get();
+  }
+  return TopoDS_Shape();
+}
+
+/**
+  Set the shape of the land cover map
+  @param theShape the new shape for the land cover map
+*/
+void HYDROData_LandCoverMap::SetShape( const TopoDS_Shape& theShape )
+{
+  TNaming_Builder aBuilder( myLab.FindChild( DataTag_Shape ) );
+  aBuilder.Generated( theShape );
+}
+
+/**
+  Perform the local partition algorithm on the land cover
+  @param theNewShape the new shape to add into the land cover
+  @param theNewType the new Strickler type for the new land cover
+  @return if the local partition is successful
+*/
+bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, const QString& theNewType )
+{
+  BOPCol_ListOfShape aShapesList;
+  BOPAlgo_PaveFiller aPaveFiller;
+
+  // add faces to shapes list
+  Iterator anIt( *this );
+  for( ; anIt.More(); anIt.Next() )
+    aShapesList.Append( anIt.Face() );
+  aShapesList.Append( theNewShape );
+
+  // prepare pave filler
+  aPaveFiller.SetArguments( aShapesList );
+  aPaveFiller.Perform();
+  Standard_Integer anError = aPaveFiller.ErrorStatus();
+  if( anError )
+    return false;
 
-  std::string aType = theType.toStdString();
-  aTypesArray->SetValue( theIndex, aType.c_str() );
+  // add faces to builder
+  BOPAlgo_Builder aBuilder;
+  anIt.Init( *this );
+  for( ; anIt.More(); anIt.Next() )
+    aBuilder.AddArgument( anIt.Face() );
+  aBuilder.AddArgument( theNewShape );
+
+  // perform the partition with the pave filler
+  aBuilder.PerformWithFiller( aPaveFiller );
+  anError = aBuilder.ErrorStatus();
+  if( anError )
+    return false;
+
+  // analysis of the history
+  BOPCol_DataMapOfShapeListOfShape aSplits = aBuilder.Splits();
+
+  //     a. fill map of shape => type for initial faces
+  HYDROData_MapOfShapeToStricklerType anOldFaces;
+  anIt.Init( *this );
+  for( ; anIt.More(); anIt.Next() )
+    anOldFaces.Add( anIt.Face(), anIt.StricklerType() );
+
+  //     b. fill map of shape => type for split faces without the new face
+  HYDROData_MapOfShapeToStricklerType aNewFaces;
+  BOPCol_DataMapOfShapeListOfShape::Iterator aSplitIt( aSplits );
+  for( ; aSplitIt.More(); aSplitIt.Next() )
+  {
+    TopoDS_Shape anInitial = aSplitIt.Key();
+    if( anInitial==theNewShape )
+      continue;
+    QString aType = anOldFaces.FindFromKey( anInitial );
+    BOPCol_ListOfShape aSplitFaces = aSplitIt.Value();
+    BOPCol_ListOfShape::Iterator aSFIt( aSplitFaces );
+    for( ; aSFIt.More(); aSFIt.Next() )
+      aNewFaces.Add( aSFIt.Value(), aType );
+  }
+
+  //     c. add the new shape if it is face with its type
+  if( theNewShape.ShapeType()==TopAbs_FACE )
+    aNewFaces.Add( theNewShape, theNewType );
+  
+  // convert map of shape to type to compound and list of types
+  StoreLandCovers( aNewFaces );
+  return true;
 }
 
+/**
+  Replace the set of land covers in the land cover map
+  @param theMap the map of shape (face) to Strickler type (string)
+*/
+void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfShapeToStricklerType& theMap )
+{
+  TopoDS_Compound aCompound;
+  BRep_Builder aCompoundBuilder;
+  aCompoundBuilder.MakeCompound( aCompound );
+
+  int n = theMap.Size();
+  Handle( TDataStd_ExtStringArray ) aTypes = 
+    TDataStd_ExtStringArray::Set( myLab.FindChild( DataTag_Types ), 0, n-1, Standard_True );
+  HYDROData_MapOfShapeToStricklerType::Iterator aNFIt( theMap );
+  for( int i=0; aNFIt.More(); aNFIt.Next(), i++ )
+  {
+    aCompoundBuilder.Add( aCompound, aNFIt.Key() );
+    aTypes->SetValue( i, HYDROData_Tool::toExtString( aNFIt.Value() ) );
+  }
+
+  SetShape( aCompound );
+}