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-2013 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 {
136 }
137 
139 {
140 }
141 
143 {
144  if(m_initialized)
145  return;
146 
148 
149  TE_LOG_TRACE(TE_TR("TerraLib Qt OGR widget startup!"));
150 
151  m_initialized = true;
152 
153  //Initializing action
154  QAction* act = te::qt::af::ApplicationController::getInstance().findAction("Project.Add Layer.Tabular File");
155  QMenu* mnu = te::qt::af::ApplicationController::getInstance().findMenu("Project.Add Layer");
156 
157  if(act != 0 && mnu != 0)
158  {
159  QWidget* parent = act->parentWidget();
160  m_showWindow = new QAction(QIcon::fromTheme("file-vector"), tr("Vector File..."), parent);
161  m_showWindow->setObjectName("Project.Add Layer.Vector File");
162  mnu->insertAction(act, m_showWindow);
163  //mnu->addAction(m_showWindow);
164 
166 
167  connect (m_showWindow, SIGNAL(triggered()), SLOT(showWindow()));
168  }
169 }
170 
172 {
173  if(!m_initialized)
174  return;
175 
176  te::da::DataSourceInfoManager::getInstance().removeByType("OGR");
178 
179  TE_LOG_TRACE(TE_TR("TerraLib Qt OGR widget shutdown!"));
180 
181  delete m_showWindow;
182 
183  m_initialized = false;
184 }
185 
187 {
188 // QString filter = GetSupportedFiles();
189 // QStringList fileNames = QFileDialog::getOpenFileNames(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Open Vector File"), te::qt::af::GetFilePathFromSettings("vector"), filter);
190 
191  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 (*.*)"));
192 
193  if(fileNames.isEmpty())
194  return;
195 
196  QFileInfo info(fileNames.value(0));
197 
198  te::qt::widgets::AddFilePathToSettings(info.absolutePath(), "vector");
199 
200  // The selected shapefiles without spatial index
201  std::map<std::string, std::string> shpWithoutSpatialIndex;
202 
203  std::list<te::map::AbstractLayerPtr> layers;
204 
205  for(QStringList::iterator it = fileNames.begin(); it != fileNames.end(); ++it)
206  {
208 
209  ds->setAccessDriver("OGR");
210 
211  std::string fpath = it->toStdString();
212  std::map<std::string, std::string> dsinfo;
213  dsinfo["URI"] = fpath;
214 
215  ds->setConnInfo(dsinfo);
216 
217  std::string desc("A single vector file: ");
218  desc += fpath;
219  ds->setDescription(desc);
220 
221  boost::filesystem::path mpath(dsinfo["URI"]);
222 
223  std::string fileBaseName = mpath.leaf().string();
224 
225  ds->setTitle(fileBaseName);
226 
227  ds->setType("OGR");
228 
229  boost::uuids::basic_random_generator<boost::mt19937> gen;
230  boost::uuids::uuid u = gen();
231  std::string id = boost::uuids::to_string(u);
232 
233  ds->setId(id);
235 
236  if(IsShapeFile(*it) && !HasShapeFileSpatialIndex(*it))
237  {
238  QString datasetName(fileBaseName.c_str());
239  datasetName.remove(".shp", Qt::CaseInsensitive);
240  shpWithoutSpatialIndex[id] = datasetName.toStdString();
241  }
242 
243  GetLayers(ds, layers);
244  }
245 
246  if(!shpWithoutSpatialIndex.empty())
247  {
248  if(QMessageBox::question(te::qt::af::ApplicationController::getInstance().getMainWindow(),
249  tr("Spatial Index"), tr("Do you want create spatial index to the selected ESRI ShapeFiles?"),
250  QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
251  {
252  QApplication::setOverrideCursor(Qt::WaitCursor);
253 
254  std::map<std::string, std::string>::iterator it;
255  for(it = shpWithoutSpatialIndex.begin(); it != shpWithoutSpatialIndex.end(); ++it)
256  {
257  te::da::DataSourcePtr driver = te::da::GetDataSource(it->first, true);
258 
259  std::string command = "CREATE SPATIAL INDEX ON " + it->second;
260 
261  driver->execute(command);
262  }
263 
264  QApplication::restoreOverrideCursor();
265 
266  QMessageBox::information(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Spatial Index"), "Spatial index created with successfully!");
267  }
268  }
269 
270  // If there is only a parent folder layer that is selected, get it as the parent of the layer to be added;
271  // otherwise, add the layer as a top level layer
272  te::map::AbstractLayerPtr parentLayer(0);
273 
274  std::list<te::map::AbstractLayerPtr> selectedLayers = te::qt::af::ApplicationController::getInstance().getProject()->getSelectedLayers();
275 
276  if(selectedLayers.size() == 1 && selectedLayers.front()->getType() == "FOLDERLAYER")
277  parentLayer = selectedLayers.front();
278 
279  std::list<te::map::AbstractLayerPtr>::iterator it;
280  for(it = layers.begin(); it != layers.end(); ++it)
281  {
282  if ((*it)->getSRID() != TE_UNKNOWN_SRS)
283  {
284  if (!te::srs::SpatialReferenceSystemManager::getInstance().recognizes((*it)->getSRID()))
285  {
286  QString msgErr(tr("Layer %1 has SRID %2 that is not recognized by TerraLib. Setting it to unknown."));
287  msgErr = msgErr.arg((*it)->getTitle().c_str());
288  msgErr = msgErr.arg((*it)->getSRID());
289 
290  QMessageBox::warning(te::qt::af::ApplicationController::getInstance().getMainWindow(),
291  tr("Layer SRS check"), msgErr);
292  (*it)->setSRID(TE_UNKNOWN_SRS);
293  }
294  }
295 
296  te::qt::af::evt::LayerAdded evt(*it, parentLayer);
298  }
299 }
300 
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:259
#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:136
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:351
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:74
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
#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:630
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:138
void shutdown()
Do nothing! Just set plugin as stopped.
Definition: Plugin.cpp:171
void startup()
Do nothing! Just set plugin as started.
Definition: Plugin.cpp:142
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:360
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:58
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr