Salome HOME
merge BR_LAND_COVER_MAP
[modules/hydro.git] / src / HYDROData / HYDROData_SinusX.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_SinusX.h"
20
21 #include <HYDROData_PolylineXY.h>
22 #include <HYDROData_Bathymetry.h>
23 #include <HYDROData_Entity.h>
24 #include <HYDROData_Document.h>
25 #include <HYDROData_Profile.h>
26 #include <HYDROData_Iterator.h>
27
28 #include <gp_XYZ.hxx>
29 #include <gp_XY.hxx>
30
31 #include <QFile>
32 #include <QFileInfo>
33 #include <QString>
34 #include <QStringList>
35 #include <QTextStream>
36
37 HYDROData_SinusX::HYDROData_SinusX( ) 
38 {
39 }
40
41 HYDROData_SinusX::~HYDROData_SinusX()
42 {
43 }
44
45 void HYDROData_SinusX::CollectExistingNames(Handle_HYDROData_Document theDocument)
46 {
47   HYDROData_Iterator anIter( theDocument );
48   int anInd = 0;
49   myExistingNames.clear();
50   std::vector<int> anAllowedIndexes;
51   for( ; anIter.More(); anIter.Next() )
52     myExistingNames.push_back(anIter.Current()->GetName());
53 }
54
55 QString HYDROData_SinusX::GetName(const QString& theName)
56 {
57   if (myExistingNames.contains(theName))
58   { 
59     QString aName = theName; 
60     while (myExistingNames.contains(aName)) 
61     {
62       QStringList aList = aName.split("_");
63       int aLastInd = aName.lastIndexOf("_");
64       bool IsNum = false; 
65       int anInd = -1;
66       anInd = aList.last().toInt(&IsNum);
67       if (IsNum)
68       {
69         aName = aName.left(aLastInd) + "_";
70         aName+= QString::number(++anInd);
71       }
72       else
73         aName = theName + "_0";
74     }
75
76     myExistingNames.push_back(aName);
77     return aName;
78   }
79   else
80   {
81     myExistingNames.push_back(theName);
82     return theName;
83   }
84
85 }
86
87
88 bool HYDROData_SinusX::Import(const QString& theFilePath, Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
89 {
90   if ( theFilePath.isEmpty() )
91   { 
92     return false;
93   }
94
95   QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
96
97   if (anExt == "sx")
98   {
99     QFile aFile (theFilePath);
100     
101     aFile.open(QIODevice::ReadOnly);
102
103     Parse(aFile);
104    
105     CollectExistingNames(theDocument);
106     SXToHydro(theDocument, theEntities);
107     
108     aFile.close();
109     
110     return true;
111   }
112   else
113     return false;
114
115 }
116
117 void HYDROData_SinusX::SXToHydro(Handle(HYDROData_Document) theDocument, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
118
119   for ( size_t i = 0; i < myCurveBlocks.size(); i++ )
120   {
121     if (myCurveBlocks[i].myType == 4) ///  scatter plot -> to bathy
122     {
123       Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( theDocument->CreateObject( KIND_BATHYMETRY ) );
124       HYDROData_Bathymetry::AltitudePoints aAPoints;
125       for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
126         aAPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[j]));
127
128       aBath->SetAltitudePoints(aAPoints);
129       aBath->SetName(GetName(myCurveBlocks[i].myName + "_bath"));
130       theEntities.Append(aBath);
131     }
132     if (myCurveBlocks[i].myType == 1 || myCurveBlocks[i].myType == 3)
133     {
134       NCollection_Sequence<gp_XYZ> aPoints;
135       for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
136         aPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[j]));
137       /*if (myCurveBlocks[i].myIsClosed)
138         aPoints.Append(gp_XYZ (myCurveBlocks[i].myXYZPoints[0]));*/
139       Handle(HYDROData_ProfileUZ) aProfileUZ = Handle(HYDROData_ProfileUZ)::DownCast( theDocument->CreateObject( KIND_PROFILEUZ ) );
140       Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) );
141       aPolyXY->AddSection( "",  
142         myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE, 
143         myCurveBlocks[i].myIsClosed ? true : false); 
144       aProfileUZ->CalculateAndAddPoints(aPoints, aPolyXY);
145       Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
146       aProfile->SetParametricPoints(aProfileUZ->GetPoints());
147       aPolyXY->SetName(GetName(myCurveBlocks[i].myName + "_polyXY"));
148       aProfileUZ->SetName(GetName(myCurveBlocks[i].myName + "_profileUZ"));
149       aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
150       theEntities.Append(aPolyXY);
151       theEntities.Append(aProfileUZ);
152       theEntities.Append(aProfile);
153     }
154     if (myCurveBlocks[i].myType == 2)
155     {
156       if (myCurveBlocks[i].myCurvePlane == 2)
157       {
158         if (myCurveBlocks[i].myAdditionalCurveInfo.size() == 4)
159         {
160           Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
161           HYDROData_ProfileUZ::PointsList aPointList;
162           for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
163             aPointList.Append(gp_XY (myCurveBlocks[i].myXYZPoints[j].X(), myCurveBlocks[i].myXYZPoints[j].Z()));
164           aProfile->GetProfileUZ()->SetSectionType(0,  myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
165           aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
166           aProfile->SetParametricPoints(aPointList);
167           if ( ! (myCurveBlocks[i].myAdditionalCurveInfo[0] == 0 &&  myCurveBlocks[i].myAdditionalCurveInfo[1] == 0 && 
168             myCurveBlocks[i].myAdditionalCurveInfo[2] == 0 && myCurveBlocks[i].myAdditionalCurveInfo[3] == 0) )
169           {
170             aProfile->SetLeftPoint(gp_XY(myCurveBlocks[i].myAdditionalCurveInfo[0], myCurveBlocks[i].myAdditionalCurveInfo[1]));
171             aProfile->SetRightPoint(gp_XY(myCurveBlocks[i].myAdditionalCurveInfo[2], myCurveBlocks[i].myAdditionalCurveInfo[3]));
172             aProfile->Update();
173           }
174           aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
175           theEntities.Append(aProfile);
176         }
177       }
178       if (myCurveBlocks[i].myCurvePlane == 0)
179       {
180         Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( theDocument->CreateObject( KIND_PROFILE ) );
181         HYDROData_Profile::ProfilePoints aPointList;
182         for (size_t j = 0; j < myCurveBlocks[i].myXYZPoints.size(); j++)
183           aPointList.Append(myCurveBlocks[i].myXYZPoints[j]);
184         aProfile->GetProfileUZ()->SetSectionType(0,  myCurveBlocks[i].myIsSpline ? HYDROData_PolylineXY::SECTION_SPLINE : HYDROData_PolylineXY::SECTION_POLYLINE);
185         aProfile->GetProfileUZ()->SetSectionClosed(0, myCurveBlocks[i].myIsClosed ? true : false);
186         aProfile->SetProfilePoints(aPointList);
187         aProfile->SetName(GetName(myCurveBlocks[i].myName + "_profile"));
188         theEntities.Append(aProfile);
189       }
190     }
191   }
192
193 }
194  
195
196 bool HYDROData_SinusX::Parse(QFile& theFile)
197 {
198   if ( !theFile.isOpen() )
199     return false;
200
201   QString aLine;
202   QString aBLine;
203   QStringList aList;
204   QStringList aBList;
205   myCurveBlocks.clear();
206   bool aTotStat = true;
207
208   aLine = theFile.readLine().simplified();
209   aList = aLine.split( ' ', QString::SkipEmptyParts );
210
211   for (;!theFile.atEnd();) 
212   {
213     if (aList[0] == "B" && (aList[1] == "C" || aList[1] == "P" || aList[1] == "N" || aList[1] == "S" ))
214     {  
215       HYDROGUI_CurveBlock aCurveBlockInfo;
216       if (aList[1] == "C")
217         aCurveBlockInfo.myType = 1;
218       else if (aList[1] == "P")
219         aCurveBlockInfo.myType = 2;
220       else if (aList[1] == "N")
221         aCurveBlockInfo.myType = 3;
222       else if (aList[1] == "S")
223         aCurveBlockInfo.myType = 4;
224
225       if (aList.size() == 9)
226       {
227         for (int j = 2; j < 8; j++)
228           aCurveBlockInfo.myRefCoords.push_back(aList[j].toDouble());
229         aCurveBlockInfo.myRefRatio = aList[8].toDouble();
230       }
231
232       QString Name;
233       do
234       {
235         aBLine = theFile.readLine().simplified();
236         aBList = aBLine.split( ' ', QString::SkipEmptyParts );
237          
238         if (aBList[0] == "CP")
239         {
240           if (aBList.size() == 2 && (aBList[1] == "0" || aBList[1] == "1" || aBList[1] == "2"))
241             aCurveBlockInfo.myCurvePlane = aBList[1].toInt();
242           else if (aBList.size() == 3 && (aBList[1] == "0" || aBList[1] == "1") && (aBList[2] == "0" || aBList[2] == "1"))
243           {
244             aCurveBlockInfo.myIsClosed = aBList[1].toInt();
245             aCurveBlockInfo.myIsSpline = aBList[2].toInt();
246           }
247           else
248           {
249             for (int j = 1; j < aBList.size(); j++)
250               aCurveBlockInfo.myAdditionalCurveInfo.push_back(aBList[j].toDouble());
251           }
252         }
253         if (aBList[0] == "CN")
254         {
255            for (int i = 1; i < aBList.size(); i++)
256              Name += aBList[i] + "_"; 
257            Name.remove(Name.size() - 1, 1);
258            aCurveBlockInfo.myName = Name;
259         }
260       } while (!theFile.atEnd() && aBLine[0] == 'C' );
261
262       bool aStat;
263       aTotStat = true;
264       do
265       {
266         if (aBList.size() >= 3 && aBLine[0] != 'B' && aBLine[0] != 'C') {
267           gp_XYZ anXYZ;
268           anXYZ.SetX (aBList[0].toDouble(&aStat));  
269           aTotStat = aTotStat && aStat;
270           anXYZ.SetY (aBList[1].toDouble(&aStat));
271           aTotStat = aTotStat && aStat;
272           anXYZ.SetZ (aBList[2].toDouble(&aStat));
273           aTotStat = aTotStat && aStat;
274
275           aCurveBlockInfo.myXYZPoints.push_back(anXYZ);
276           
277           aBLine = theFile.readLine().simplified();
278           aBList = aBLine.split( ' ', QString::SkipEmptyParts );
279         }
280         else 
281           break;
282     
283       } while (!theFile.atEnd() || !aBLine.isEmpty());
284       if (aTotStat)
285         myCurveBlocks.push_back(aCurveBlockInfo);
286
287       aLine = aBLine;
288       aList = aBList;
289
290     }
291     else
292     {
293       aLine = theFile.readLine().simplified();
294       aList = aLine.split( ' ', QString::SkipEmptyParts );
295     }
296
297   }
298
299   return true;
300
301 }
302
303 bool HYDROData_SinusX::Export(const QString& theFilePath, const NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
304 {
305   if ( theFilePath.isEmpty() )
306   { 
307     return false;
308   }
309
310   QString anExt = theFilePath.split('.', QString::SkipEmptyParts).back();
311
312   if (anExt == "sx")
313   {
314     QFile aFile (theFilePath);
315     
316     aFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
317
318     HydroToSX(aFile, theEntities);
319     
320     aFile.close();
321     
322     return true;
323   }
324   else
325     return false;
326
327 }
328
329 void HYDROData_SinusX::HydroToSX(QFile& theFile, const NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
330 {
331   QTextStream aTextStream(&theFile);
332   aTextStream << "C  Generated by HYDRO Module\n";
333   aTextStream << "C\n";
334
335   for (int i = 1; i <= theEntities.Size(); i++)
336   {
337     Handle_HYDROData_Entity anEnt = theEntities.Value(i);
338     if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Bathymetry) ))
339     {
340       Handle(HYDROData_Bathymetry) aBathy = Handle(HYDROData_Bathymetry)::DownCast( anEnt );
341       HYDROData_Bathymetry::AltitudePoints anXYZPoints = aBathy->GetAltitudePoints(true);
342       //Write to stream
343       aTextStream << "B S\n";
344       aTextStream << "CN " << aBathy->GetName() << "\n";
345       aTextStream << "CP 0 0\n";
346       aTextStream << "CP 0\n";
347       for (int j = anXYZPoints.Lower(); j <= anXYZPoints.Upper(); j++)
348         aTextStream << " " << QString::number(anXYZPoints(j).X(), 'f', 3)  
349                     << " " << QString::number(anXYZPoints(j).Y(), 'f', 3)  
350                     << " " << QString::number(anXYZPoints(j).Z(), 'f', 3) << "\n"; 
351     }
352     else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_PolylineXY) ))
353     {
354       Handle(HYDROData_PolylineXY) aPolyXY = Handle(HYDROData_PolylineXY)::DownCast( anEnt );
355       for (int j = 0; j < aPolyXY->NbSections(); j++)
356       { 
357         //Collect data
358         bool IsClosed = aPolyXY->IsClosedSection(j);
359         bool IsSpline = false;
360         if (aPolyXY->GetSectionType(j) == HYDROData_PolylineXY::SECTION_SPLINE)
361           IsSpline = true;
362         HYDROData_PolylineXY::PointsList anXYPoints = aPolyXY->GetPoints(j, true);
363         //Write to stream
364         aTextStream << "B N\n";
365         aTextStream << "CN " << aPolyXY->GetName() << "\n";
366         aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
367         aTextStream << "CP 0.0\n";
368         aTextStream << "CP 0\n";
369         if (aPolyXY->NbSections() > 1)
370           aTextStream << "C " << aPolyXY->GetName() << "_section_" << QString::number(j) << "\n";
371         for (int k = anXYPoints.Lower(); k <= anXYPoints.Upper(); k++)
372          aTextStream << " " << QString::number(anXYPoints(k).X(), 'f', 3)  
373                      << " " << QString::number(anXYPoints(k).Y(), 'f', 3)  
374                      << " 0.000\n"; 
375       }
376     }
377     else if (anEnt->IsKind( STANDARD_TYPE(HYDROData_Profile) ))
378     {
379       //Collect data
380       Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anEnt );
381       HYDROData_ProfileUZ::PointsList aPointList = aProfile->GetParametricPoints();
382       bool IsClosed = aProfile->GetProfileUZ(false)->IsClosedSection(0);;
383       bool IsSpline = false;
384       if (aProfile->GetProfileUZ(false)->GetSectionType(0) == HYDROData_PolylineXY::SECTION_SPLINE)
385         IsSpline = true;
386       //Write to stream
387       aTextStream << "B P\n";
388       aTextStream << "CN " << aProfile->GetName() << "\n";
389       aTextStream << "CP " << IsClosed << " " << IsSpline << "\n";
390       gp_XY aLeftPoint(0.0, 0.0);
391       gp_XY aRightPoint(0.0, 0.0);
392       if (aProfile->GetLeftPoint(aLeftPoint, true) && aProfile->GetRightPoint(aRightPoint, true))
393         aTextStream << "CP " << QString::number(aLeftPoint.X(), 'f', 3) << " " <<
394                                 QString::number(aLeftPoint.Y(), 'f', 3) << " " <<
395                                 QString::number(aRightPoint.X(), 'f', 3) << " " <<
396                                 QString::number(aRightPoint.Y(), 'f', 3) << "\n";
397       else
398         aTextStream << "CP 0.0 0.0 0.0 0.0\n";
399       aTextStream << "CP 2\n";
400       for (int k = aPointList.Lower(); k <= aPointList.Upper(); k++)
401          aTextStream << " " << QString::number(aPointList(k).X(), 'f', 3)  
402                      << " 0.000 "
403                      << QString::number(aPointList(k).Y(), 'f', 3) << "\n";  
404     }
405   }
406 }