Salome HOME
LCM // Import/Export of SHP p.3
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportLandCoverMapOp.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_ImportLandCoverMapOp.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_UpdateFlags.h"
28 #include "HYDROGUI_Tool.h"
29 #include "HYDROGUI_ImportLandCoverMapDlg.h"
30 #include "HYDROGUI_Shape.h"
31 #include <HYDROData_LandCoverMap.h>
32 #include <HYDROGUI_ZLayers.h>
33
34 #include <HYDROGUI_DataObject.h>
35 #include <HYDROData_Iterator.h>
36 #include <HYDROData_ShapeFile.h>
37 #include <HYDROData_Profile.h>
38
39 #include <SUIT_Desktop.h>
40 #include <SUIT_FileDlg.h>
41 #include <LightApp_Application.h>
42
43 #include <QApplication>
44 #include <QFile>
45 #include <QFileInfo>
46 #include <SUIT_MessageBox.h>
47
48 #include <OCCViewer_ViewManager.h>
49 #include <OCCViewer_ViewModel.h>
50
51 #include <SalomeApp_Study.h>
52
53 #include <LightApp_Application.h>
54 #include <LightApp_DataOwner.h>
55 #include <LightApp_Displayer.h>
56 #include <LightApp_SelectionMgr.h>
57 #include <HYDROData_StricklerTable.h>
58
59 #include <SUIT_Desktop.h>
60 #include <SUIT_ViewManager.h>
61
62 #include <BRep_Builder.hxx>
63 #include <TopoDS.hxx>
64 #include <TopoDS_Shape.hxx>
65 #include <TopoDS_Wire.hxx>
66 #include <QSet>
67
68 #include <HYDROData_LandCoverMap.h>
69
70
71 //TODO deny to create null-LCM (selected poltgons on the first page = 0)
72 //TODO erase onBack/onFinish if not needed...
73
74 HYDROGUI_ImportLandCoverMapOp::HYDROGUI_ImportLandCoverMapOp( HYDROGUI_Module* theModule )
75 : HYDROGUI_Operation( theModule )
76 {
77   setName( tr( "IMPORT_LANDCOVERMAP" ) );
78 }
79
80 HYDROGUI_ImportLandCoverMapOp::~HYDROGUI_ImportLandCoverMapOp()
81 {
82   erasePreview();
83   myImporter.Free();
84   myAttrV.clear();
85 }
86
87 void HYDROGUI_ImportLandCoverMapOp::startOperation()
88 {
89   HYDROGUI_Operation::startOperation();
90
91   if ( !getPreviewManager() ) {
92     setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>( 
93                        module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
94   }
95
96   HYDROGUI_ImportLandCoverMapDlg* aPanel = 
97     ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
98   if ( !aPanel ) {
99     return;
100   }
101
102   aPanel->reset();
103 }
104
105 void HYDROGUI_ImportLandCoverMapOp::onFileSelected()
106 {
107   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
108   if ( !aPanel )
109     return;
110   
111   QString anObjectName = aPanel->getObjectName().simplified();
112   anObjectName = aPanel->getFileName();
113   if ( !anObjectName.isEmpty() ) 
114       anObjectName = QFileInfo( anObjectName ).baseName();
115
116   if ( anObjectName.isEmpty() ) 
117     anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_LANDCOVERMAP_NAME" ) );
118   aPanel->setObjectName( anObjectName );
119
120   myFileName = aPanel->getFileName();
121   if ( myFileName.isEmpty() )
122   {
123     abort();
124     return;
125   }
126
127   QString anExt = myFileName.split('.', QString::SkipEmptyParts).back();
128
129   if (anExt == "shp")
130   {     
131     startDocOperation();    
132     QApplication::setOverrideCursor(Qt::WaitCursor);
133     
134     QStringList aPolygonsList;
135     myPolygonFaces.Clear();
136     myImporter.Free();
137
138     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
139     if ( !aStudy )
140       return;
141
142     erasePreview();
143
144     Handle(AIS_InteractiveContext) aCtx = NULL;
145     int aShapeTypeOfFile = -1;
146
147     //Import polygons from SHP file as faces
148     //This faces should be added to the new LCM object
149
150     int aStat = myImporter.ImportPolygons(myFileName, aPolygonsList, myPolygonFaces, aShapeTypeOfFile);
151     if (aStat == 1)
152     {
153       aPanel->setPolygonNames(aPolygonsList);
154
155       LightApp_Application* anApp = module()->getApp();
156       if ( !getPreviewManager() )
157         setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>( anApp->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
158       OCCViewer_ViewManager* aViewManager = getPreviewManager();
159
160       if ( aViewManager )
161       {
162         if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
163         {
164           aCtx = aViewer->getAISContext();
165           connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
166         }
167       }
168
169       for ( int i = 1; i <= myPolygonFaces.Length(); i++ ) 
170       {
171         TopoDS_Face aFace = TopoDS::Face(myPolygonFaces.Value( i ));
172         if ( aViewManager && !aCtx.IsNull() )
173         {
174           HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
175           //Green color for now..
176           aShape->setFillingColor(QColor(0,255,0), false, false);
177           aShape->setBorderColor(QColor(0,255,0), false, false);
178           if( !aFace.IsNull() )
179             aShape->setShape( aFace);
180
181           myPolygonName2PrsShape.insert( "polygon_" + QString::number(i), aShape);
182         }
183       }
184       if ( !aCtx.IsNull() ) 
185       {
186         UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, Graphic3d_ZLayerId_TopOSD );
187         aCtx->UpdateCurrentViewer();
188       }
189       //
190       QApplication::restoreOverrideCursor();
191       aPanel->setFirstPageState(true); 
192     }
193     else
194     {
195       erasePreview();
196       aPanel->setPolygonNames(QStringList());
197       aPanel->setObjectName("");
198       QApplication::restoreOverrideCursor();
199       QString aMess = "Cannot import land cover;\n";
200       if (aStat == -1)
201         aMess += "Cannot open SHP file";
202       else if (aStat == -2)
203         aMess += "Cannot open SHX file";
204       else 
205         aMess += "The shape type of file is " + myImporter.GetShapeTypeName(aShapeTypeOfFile);
206       SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "IMPORT_LANDCOVER" ), aMess);
207       commitDocOperation();
208       myImporter.Free();
209       //abort();
210       aPanel->setFirstPageState(false);
211     }
212     
213   }
214   
215 }
216
217 HYDROGUI_InputPanel* HYDROGUI_ImportLandCoverMapOp::createInputPanel() const
218 {
219   HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportLandCoverMapDlg( module(), getName() );
220
221   connect( aPanel, SIGNAL( FileSelected( const QString& ) ), SLOT( onFileSelected() ) );
222
223   connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
224
225   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
226   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onBack( const int ) ) );
227   connect( aPanel, SIGNAL( Finish( const int ) ), SLOT( onFinish( const int ) ) );
228     
229   return aPanel;
230 }
231
232 bool HYDROGUI_ImportLandCoverMapOp::processApply( int& theUpdateFlags,
233                                                 QString& theErrorMsg,
234                                                 QStringList& theBrowseObjectsEntries )
235 {
236   //TODO rewrite this!
237   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
238   if ( !aPanel ) {
239     return false;
240   }
241
242   Handle(HYDROData_LandCoverMap) aLCM =  Handle(HYDROData_LandCoverMap)::DownCast( doc()->CreateObject( KIND_LAND_COVER_MAP ) );
243    
244   HYDROData_MapOfFaceToStricklerType aMapFace2ST;
245
246   /*QStringList aSelectedPolygons = aPanel->getSelectedPolygonNames();
247   aPanel->removePolygonNames( aSelectedPolygons );
248     
249   foreach ( QString aName, aSelectedPolygons )
250   {
251     TopoDS_Shape aShape = myPolygonName2PrsShape.value( aName )->getTopoShape();
252     if ( aShape.IsNull() ) 
253       continue;
254     aMapFace2ST.Add( TopoDS::Face( aShape ), "TODO temp" ); //TODO get from tableW
255     HYDROGUI_Shape* aShapeToDelete = myPolygonName2PrsShape.take( aName );
256     delete aShapeToDelete;
257   }*/
258   QStringList aAttrV_T;
259   QStringList aSTL;
260   aPanel->GetAttribute2StricklerCorr(aAttrV_T, aSTL);
261
262   QVector<int> aSelIndices = aPanel->getSelectedPolygonIndices();
263   foreach ( int Ind, aSelIndices ) //check i-base.
264   {
265     TopoDS_Shape aShape = myPolygonFaces(Ind + 1);
266     if ( aShape.IsNull() ) 
267       continue;
268     HYDROData_ShapeFile::DBF_AttrValue aV = myAttrV[Ind];
269     int StricklerTypesInd = aAttrV_T.indexOf(QString(aV.myStrVal));
270       QString aST = aSTL.at(StricklerTypesInd);
271     aMapFace2ST.Add( TopoDS::Face( aShape ), aST ); //TODO get from tableW
272     //HYDROGUI_Shape* aShapeToDelete = myPolygonName2PrsShape.take( aName );
273     //delete aShapeToDelete;
274   }
275
276   //
277   aLCM->StoreLandCovers(aMapFace2ST);
278
279   if( !aLCM.IsNull() ) 
280   {
281     aLCM->SetName( "temp_name" );
282     aLCM->SetColor( QColor(0,100,100) );
283     aLCM->Show();
284     module()->setIsToUpdate( aLCM );
285     
286   }
287   
288   module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init );
289
290   erasePreview();
291   myImporter.Free();
292   myAttrV.clear();
293
294   return true;
295 }
296
297 void HYDROGUI_ImportLandCoverMapOp::onSelectionChanged( const QStringList& theSelectedNames )
298 {
299   Handle(AIS_InteractiveContext) aCtx = NULL;
300
301   OCCViewer_ViewManager* aViewManager = getPreviewManager();
302   if ( aViewManager ) {
303     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
304       aCtx = aViewer->getAISContext();
305     }
306   }
307
308   if ( !aCtx.IsNull() ) {
309     foreach ( QString aName, myPolygonName2PrsShape.keys() ) {
310       Handle(AIS_InteractiveObject) anObject = 
311         myPolygonName2PrsShape.value(aName)->getAISObject();
312
313       bool isSelected = theSelectedNames.contains( aName );
314       if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
315            ( !isSelected && aCtx->IsSelected( anObject) ) ) {
316         aCtx->AddOrRemoveSelected( anObject, Standard_False );
317       }
318       /*if (isSelected)
319       {
320         HYDROGUI_Shape* aHydroSh = myPolygonName2PrsShape.value( aName );
321         aHydroSh->setFillingColor(QColor(0,255,255), true, true);
322       }*/
323     }
324     aCtx->UpdateCurrentViewer();
325   }
326 }
327
328
329 void HYDROGUI_ImportLandCoverMapOp::onViewerSelectionChanged()
330 {
331   // Get panel
332   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
333   if ( !aPanel ) {
334     return;
335   }
336
337   OCCViewer_ViewManager* aViewManager = getPreviewManager();
338   Handle(AIS_InteractiveContext) aCtx = NULL;
339   if ( aViewManager ) {
340     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
341       aCtx = aViewer->getAISContext();
342     }
343   }
344   
345   if ( !aCtx.IsNull() )
346   {
347     QStringList aSelectedNames;
348     foreach ( QString aName, myPolygonName2PrsShape.keys() ) {
349       bool isSelected = aCtx->IsSelected( myPolygonName2PrsShape.value(aName)->getAISObject() );
350       if ( isSelected ) {
351         aSelectedNames << aName;
352       }
353     }
354     aPanel->setSelectedPolygonNames( aSelectedNames );
355   }
356 }
357
358
359 void HYDROGUI_ImportLandCoverMapOp::erasePreview()
360 {
361   foreach ( HYDROGUI_Shape* aShape, myPolygonName2PrsShape ) {
362     delete aShape;
363   }
364
365   myPolygonName2PrsShape.clear();
366 }
367
368
369 void HYDROGUI_ImportLandCoverMapOp::abortOperation()
370 {
371   LightApp_Application* anApp = module()->getApp();
372   if ( anApp ) {
373     anApp->disconnect( this );
374   }
375
376   erasePreview();
377   myImporter.Free();
378   HYDROGUI_Operation::abortOperation();
379 }
380
381 //TODO take "Use dbf attrs as ST.." into account
382 void HYDROGUI_ImportLandCoverMapOp::onNext( const int theIndex )
383 {  
384   //TODO add acceptor
385   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
386   if ( !aPanel )
387     return;
388
389   if (theIndex == 1)
390   {
391       //Try to load DBF-database...
392       QString theDBFFileName;
393       theDBFFileName = myFileName.simplified().replace( ".shp", ".dbf", Qt::CaseInsensitive);
394       bool DBF_Stat = myImporter.DBF_OpenDBF(theDBFFileName);
395       // TODO:
396       // add MSG BOX if stat is bad
397       myFieldList = myImporter.DBF_GetFieldList();
398       aPanel->setAttributeNames(myFieldList);
399   }
400
401   if (theIndex == 2)
402   {
403     //std::vector<HYDROData_ShapeFile::DBF_AttrValue> myAttrV;
404     int Ind = myFieldList.indexOf(aPanel->getSelectedFieldName());
405     if (Ind == -1)
406     {
407       return;
408     }
409     //aPanel->setSecondPageState(true);
410     myAttrV.clear();
411     myImporter.DBF_GetAttributeList(Ind, myAttrV ); 
412
413     mySetOfAttrValues.clear();
414     for (size_t i = 0; i < myAttrV.size(); i++)
415     {
416       HYDROData_ShapeFile::DBF_AttrValue aV = myAttrV[i];
417       mySetOfAttrValues << QString(aV.myStrVal);  //take myStrVal by now..
418     }
419
420     //Collect all strickler_types
421     QSet<QString> aSTSet;
422     Handle_HYDROData_Document aDoc = HYDROData_Document::Document( application()->activeStudy()->id() );
423     if ( aDoc )
424     {
425       HYDROData_Iterator It( aDoc, KIND_STRICKLER_TABLE );
426       for( ; It.More(); It.Next() )
427       {
428         Handle(HYDROData_StricklerTable) aStricklerTableObj = Handle(HYDROData_StricklerTable)::DownCast( It.Current() );       
429         if ( !aStricklerTableObj.IsNull())
430         {
431           const QStringList& aStricklerList = aStricklerTableObj->GetTypes();
432           foreach (QString aStr, aStricklerList)
433             aSTSet << aStr;
434         }
435       }
436     }
437     aPanel->FillCorrTable(mySetOfAttrValues.toList(), aSTSet.toList());
438   }
439
440 }
441
442 void HYDROGUI_ImportLandCoverMapOp::onBack( const int theIndex )
443 {
444
445 }
446
447 void HYDROGUI_ImportLandCoverMapOp::onApply()
448 {
449
450   QApplication::setOverrideCursor( Qt::WaitCursor );
451   int anUpdateFlags = 0;
452   QString anErrorMsg;
453   QStringList aBrowseObjectsEntries;
454
455   bool aResult = false;
456   try
457   {
458     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
459   }
460   catch (...)
461   {
462     aResult = false;
463   }
464   
465   QApplication::restoreOverrideCursor();
466
467   if ( aResult )
468   {
469     module()->update( anUpdateFlags );
470     commit();
471     browseObjects( aBrowseObjectsEntries );
472   }
473   else
474   {
475     abort();
476   }
477 }
478