Salome HOME
Merge branch 'BR_v14_rc' of ssh://git.salome-platform.org/modules/hydro into BR_v14_rc
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportPolylineOp.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_ImportPolylineOp.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_UpdateFlags.h"
28 #include "HYDROGUI_Tool.h"
29 #include <HYDROData_PolylineXY.h>
30 #include <HYDROData_Polyline3D.h>
31 #include <HYDROGUI_DataObject.h>
32 #include <HYDROData_Bathymetry.h>
33 #include <HYDROData_Iterator.h>
34
35 #include <HYDROData_Profile.h>
36
37 #include <SUIT_Desktop.h>
38 #include <SUIT_FileDlg.h>
39 #include <LightApp_Application.h>
40
41 #include <QApplication>
42 #include <QFile>
43 #include <QFileInfo>
44 #include <SUIT_MessageBox.h>
45
46
47 HYDROGUI_ImportPolylineOp::HYDROGUI_ImportPolylineOp( HYDROGUI_Module* theModule )
48 : HYDROGUI_Operation( theModule )
49 {
50   setName( tr( "IMPORT_POLYLINE" ) );
51 }
52
53 HYDROGUI_ImportPolylineOp::~HYDROGUI_ImportPolylineOp()
54 {
55 }
56
57 void HYDROGUI_ImportPolylineOp::startOperation()
58 {
59   HYDROGUI_Operation::startOperation();
60
61   myFileDlg = new SUIT_FileDlg( module()->getApp()->desktop(), true );
62   myFileDlg->setWindowTitle( getName() );
63   myFileDlg->setFileMode( SUIT_FileDlg::ExistingFiles );
64   myFileDlg->setFilter( tr("POLYLINE_FILTER") );
65
66   connect( myFileDlg, SIGNAL( accepted() ), this, SLOT( onApply() ) );
67   connect( myFileDlg, SIGNAL( rejected() ), this, SLOT( onCancel() ) );
68
69   myFileDlg->exec();
70 }
71
72 void HYDROGUI_ImportPolylineOp::onApply()
73 {
74   if ( !myFileDlg )
75   {
76     abort();
77     return;
78   }
79
80   QStringList aFileNames = myFileDlg->selectedFiles();
81   
82   QApplication::setOverrideCursor( Qt::WaitCursor );  
83   startDocOperation();
84
85   foreach (QString aFileName, aFileNames) 
86   {
87     if ( aFileName.isEmpty() )
88       continue;
89
90     QString anExt = aFileName.split('.', QString::SkipEmptyParts).back();
91
92     if (anExt == "shp")
93     {
94       SHPHandle aHSHP;
95       aHSHP = SHPOpen( aFileName.toAscii().data(), "rb" );
96       Parse(aHSHP);
97
98       HYDROData_Iterator anIter( doc() );
99       int anInd = 0;
100       QStringList anExistingNames;
101       std::vector<int> anAllowedIndexes;
102       for( ; anIter.More(); anIter.Next() )
103         anExistingNames.push_back(anIter.Current()->GetName());
104
105       QFileInfo aFileInfo(aFileName);
106       QString aBaseFileName = aFileInfo.baseName();
107
108       if (aHSHP->nShapeType == 3 || aHSHP->nShapeType == 23)
109       {
110         anInd = 0;
111         for (;anAllowedIndexes.size() < mySHPObjects.size();)
112         {
113           if (!anExistingNames.contains(aBaseFileName + "_PolyXY_" + QString::number(anInd)))
114           {
115             anAllowedIndexes.push_back(anInd);
116             anInd++;
117           }
118           else
119             anInd++;
120         }
121         
122         for (size_t i = 0; i < mySHPObjects.size(); i++ )
123         {
124           ProcessSHPPolyXY(mySHPObjects[i], aBaseFileName, anAllowedIndexes[i]);
125         }
126       }
127       else if (aHSHP->nShapeType == 13)
128       {
129         anInd = 0;
130         for (;anAllowedIndexes.size() < mySHPObjects.size();)
131         {
132           if (!anExistingNames.contains(aBaseFileName + "_PolyXY_" + QString::number(anInd)) &&
133               !anExistingNames.contains(aBaseFileName + "_Poly3D_" + QString::number(anInd)) &&
134               !anExistingNames.contains(aBaseFileName + "_Bath_" + QString::number(anInd)))
135           {
136             anAllowedIndexes.push_back(anInd);
137             anInd++;
138           }
139           else
140             anInd++;
141         }
142         for (size_t i = 0; i < mySHPObjects.size(); i++ )
143           ProcessSHPPoly3D(mySHPObjects[i], aBaseFileName, anAllowedIndexes[i]);
144       }
145       else  
146       {
147         SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), "Cannot import polyline;\nThe shape type is incorrect" );
148       }
149     
150       for (size_t i = 0; i < mySHPObjects.size(); i++ )
151         free (mySHPObjects[i]);
152
153       mySHPObjects.clear();
154       SHPClose(aHSHP);
155     }
156   }
157   if (!aFileNames.empty())
158   {
159     commitDocOperation();
160     commit();
161     module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init );
162   }
163   else
164     abort();
165   
166   QApplication::restoreOverrideCursor();
167 }
168
169 void HYDROGUI_ImportPolylineOp::ProcessSHPPolyXY(SHPObject* anObj, QString theFileName, int theInd)
170 {
171   //if (anObj->nSHPType != SHPT_ARC && anObj->nSHPType != SHPT_ARCM)
172   // return false;
173   Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
174   
175   int nParts = anObj->nParts;
176   for ( int i = 0 ; i < nParts ; i++ )
177   {
178     int StartIndex = anObj->panPartStart[i];
179     int EndIndex;
180     if (i != nParts - 1)
181       EndIndex = anObj->panPartStart[i + 1];
182     else
183       EndIndex = anObj->nVertices;
184
185     bool IsClosed = false;
186     HYDROData_PolylineXY::SectionType aSectType = HYDROData_PolylineXY::SECTION_POLYLINE; 
187     if (anObj->padfX[StartIndex] == anObj->padfX[EndIndex - 1] &&
188         anObj->padfY[StartIndex] == anObj->padfY[EndIndex - 1] )
189     {
190       IsClosed = true;
191       aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, true);
192     }
193     else
194       aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, false);
195     
196     if (IsClosed)
197       EndIndex--;
198     for ( int k = StartIndex; k < EndIndex ; k++ )
199     {
200       HYDROData_PolylineXY::Point aSectPoint;
201       aSectPoint.SetX( anObj->padfX[k] );
202       aSectPoint.SetY( anObj->padfY[k] );
203       aPolylineXY->AddPoint( i, aSectPoint );
204     }
205
206   }
207   
208   aPolylineXY->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
209   aPolylineXY->SetName( theFileName + "_PolyXY_" + QString::number(theInd) );
210   
211   aPolylineXY->Update();
212   
213   size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module() );
214   if ( anActiveViewId == 0 )
215     anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module() );
216   
217   module()->setObjectVisible( anActiveViewId, aPolylineXY, true );
218   
219   module()->setIsToUpdate( aPolylineXY );
220 }
221
222 void HYDROGUI_ImportPolylineOp::ProcessSHPPoly3D(SHPObject* anObj, QString theFileName, int theInd)
223 {
224   Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
225
226   Handle(HYDROData_Polyline3D) aPolylineObj = Handle(HYDROData_Polyline3D)::DownCast( doc()->CreateObject( KIND_POLYLINE ) );
227
228   Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( doc()->CreateObject( KIND_BATHYMETRY ) );
229   HYDROData_Bathymetry::AltitudePoints aAPoints;
230
231   int nParts = anObj->nParts;
232   for ( int i = 0 ; i < nParts ; i++ )
233   {
234     //bool aSectClosure = true;
235     int StartIndex = anObj->panPartStart[i];
236     int EndIndex;
237     if (i != nParts - 1)
238       EndIndex = anObj->panPartStart[i + 1];
239     else
240       EndIndex = anObj->nVertices;
241
242     bool IsClosed = false;
243     HYDROData_PolylineXY::SectionType aSectType = HYDROData_PolylineXY::SECTION_POLYLINE; 
244     if (anObj->padfX[StartIndex] == anObj->padfX[EndIndex - 1] &&
245         anObj->padfY[StartIndex] == anObj->padfY[EndIndex - 1] &&
246         anObj->padfZ[StartIndex] == anObj->padfZ[EndIndex - 1])
247     {
248       IsClosed = true;
249       aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, true );
250     }
251     else
252       aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, false  );
253     
254     if (IsClosed)
255       EndIndex--;
256     for ( int k = StartIndex ; k < EndIndex ; k++ )
257     {
258       HYDROData_PolylineXY::Point aSectPoint;
259       aSectPoint.SetX( anObj->padfX[k] );
260       aSectPoint.SetY( anObj->padfY[k] );
261       aPolylineXY->AddPoint( i, aSectPoint );
262       aAPoints.Append(gp_XYZ (anObj->padfX[k], anObj->padfY[k], anObj->padfZ[k]));
263     }
264   }
265
266
267   QString aBathName = theFileName + "_bath_" + QString::number(theInd);
268   QString aPolyXYName = theFileName + "_polyXY_" + QString::number(theInd);
269   QString aPoly3DName = theFileName + "_poly3D_" + QString::number(theInd);
270
271   aPolylineXY->SetName( aPolyXYName );
272   aPolylineXY->SetWireColor(HYDROData_PolylineXY::DefaultWireColor());
273   aPolylineXY->Update();
274   
275   aBath->SetAltitudePoints(aAPoints);
276   aBath->SetName( aBathName );
277
278   aPolylineObj->SetPolylineXY (aPolylineXY, false);
279   aPolylineObj->SetAltitudeObject(aBath);
280
281   aPolylineObj->SetBorderColor( HYDROData_Polyline3D::DefaultBorderColor() );
282   aPolylineObj->SetName( aPoly3DName );
283   
284   aPolylineObj->Update();
285
286   size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module() );
287   if ( anActiveViewId == 0 )
288     anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module() );
289
290   module()->setObjectVisible( anActiveViewId, aPolylineXY, true );
291   module()->setObjectVisible( anActiveViewId, aPolylineObj, true );
292
293   module()->setIsToUpdate( aPolylineObj );
294 }
295
296 void HYDROGUI_ImportPolylineOp::Parse(SHPHandle theHandle)
297 {
298   int aShapeType;
299   mySHPObjects.clear();
300   SHPGetInfo( theHandle, NULL, &aShapeType, NULL, NULL );
301   if (aShapeType == 3 || aShapeType == 13 || aShapeType == 23) 
302   {
303     for (int i = 0; i < theHandle->nRecords; i++) 
304       mySHPObjects.push_back(SHPReadObject(theHandle, i));
305   }
306 }