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