Salome HOME
c801780fd80cbb46cdd3d5aa249cecebac203bf1
[modules/hydro.git] / src / HYDROData / HYDROData_LandCoverMap.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROData_LandCoverMap.h>
20 #include <HYDROData_Tool.h>
21
22 #include <BOPAlgo_Builder.hxx>
23 #include <BOPAlgo_PaveFiller.hxx>
24 #include <BOPCol_ListOfShape.hxx>
25 #include <BRep_Builder.hxx>
26 #include <NCollection_IndexedMap.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_NamedShape.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Iterator.hxx>
33 #include <TopoDS_Shell.hxx>
34
35 #include <QString>
36
37 IMPLEMENT_STANDARD_HANDLE(HYDROData_LandCoverMap, HYDROData_Entity)
38 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_LandCoverMap, HYDROData_Entity)
39
40 class HYDROData_MapOfShapeToStricklerType : public NCollection_IndexedDataMap<TopoDS_Shape, QString>
41 {
42 };
43
44 /**
45   Constructor
46   @param theMap the land cover map to iterate through
47 */
48 HYDROData_LandCoverMap::Iterator::Iterator( const HYDROData_LandCoverMap& theMap )
49 {
50   Init( theMap );
51 }
52
53 /**
54   Initialize the iterator
55   @param theMap the land cover map to iterate through
56 */
57 void HYDROData_LandCoverMap::Iterator::Init( const HYDROData_LandCoverMap& theMap )
58 {
59   myIterator = new TopoDS_Iterator( theMap.GetShape() );
60   myIndex = 0;
61   theMap.myLab.FindChild( DataTag_Types ).FindAttribute( TDataStd_ExtStringArray::GetID(), myArray );
62 }
63
64 /**
65   Destructor
66 */
67 HYDROData_LandCoverMap::Iterator::~Iterator()
68 {
69   delete myIterator;
70 }
71
72 /**
73   Return if the iterator has more elements
74   @return if the iterator has more elements
75 */
76 bool HYDROData_LandCoverMap::Iterator::More() const
77 {
78   return !myArray.IsNull() && myIterator->More();
79 }
80
81 /**
82   Move iterator to the next element
83 */
84 void HYDROData_LandCoverMap::Iterator::Next()
85 {
86   myIterator->Next();
87 }
88
89 /**
90   Get the current land cover (face)
91   @return the land cover's face
92 */
93 TopoDS_Face HYDROData_LandCoverMap::Iterator::Face() const
94 {
95   return TopoDS::Face( myIterator->Value() );
96 }
97
98 /**
99   Get the current land cover's Strickler type 
100   @return the land cover's Strickler type 
101 */
102 QString HYDROData_LandCoverMap::Iterator::StricklerType() const
103 {
104   if( myArray.IsNull() || myIndex < myArray->Lower() || myIndex > myArray->Upper() )
105     return "";
106   else
107     return HYDROData_Tool::toQString( myArray->Value( myIndex ) );
108 }
109
110 /**
111   Constructor
112 */
113 HYDROData_LandCoverMap::HYDROData_LandCoverMap()
114 {
115 }
116
117 /**
118   Destructor
119 */
120 HYDROData_LandCoverMap::~HYDROData_LandCoverMap()
121 {
122 }
123
124 /**
125   Get object's kind
126   @return object's kind
127 */
128 const ObjectKind HYDROData_LandCoverMap::GetKind() const
129 {
130   return KIND_LAND_COVER_MAP;
131 }
132
133 /**
134   Import the land cover map from QGIS
135   @param theFileName the name of file
136   @return if the import is successful
137 */
138 bool HYDROData_LandCoverMap::ImportQGIS( const QString& theFileName )
139 {
140   //TODO
141   return false;
142 }
143
144 /**
145   Export the land cover map to QGIS
146   @param theFileName the name of file
147   @return if the export is successful
148 */
149 bool HYDROData_LandCoverMap::ExportQGIS( const QString& theFileName ) const
150 {
151   //TODO
152   return false;
153 }
154
155 /**
156   Export the land cover map for the solver (Telemac)
157   @param theFileName the name of file
158   @return if the export is successful
159 */
160 bool HYDROData_LandCoverMap::ExportTelemac( const QString& theFileName ) const
161 {
162   //TODO
163   return false;
164 }
165
166 /**
167   Add a new object as land cover
168   @param theObject the object to add as land cover
169   @param theType the Strickler type for the new land cover
170   @return if the addition is successful
171 */
172 bool HYDROData_LandCoverMap::Add( const Handle( HYDROData_Object )& theObject, const QString& theType )
173 {
174   //TODO
175   return false;
176 }
177
178 /**
179   Add a new polyline as land cover
180   @param thePolyline the polyline to add as land cover
181   @param theType the Strickler type for the new land cover
182   @return if the addition is successful
183 */
184 bool HYDROData_LandCoverMap::Add( const Handle( HYDROData_Polyline )& thePolyline, const QString& theType )
185 {
186   //TODO
187   return false;
188 }
189
190 /**
191   Remove the given face from land cover map
192   @param theFace the face to be removed
193   @return if the removing is successful
194 */
195 bool HYDROData_LandCoverMap::Remove( const TopoDS_Face& theFace )
196 {
197   //TODO
198   return false;
199 }
200
201 /**
202   Split the land cover map by the given polyline
203   @param thePolyline the tool polyline to split the land cover map
204   @return if the removing is successful
205 */
206 bool HYDROData_LandCoverMap::Split( const Handle( HYDROData_Polyline )& thePolyline )
207 {
208   //TODO
209   return false;
210 }
211
212 /**
213   Merge the given faces in the land cover
214   @param theFaces the faces to merge in the land cover map
215   @param theType the Strickler type for the merged land cover
216   @return if the merge is successful
217 */
218 bool HYDROData_LandCoverMap::Merge( const TopTools_ListOfShape& theFaces, const QString& theType )
219 {
220   //TODO
221   return false;
222 }
223
224 /**
225   Get the shape of the land cover map
226 */
227 TopoDS_Shape HYDROData_LandCoverMap::GetShape() const
228 {
229   TDF_Label aLabel = myLab.FindChild( DataTag_Shape, false );
230   if ( !aLabel.IsNull() )
231   {
232     Handle(TNaming_NamedShape) aNamedShape;
233     if( aLabel.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) )
234       return aNamedShape->Get();
235   }
236   return TopoDS_Shape();
237 }
238
239 /**
240   Set the shape of the land cover map
241   @param theShape the new shape for the land cover map
242 */
243 void HYDROData_LandCoverMap::SetShape( const TopoDS_Shape& theShape )
244 {
245   TNaming_Builder aBuilder( myLab.FindChild( DataTag_Shape ) );
246   aBuilder.Generated( theShape );
247 }
248
249 /**
250   Perform the local partition algorithm on the land cover
251   @param theNewShape the new shape to add into the land cover
252   @param theNewType the new Strickler type for the new land cover
253   @return if the local partition is successful
254 */
255 bool HYDROData_LandCoverMap::LocalPartition( const TopoDS_Shape& theNewShape, const QString& theNewType )
256 {
257   BOPCol_ListOfShape aShapesList;
258   BOPAlgo_PaveFiller aPaveFiller;
259
260   // add faces to shapes list
261   Iterator anIt( *this );
262   for( ; anIt.More(); anIt.Next() )
263     aShapesList.Append( anIt.Face() );
264   aShapesList.Append( theNewShape );
265
266   // prepare pave filler
267   aPaveFiller.SetArguments( aShapesList );
268   aPaveFiller.Perform();
269   Standard_Integer anError = aPaveFiller.ErrorStatus();
270   if( anError )
271     return false;
272
273   // add faces to builder
274   BOPAlgo_Builder aBuilder;
275   anIt.Init( *this );
276   for( ; anIt.More(); anIt.Next() )
277     aBuilder.AddArgument( anIt.Face() );
278   aBuilder.AddArgument( theNewShape );
279
280   // perform the partition with the pave filler
281   aBuilder.PerformWithFiller( aPaveFiller );
282   anError = aBuilder.ErrorStatus();
283   if( anError )
284     return false;
285
286   // analysis of the history
287   BOPCol_DataMapOfShapeListOfShape aSplits = aBuilder.Splits();
288
289   //     a. fill map of shape => type for initial faces
290   HYDROData_MapOfShapeToStricklerType anOldFaces;
291   anIt.Init( *this );
292   for( ; anIt.More(); anIt.Next() )
293     anOldFaces.Add( anIt.Face(), anIt.StricklerType() );
294
295   //     b. fill map of shape => type for split faces without the new face
296   HYDROData_MapOfShapeToStricklerType aNewFaces;
297   BOPCol_DataMapOfShapeListOfShape::Iterator aSplitIt( aSplits );
298   for( ; aSplitIt.More(); aSplitIt.Next() )
299   {
300     TopoDS_Shape anInitial = aSplitIt.Key();
301     if( anInitial==theNewShape )
302       continue;
303     QString aType = anOldFaces.FindFromKey( anInitial );
304     BOPCol_ListOfShape aSplitFaces = aSplitIt.Value();
305     BOPCol_ListOfShape::Iterator aSFIt( aSplitFaces );
306     for( ; aSFIt.More(); aSFIt.Next() )
307       aNewFaces.Add( aSFIt.Value(), aType );
308   }
309
310   //     c. add the new shape if it is face with its type
311   if( theNewShape.ShapeType()==TopAbs_FACE )
312     aNewFaces.Add( theNewShape, theNewType );
313   
314   // convert map of shape to type to compound and list of types
315   StoreLandCovers( aNewFaces );
316   return true;
317 }
318
319 /**
320   Replace the set of land covers in the land cover map
321   @param theMap the map of shape (face) to Strickler type (string)
322 */
323 void HYDROData_LandCoverMap::StoreLandCovers( const HYDROData_MapOfShapeToStricklerType& theMap )
324 {
325   TopoDS_Compound aCompound;
326   BRep_Builder aCompoundBuilder;
327   aCompoundBuilder.MakeCompound( aCompound );
328
329   int n = theMap.Size();
330   Handle( TDataStd_ExtStringArray ) aTypes = 
331     TDataStd_ExtStringArray::Set( myLab.FindChild( DataTag_Types ), 0, n-1, Standard_True );
332   HYDROData_MapOfShapeToStricklerType::Iterator aNFIt( theMap );
333   for( int i=0; aNFIt.More(); aNFIt.Next(), i++ )
334   {
335     aCompoundBuilder.Add( aCompound, aNFIt.Key() );
336     aTypes->SetValue( i, HYDROData_Tool::toExtString( aNFIt.Value() ) );
337   }
338
339   SetShape( aCompound );
340 }