All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 <QtCore/QFileInfo>
58 #include <QtGui/QAction>
59 #include <QtGui/QApplication>
60 #include <QtGui/QFileDialog>
61 #include <QtGui/QMenu>
62 #include <QtGui/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 // it initializes the Translator support for the TerraLib PostGIS driver support
151 
152  TE_LOG_TRACE(TE_QT_PLUGIN_DATASOURCE_OGR("TerraLib Qt OGR widget startup!"));
153 
154  m_initialized = true;
155 
156  //Initializing action
157  QAction* act = te::qt::af::ApplicationController::getInstance().findAction("Project.Add Layer.Tabular File");
158  QMenu* mnu = te::qt::af::ApplicationController::getInstance().findMenu("Project.Add Layer");
159 
160  if(act != 0 && mnu != 0)
161  {
162  QWidget* parent = act->parentWidget();
163  m_showWindow = new QAction(QIcon::fromTheme("file-vector"), tr("Vector File..."), parent);
164  m_showWindow->setObjectName("Project.Add Layer.Vector File");
165  mnu->insertAction(act, m_showWindow);
166  //mnu->addAction(m_showWindow);
167 
169 
170  connect (m_showWindow, SIGNAL(triggered()), SLOT(showWindow()));
171  }
172 }
173 
175 {
176  if(!m_initialized)
177  return;
178 
179  te::da::DataSourceInfoManager::getInstance().removeByType("OGR");
181 
182  TE_LOG_TRACE(TE_QT_PLUGIN_DATASOURCE_OGR("TerraLib Qt OGR widget shutdown!"));
183 
184  delete m_showWindow;
185 
186  m_initialized = false;
187 }
188 
190 {
191 // QString filter = GetSupportedFiles();
192 // QStringList fileNames = QFileDialog::getOpenFileNames(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Open Vector File"), te::qt::af::GetFilePathFromSettings("vector"), filter);
193 
194  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 (*.*)"));
195 
196  if(fileNames.isEmpty())
197  return;
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  if(!shpWithoutSpatialIndex.empty())
250  {
251  if(QMessageBox::question(te::qt::af::ApplicationController::getInstance().getMainWindow(),
252  tr("Spatial Index"), tr("Do you want create spatial index to the selected ESRI ShapeFiles?"),
253  QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
254  {
255  QApplication::setOverrideCursor(Qt::WaitCursor);
256 
257  std::map<std::string, std::string>::iterator it;
258  for(it = shpWithoutSpatialIndex.begin(); it != shpWithoutSpatialIndex.end(); ++it)
259  {
260  te::da::DataSourcePtr driver = te::da::GetDataSource(it->first, true);
261 
262  std::string command = "CREATE SPATIAL INDEX ON " + it->second;
263 
264  driver->execute(command);
265  }
266 
267  QApplication::restoreOverrideCursor();
268 
269  QMessageBox::information(te::qt::af::ApplicationController::getInstance().getMainWindow(), tr("Spatial Index"), "Spatial index created with successfully!");
270  }
271  }
272 
273  // If there is only a parent folder layer that is selected, get it as the parent of the layer to be added;
274  // otherwise, add the layer as a top level layer
275  te::map::AbstractLayerPtr parentLayer(0);
276 
277  std::list<te::map::AbstractLayerPtr> selectedLayers = te::qt::af::ApplicationController::getInstance().getProject()->getSelectedLayers();
278 
279  if(selectedLayers.size() == 1 && selectedLayers.front()->getType() == "FOLDERLAYER")
280  parentLayer = selectedLayers.front();
281 
282  std::list<te::map::AbstractLayerPtr>::iterator it;
283  for(it = layers.begin(); it != layers.end(); ++it)
284  {
285  if ((*it)->getSRID() != TE_UNKNOWN_SRS)
286  {
287  if (!te::srs::SpatialReferenceSystemManager::getInstance().recognizes((*it)->getSRID()))
288  {
289  QString msgErr(tr("Layer %1 has SRID %2 that is not recognized by TerraLib. Setting it to unknown."));
290  msgErr = msgErr.arg((*it)->getTitle().c_str());
291  msgErr = msgErr.arg((*it)->getSRID());
292 
293  QMessageBox::warning(te::qt::af::ApplicationController::getInstance().getMainWindow(),
294  tr("Layer SRS check"), msgErr);
295  (*it)->setSRID(TE_UNKNOWN_SRS);
296  }
297  }
298 
299  te::qt::af::evt::LayerAdded evt(*it, parentLayer);
301  }
302 }
303 
The basic information about a plugin.
Definition: PluginInfo.h:61
QMenu * findMenu(const QString &id) const
Returns the menu registered with key id.
#define TE_QT_PLUGIN_DATASOURCE_OGR_TEXT_DOMAIN
It contains the name of the text domain used in the translation of messages in TerraLib OGR driver im...
Definition: Config.h:39
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:258
std::list< te::da::DataSetTypePtr > GetDataSetsInfo(const te::da::DataSourceInfoPtr &info)
Definition: Plugin.cpp:58
TEQTWIDGETSEXPORT QString GetFilePathFromSettings(const QString &typeFile)
Returns the value of the last saved file path for the typeFile required.
Definition: Utils.cpp:360
A class that represents a data source component.
TEQTWIDGETSEXPORT void AddFilePathToSettings(const QString &path, const QString &typeFile)
Save last used path in QSettings.
Definition: Utils.cpp:351
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:72
Plugin implementation for the OGR data source widget.
static ApplicationController & getInstance()
It gives access to the controller singleton.
Plugin(const te::plugin::PluginInfo &pluginInfo)
Definition: Plugin.cpp:132
#define TE_LOG_TRACE(msg)
Use this tag in order to log a message to a specified logger with the TRACE level.
Definition: Config.h:418
OGR data source type.
void shutdown()
Do nothing! Just set plugin as stopped.
Definition: Plugin.cpp:174
This event signals that a new layer was created.
Definition: LayerEvents.h:61
bool HasShapeFileSpatialIndex(const QString &path)
Definition: Utils.cpp:49
#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
Utility functions for the data access module.
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1395
void GetLayers(const te::da::DataSourceInfoPtr &info, std::list< te::map::AbstractLayerPtr > &layers)
Definition: Plugin.cpp:74
#define TE_ADD_TEXT_DOMAIN(domain, domaindir, codeset)
It adds the given text domain located at domain-dir with the given codeset to the multilingual system...
Definition: Config.h:118
#define TE_QT_PLUGIN_DATASOURCE_OGR_TEXT_DOMAIN_DIR
It contains the translation catalog directory.
Definition: Config.h:46
bool IsShapeFile(const QString &path)
Definition: Utils.cpp:36
QString GetSupportedFiles()
Definition: Plugin.cpp:112
#define TE_QT_PLUGIN_DATASOURCE_OGR(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
Definition: Config.h:53
void startup()
Do nothing! Just set plugin as started.
Definition: Plugin.cpp:142
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
QString GetFileExtensionName(const std::string &type)
Definition: Plugin.cpp:90
static DataSourceManager & getInstance()
It returns a reference to the singleton instance.
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
~Plugin()
Virtual destructor.
Definition: Plugin.cpp:138
void broadcast(te::qt::af::evt::Event *evt)
Send events in broadcast for all registered components.
QAction * findAction(const QString &id) const
Returns the action identified by id or NULL if there&#39;s not an action identified by id...
te::qt::af::Project * getProject()
Get the current project.
TEQTAFEXPORT void AddActionToCustomToolbars(QAction *act)
Check QSettings for existance of act and adds it if necessary.
Definition: Utils.cpp:651
const std::list< te::map::AbstractLayerPtr > getSelectedLayers() const
It gets all the layers that are selected.
Definition: Project.cpp:144