Salome HOME
LCM // Import/Export of SHP p.2
[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.h>
67
68 HYDROGUI_ImportLandCoverMapOp::HYDROGUI_ImportLandCoverMapOp( HYDROGUI_Module* theModule )
69 : HYDROGUI_Operation( theModule )
70 {
71   setName( tr( "IMPORT_LANDCOVERMAP" ) );
72 }
73
74 HYDROGUI_ImportLandCoverMapOp::~HYDROGUI_ImportLandCoverMapOp()
75 {
76   erasePreview();
77 }
78
79 void HYDROGUI_ImportLandCoverMapOp::startOperation()
80 {
81   HYDROGUI_Operation::startOperation();
82
83   if ( !getPreviewManager() ) {
84     setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>( 
85                        module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
86   }
87
88   if ( !isApplyAndClose() ) {
89     return;
90   }
91
92   HYDROGUI_ImportLandCoverMapDlg* aPanel = 
93     ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
94   if ( !aPanel ) {
95     return;
96   }
97
98   aPanel->reset();
99 }
100
101 void HYDROGUI_ImportLandCoverMapOp::onFileSelected()
102 {
103   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
104   if ( !aPanel )
105     return;
106   
107   QString anObjectName = aPanel->getObjectName().simplified();
108   anObjectName = aPanel->getFileName();
109   if ( !anObjectName.isEmpty() ) 
110       anObjectName = QFileInfo( anObjectName ).baseName();
111
112   if ( anObjectName.isEmpty() ) 
113     anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_LANDCOVERMAP_NAME" ) );
114   aPanel->setObjectName( anObjectName );
115
116   myFileName = aPanel->getFileName();
117   if ( myFileName.isEmpty() )
118   {
119     abort();
120     return;
121   }
122
123   QString anExt = myFileName.split('.', QString::SkipEmptyParts).back();
124
125   if (anExt == "shp")
126   {     
127     startDocOperation();    
128     QApplication::setOverrideCursor(Qt::WaitCursor);
129     
130     QStringList aPolygonsList;
131     myPolygonFaces.Clear();
132     myImporter.Free();
133
134     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
135     if ( !aStudy )
136       return;
137
138     erasePreview();
139
140     Handle(AIS_InteractiveContext) aCtx = NULL;
141     int aShapeTypeOfFile = -1;
142
143     //Import polygons from SHP file as faces
144     //This faces should be added to the new LCM object
145
146     int aStat = myImporter.ImportPolygons(myFileName, aPolygonsList, myPolygonFaces, aShapeTypeOfFile);
147     if (aStat == 1)
148     {
149       aPanel->setPolygonNames(aPolygonsList);
150
151       LightApp_Application* anApp = module()->getApp();
152       if ( !getPreviewManager() )
153         setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>( anApp->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
154       OCCViewer_ViewManager* aViewManager = getPreviewManager();
155
156       if ( aViewManager )
157       {
158         if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
159         {
160           aCtx = aViewer->getAISContext();
161           connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
162         }
163       }
164
165       for ( int i = 1; i <= myPolygonFaces.Length(); i++ ) 
166       {
167         TopoDS_Face aFace = TopoDS::Face(myPolygonFaces.Value( i ));
168         if ( aViewManager && !aCtx.IsNull() )
169         {
170           HYDROGUI_Shape* aShape = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
171           //Green color for now..
172           aShape->setFillingColor(QColor(0,255,0), false, false);
173           aShape->setBorderColor(QColor(0,255,0), false, false);
174           if( !aFace.IsNull() )
175             aShape->setShape( aFace);
176
177           myPolygonName2PrsShape.insert( "polygon_" + QString::number(i), aShape);
178         }
179       }
180       if ( !aCtx.IsNull() ) 
181       {
182         UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, Graphic3d_ZLayerId_TopOSD );
183         aCtx->UpdateCurrentViewer();
184       }
185       //
186       QApplication::restoreOverrideCursor();
187       commitDocOperation();
188     }
189     else
190     {
191       erasePreview();
192       aPanel->setPolygonNames(QStringList());
193       aPanel->setObjectName("");
194       QApplication::restoreOverrideCursor();
195       QString aMess = "Cannot import land cover;\n";
196       if (aStat == -1)
197         aMess += "Cannot open SHP file";
198       else if (aStat == -2)
199         aMess += "Cannot open SHX file";
200       else 
201         aMess += "The shape type of file is " + myImporter.GetShapeTypeName(aShapeTypeOfFile);
202       SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "IMPORT_LANDCOVER" ), aMess);
203       commitDocOperation();
204       myImporter.Free();
205       //abort();
206     }
207     
208   }
209   
210 }
211
212 HYDROGUI_InputPanel* HYDROGUI_ImportLandCoverMapOp::createInputPanel() const
213 {
214   HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportLandCoverMapDlg( module(), getName() );
215
216   connect( aPanel, SIGNAL( FileSelected( const QString& ) ), SLOT( onFileSelected() ) );
217
218   connect( aPanel, SIGNAL( selectionChanged( const QStringList& ) ), this, SLOT( onSelectionChanged( const QStringList& ) ) );
219
220   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
221   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onBack( const int ) ) );
222   connect( aPanel, SIGNAL( Finish( const int ) ), SLOT( onFinish( const int ) ) );
223     
224   return aPanel;
225 }
226
227 bool HYDROGUI_ImportLandCoverMapOp::processApply( int& theUpdateFlags,
228                                                 QString& theErrorMsg,
229                                                 QStringList& theBrowseObjectsEntries )
230 {
231
232   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
233   if ( !aPanel ) {
234     return false;
235   }
236   
237   QStringList aSelectedtPolygons = aPanel->getSelectedPolygonNames();
238   aPanel->removePolygonNames( aSelectedtPolygons );
239     
240   if (!aSelectedtPolygons.empty())
241   {
242     Handle(HYDROData_LandCoverMap) aLCM =  Handle(HYDROData_LandCoverMap)::DownCast( doc()->CreateObject( KIND_LAND_COVER_MAP ) );
243     TopoDS_Shape aResShape;
244     if (aSelectedtPolygons.size() > 1) 
245     {
246       TopoDS_Compound cmp;
247       BRep_Builder BB;
248       BB.MakeCompound(cmp);
249
250       foreach ( QString aName, aSelectedtPolygons ) {
251         TopoDS_Shape aShape = myPolygonName2PrsShape.value( aName )->getTopoShape();
252         if ( aShape.IsNull() ) 
253           continue;
254         BB.Add(cmp, aShape);
255         HYDROGUI_Shape* aShapeToDelete = myPolygonName2PrsShape.take( aName );
256         delete aShapeToDelete;
257       }
258       aResShape = cmp;
259     }
260     else
261     {         
262       TopoDS_Shape aShape = myPolygonName2PrsShape.value( aSelectedtPolygons.first() )->getTopoShape();
263       if ( !aShape.IsNull() ) 
264       {
265         HYDROGUI_Shape* aShapeToDelete = myPolygonName2PrsShape.take( aSelectedtPolygons.first() );
266         delete aShapeToDelete;
267         aResShape = aShape;
268       }
269     }
270     if( !aLCM.IsNull() ) 
271     {
272       QString aLCName = aPanel->getObjectName() + "_polygon";
273       int i = 0;
274       for( ;HYDROGUI_Tool::FindObjectByName(module(), aLCName); i++)
275         aLCName = aPanel->getObjectName() + "_polygon_" + QString::number(i);
276       aLCM->SetName( aLCName );
277       //TODO add color
278       //aLCM->SetFillingColor( aLCM->DefaultFillingColor() );
279       //aLCM->SetBorderColor( aLCM->DefaultBorderColor() );
280       
281       //aLCM->SetShape(aResShape);
282       aLCM->Show();
283             
284       //erasePreview();
285       
286       module()->setIsToUpdate( aLCM );
287       
288     }
289   }
290  
291   module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init );
292
293   if ( isApplyAndClose() )
294     erasePreview();
295
296   myImporter.Free();
297
298   return true;
299 }
300
301 void HYDROGUI_ImportLandCoverMapOp::onSelectionChanged( const QStringList& theSelectedNames )
302 {
303   Handle(AIS_InteractiveContext) aCtx = NULL;
304
305   OCCViewer_ViewManager* aViewManager = getPreviewManager();
306   if ( aViewManager ) {
307     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
308       aCtx = aViewer->getAISContext();
309     }
310   }
311
312   if ( !aCtx.IsNull() ) {
313     foreach ( QString aName, myPolygonName2PrsShape.keys() ) {
314       Handle(AIS_InteractiveObject) anObject = 
315         myPolygonName2PrsShape.value(aName)->getAISObject();
316
317       bool isSelected = theSelectedNames.contains( aName );
318       if ( ( isSelected && !aCtx->IsSelected( anObject) ) ||
319            ( !isSelected && aCtx->IsSelected( anObject) ) ) {
320         aCtx->AddOrRemoveSelected( anObject, Standard_False );
321       }
322       /*if (isSelected)
323       {
324         HYDROGUI_Shape* aHydroSh = myPolygonName2PrsShape.value( aName );
325         aHydroSh->setFillingColor(QColor(0,255,255), true, true);
326       }*/
327     }
328     aCtx->UpdateCurrentViewer();
329   }
330 }
331
332
333 void HYDROGUI_ImportLandCoverMapOp::onViewerSelectionChanged()
334 {
335   // Get panel
336   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
337   if ( !aPanel ) {
338     return;
339   }
340
341   OCCViewer_ViewManager* aViewManager = getPreviewManager();
342   Handle(AIS_InteractiveContext) aCtx = NULL;
343   if ( aViewManager ) {
344     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
345       aCtx = aViewer->getAISContext();
346     }
347   }
348   
349   if ( !aCtx.IsNull() )
350   {
351     QStringList aSelectedNames;
352     foreach ( QString aName, myPolygonName2PrsShape.keys() ) {
353       bool isSelected = aCtx->IsSelected( myPolygonName2PrsShape.value(aName)->getAISObject() );
354       if ( isSelected ) {
355         aSelectedNames << aName;
356       }
357     }
358     aPanel->setSelectedPolygonNames( aSelectedNames );
359   }
360 }
361
362
363 void HYDROGUI_ImportLandCoverMapOp::erasePreview()
364 {
365   foreach ( HYDROGUI_Shape* aShape, myPolygonName2PrsShape ) {
366     delete aShape;
367   }
368
369   myPolygonName2PrsShape.clear();
370 }
371
372
373 void HYDROGUI_ImportLandCoverMapOp::abortOperation()
374 {
375   LightApp_Application* anApp = module()->getApp();
376   if ( anApp ) {
377     anApp->disconnect( this );
378   }
379
380   erasePreview();
381
382   HYDROGUI_Operation::abortOperation();
383 }
384
385
386 void HYDROGUI_ImportLandCoverMapOp::onNext( const int theIndex )
387 {  
388   //TODO add acceptor
389   HYDROGUI_ImportLandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_ImportLandCoverMapDlg*>( inputPanel() );
390   if ( !aPanel )
391     return;
392
393   if (theIndex == 1)
394   {
395       //Try to load DBF-database...
396       QString theDBFFileName;
397       theDBFFileName = myFileName.simplified().replace( ".shp", ".dbf", Qt::CaseInsensitive);
398       bool DBF_Stat = myImporter.DBF_OpenDBF(theDBFFileName);
399       // TODO:
400       // add MSG BOX if stat is bad
401       myFieldList = myImporter.DBF_GetFieldList();
402       aPanel->setAttributeNames(myFieldList);
403   }
404
405   if (theIndex == 2)
406   {
407     std::vector<HYDROData_ShapeFile::DBF_AttrValue> theAttrV;
408     int Ind = myFieldList.indexOf(aPanel->getSelectedFieldName());
409     if (Ind == -1)
410       return; //TODO add acceptor here!!
411     myImporter.DBF_GetAttributeList(Ind, theAttrV ); 
412
413     mySetOfAttrValues.clear();
414     for (size_t i = 0; i < theAttrV.size(); i++)
415     {
416       HYDROData_ShapeFile::DBF_AttrValue aV = theAttrV[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 }