All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Plugin.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/plugins/datasource/ogr/Plugin.cpp
22 
23  \brief Plugin implementation for the OGR data source widget.
24 */
25 
26 // TerraLib
27 #include "../../../../common/Config.h"
28 #include "../../../../common/Translator.h"
29 #include "../../../../common/Logger.h"
30 #include "../../../../srs/Config.h"
31 #include "../../../../srs/SpatialReferenceSystemManager.h"
32 #include "../../../../dataaccess/dataset/DataSetType.h"
33 #include "../../../../dataaccess/datasource/DataSourceInfoManager.h"
34 #include "../../../../dataaccess/datasource/DataSourceManager.h"
35 #include "../../../../dataaccess/utils/Utils.h"
36 #include "../../../../maptools/AbstractLayer.h"
37 #include "../../../widgets/layer/utils/DataSet2Layer.h"
38 #include "../../../widgets/datasource/core/DataSourceTypeManager.h"
39 #include "../../../widgets/Utils.h"
40 #include "../../../af/ApplicationController.h"
41 #include "../../../af/Project.h"
42 #include "../../../af/Utils.h"
43 #include "../../../af/events/LayerEvents.h"
44 #include "OGRType.h"
45 #include "Plugin.h"
46 #include "Utils.h"
47 
48 // OGR
49 #include <ogrsf_frmts.h>
50 
51 // Boost
52 #include <boost/uuid/random_generator.hpp>
53 #include <boost/uuid/uuid_io.hpp>
54 #include <boost/filesystem.hpp>
55 
56 // Qt
57 #include <QFileInfo>
58 #include <QAction>
59 #include <QApplication>
60 #include <QFileDialog>
61 #include <QMenu>
62 #include <QMessageBox>
63 
64 std::list<te::da::DataSetTypePtr> GetDataSetsInfo(const te::da::DataSourceInfoPtr& info)
65 {
66  std::list<te::da::DataSetTypePtr> res;
67 
68  te::da::DataSourcePtr ds = te::da::DataSourceManager::getInstance().get(info->getId(), info->getType(), info->getConnInfo());
69  if (!ds->isOpened())
70  ds->open();
71 
72  std::vector<std::string> dsets = ds->getDataSetNames();
73 
74  std::vector<std::string>::iterator it;
75 
76  for(it = dsets.begin(); it != dsets.end(); ++it)
77  res.push_back(te::da::DataSetTypePtr(ds->getDataSetType(*it).release()));
78 
79  return res;
80 }
81 
82 void GetLayers(const te::da::DataSourceInfoPtr& info, std::list<te::map::AbstractLayerPtr>& layers)
83 {
84  std::list<te::map::AbstractLayerPtr> res;
85  std::list<te::da::DataSetTypePtr> dss = GetDataSetsInfo(info);
86 
87  std::transform(dss.begin(), dss.end(), std::back_inserter(layers), te::qt::widgets::DataSet2Layer(info->getId()));
88 }
89 
90 QString GetFileExtensionName(const std::string& type)
91 {
92  if(type.compare("ESRI Shapefile") == 0)
93  return QObject::tr("ESRI Shapefile (*.shp *.SHP)");
94  else if(type.compare("MapInfo File") == 0)
95  return QObject::tr("MapInfo File (*.mif *.MIF)");
96  else if(type.compare("DGN") == 0)
97  return QObject::tr("DGN File (*.dgn *.DGN)");
98 // else if(type.compare("CSV") == 0)
99 // return QObject::tr("CSV File (*.csv *.CSV)");
100  else if(type.compare("GML") == 0)
101  return QObject::tr("GML File (*.gml *.GML)");
102  else if(type.compare("KML") == 0)
103  return QObject::tr("KML File (*.kml *.KML)");
104  else if(type.compare("GeoJSON") == 0)
105  return QObject::tr("GeoJSON File (*.geojson *.GEOJSON)");
106  else if(type.compare("DXF") == 0)
107  return QObject::tr("DXF File (*.dxf *.DXF)");
108 
109  return "";
110 }
111 
113 {
114  QString res;
115  OGRSFDriverRegistrar* dMgr = OGRSFDriverRegistrar::GetRegistrar();
116 
117  int count = dMgr->GetDriverCount();
118 
119  for(int i=0; i<count; i++)
120  {
121  std::string dName = dMgr->GetDriver(i)->GetName();
122 
123  QString drv = GetFileExtensionName(dName);
124 
125  if(!drv.isEmpty())
126  res += drv + ";;";
127  }
128 
129  return res;
130 }
131 
133 QObject(),
134 te::plugin::Plugin(pluginInfo),
135 m_showWindow(0)
136 {
137 }
138 
140 {
141 }
142 
144 {
145  if(m_initialized)
146  return;
147 
149 
150  TE_LOG_TRACE(TE_TR("TerraLib Qt OGR widget startup!"));
151 
152  m_initialized = true;
153 
154  //Initializing action
155  QAction* act = te::qt::af::ApplicationController::getInstance().findAction("Project.Add Layer.Tabular File");
156  QMenu* mnu = te::qt::af::ApplicationController::getInstance().findMenu("Project.Add Layer");
157 
158  if(act != 0 && mnu != 0)
159  {
160  QWidget* parent = act->parentWidget();
161  m_showWindow = new QAction(QIcon::fromTheme("file-vector"), tr("Vector File..."), parent);
162  m_showWindow->setObjectName("Project.Add Layer.Vector File");
163  mnu->insertAction(act, m_showWindow);
164  //mnu->addAction(m_showWindow);
165 
167 
168  connect (m_showWindow, SIGNAL(triggered()), SLOT(showWindow()));
169  }
170 }
171 
173 {
174  if(!m_initialized)
175  return;
176 
177  te::da::DataSourceInfoManager::getInstance().removeByType("OGR");
179 
180  TE_LOG_TRACE(TE_TR("TerraLib Qt OGR widget shutdown!"));
181 
182  delete m_showWindow;
183 
184  m_initialized = false;
185 }
186 
188 {
189 // QString filter = GetSupportedFiles();
190 // QStringList fileNames = QFileDialog::getOpenFileNames(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Open Vector File"), te::qt::af::GetFilePathFromSettings("vector"), filter);
191 
192  QStringList fileNames = QFileDialog::getOpenFileNames(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Open Vector File"), te::qt::widgets::GetFilePathFromSettings("vector"), tr("Esri Shapefile (*.shp *.SHP);; Mapinfo File (*.mif *.MIF);; GeoJSON (*.geojson *.GeoJSON);; GML (*.gml *.GML);; KML (*.kml *.KML);; All Files (*.*)"));
193 
194  if(fileNames.isEmpty())
195  return;
196 
197  QApplication::setOverrideCursor(Qt::WaitCursor);
198 
199  QFileInfo info(fileNames.value(0));
200 
201  te::qt::widgets::AddFilePathToSettings(info.absolutePath(), "vector");
202 
203  // The selected shapefiles without spatial index
204  std::map<std::string, std::string> shpWithoutSpatialIndex;
205 
206  std::list<te::map::AbstractLayerPtr> layers;
207 
208  for(QStringList::iterator it = fileNames.begin(); it != fileNames.end(); ++it)
209  {
211 
212  ds->setAccessDriver("OGR");
213 
214  std::string fpath = it->toStdString();
215  std::map<std::string, std::string> dsinfo;
216  dsinfo["URI"] = fpath;
217 
218  ds->setConnInfo(dsinfo);
219 
220  std::string desc("A single vector file: ");
221  desc += fpath;
222  ds->setDescription(desc);
223 
224  boost::filesystem::path mpath(dsinfo["URI"]);
225 
226  std::string fileBaseName = mpath.leaf().string();
227 
228  ds->setTitle(fileBaseName);
229 
230  ds->setType("OGR");
231 
232  boost::uuids::basic_random_generator<boost::mt19937> gen;
233  boost::uuids::uuid u = gen();
234  std::string id = boost::uuids::to_string(u);
235 
236  ds->setId(id);
238 
239  if(IsShapeFile(*it) && !HasShapeFileSpatialIndex(*it))
240  {
241  QString datasetName(fileBaseName.c_str());
242  datasetName.remove(".shp", Qt::CaseInsensitive);
243  shpWithoutSpatialIndex[id] = datasetName.toStdString();
244  }
245 
246  GetLayers(ds, layers);
247  }
248 
249  QApplication::restoreOverrideCursor();
250 
251  if(!shpWithoutSpatialIndex.empty())
252  {
253  if(QMessageBox::question(te::qt::af::ApplicationController::getInstance().getMainWindow(),
254  tr("Spatial Index"), tr("Do you want create spatial index to the selected ESRI ShapeFiles?"),
255  QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
256  {
257  QApplication::setOverrideCursor(Qt::WaitCursor);
258 
259  std::map<std::string, std::string>::iterator it;
260  for(it = shpWithoutSpatialIndex.begin(); it != shpWithoutSpatialIndex.end(); ++it)
261  {
262  te::da::DataSourcePtr driver = te::da::GetDataSource(it->first, true);
263 
264  std::string command = "CREATE SPATIAL INDEX ON " + it->second;
265 
266  driver->execute(command);
267  }
268 
269  QApplication::restoreOverrideCursor();
270 
271  QMessageBox::information(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Spatial Index"), "Spatial index created with successfully!");
272  }
273  }
274 
275  // If there is only a parent folder layer that is selected, get it as the parent of the layer to be added;
276  // otherwise, add the layer as a top level layer
277  te::map::AbstractLayerPtr parentLayer(0);
278 
279  std::list<te::map::AbstractLayerPtr> selectedLayers = te::qt::af::ApplicationController::getInstance().getProject()->getSelectedLayers();
280 
281  if(selectedLayers.size() == 1 && selectedLayers.front()->getType() == "FOLDERLAYER")
282  parentLayer = selectedLayers.front();
283 
284  std::list<te::map::AbstractLayerPtr>::iterator it;
285  for(it = layers.begin(); it != layers.end(); ++it)
286  {
287  if ((*it)->getSRID() != TE_UNKNOWN_SRS)
288  {
289  if (!te::srs::SpatialReferenceSystemManager::getInstance().recognizes((*it)->getSRID()))
290  {
291  QString msgErr(tr("Layer %1 has SRID %2 that is not recognized by TerraLib. Setting it to unknown."));
292  msgErr = msgErr.arg((*it)->getTitle().c_str());
293  msgErr = msgErr.arg((*it)->getSRID());
294 
295  QMessageBox::warning(te::qt::af::ApplicationController::getInstance().getMainWindow(),
296  tr("Layer SRS check"), msgErr);
297  (*it)->setSRID(TE_UNKNOWN_SRS);
298  }
299  }
300 
301  te::qt::af::evt::LayerAdded evt(*it, parentLayer);
303  }
304 }
305 
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
Definition: Utils.cpp:262
#define TE_LOG_TRACE(msg)
Use this tag in order to log a message to a specified logger with the TRACE level.
Definition: Logger.h:137
This event signals that a new layer was created.
Definition: LayerEvents.h:66
Utility functions for the data access module.
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
TEQTWIDGETSEXPORT void AddFilePathToSettings(const QString &path, const QString &typeFile)
Save last used path in QSettings.
Definition: Utils.cpp:367
bool IsShapeFile(const QString &path)
Definition: Utils.cpp:36
OGR data source type.
void GetLayers(const te::da::DataSourceInfoPtr &info, std::list< te::map::AbstractLayerPtr > &layers)
Definition: Plugin.cpp:78
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
#define PLUGIN_CALL_BACK_IMPL(PLUGIN_CLASS_NAME)
This macro should be used by C++ plugins in order to declare the exportable/callable DLL function...
Definition: Config.h:57
TEQTAFEXPORT void AddActionToCustomToolbars(QAction *act)
Check QSettings for existance of act and adds it if necessary.
Definition: Utils.cpp:763
static DataSourceManager & getInstance()
It returns a reference to the singleton instance.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
~Plugin()
Virtual destructor.
Definition: Plugin.cpp:139
void shutdown()
Do nothing! Just set plugin as stopped.
Definition: Plugin.cpp:172
void startup()
Do nothing! Just set plugin as started.
Definition: Plugin.cpp:143
A class that represents a data source component.
QString GetSupportedFiles()
Definition: Plugin.cpp:112
TEQTWIDGETSEXPORT QString GetFilePathFromSettings(const QString &typeFile)
Returns the value of the last saved file path for the typeFile required.
Definition: Utils.cpp:376
The basic information about a plugin.
Definition: PluginInfo.h:61
QString GetFileExtensionName(const std::string &type)
Definition: Plugin.cpp:90
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
Plugin implementation for the OGR data source widget.
bool HasShapeFileSpatialIndex(const QString &path)
Definition: Utils.cpp:49
Plugin(const te::plugin::PluginInfo &pluginInfo)
Definition: Plugin.cpp:132
std::list< te::da::DataSetTypePtr > GetDataSetsInfo(const te::da::DataSourceInfoPtr &info)
Definition: Plugin.cpp:62
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr