gdal/GeoFileDragAndDropHandler.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/widgets/utils/GeoFileDragAndDropHandler.h
22 
23 \brief A class used to handle geofile drag and drop events.
24 */
25 
26 #include "../../../widgets/layer/explorer/LayerItemView.h"
28 #include "Utils.h"
29 
30 // Terralib
31 #include "../../../../dataaccess/datasource/DataSource.h"
32 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
33 #include "../../../../maptools/Utils.h"
34 #include "../../../widgets/canvas/MultiThreadMapDisplay.h"
35 #include "../../../af/events/MapEvents.h"
36 
37 // Qt
38 #include <QDragEnterEvent>
39 #include <QEvent>
40 #include <QMimeData>
41 #include <QUrl>
42 
43 bool IsSupported(const std::string& fileName)
44 {
45  std::string connInfo("file://" + fileName);
46 
47  std::unique_ptr<te::da::DataSource> ds(te::da::DataSourceFactory::make("GDAL", connInfo));
48 
49  try
50  {
51  ds->open();
52 
54 
55  std::vector<std::string> dsets = ds->getDataSetNames();
56 
57  if (dsets.size() == 0)
58  return false;
59 
60  dsType = ds->getDataSetType(dsets[0]);
61 
62  if (dsType.get() == nullptr)
63  return false;
64  }
65  catch (const std::exception&)
66  {
67  return false;
68  }
69  catch (...)
70  {
71  return false;
72  }
73 
74  return true;
75 }
76 
78  QObject(parent),
79  m_isValid(false)
80 {
81 
82 }
83 
85  default;
86 
88 {
89  if (e->type() == QEvent::DragEnter)
90  {
91  QDragEnterEvent* dragEvent = dynamic_cast<QDragEnterEvent*>(e);
92  dragEvent->setDropAction(Qt::DropAction::LinkAction);
93 
94  const QMimeData* mimeData = dragEvent->mimeData();
95 
96  QList<QUrl> urlList = mimeData->urls();
97 
98  m_isValid = false;
99 
100  // extract the local paths of the files
101  for (int i = 0; i < urlList.size(); ++i)
102  {
103  std::string fileName = urlList.at(i).toLocalFile().toUtf8().constData();
104 
105  if (IsSupported(fileName))
106  {
107  m_isValid = true;
108  break;
109  }
110  }
111 
112  if (m_isValid)
113  {
114  dragEvent->accept();
115  return true;
116  }
117  else
118  {
119  return QObject::eventFilter(watched, e);
120  }
121  }
122  else if (e->type() == QEvent::Drop && m_isValid)
123  {
124  QDropEvent* dropEvent = dynamic_cast<QDropEvent*>(e);
125 
126  const QMimeData* mimeData = dropEvent->mimeData();
127 
128  QStringList pathList;
129  QList<QUrl> urlList = mimeData->urls();
130 
131  // extract the local paths of the files
132  for (int i = 0; i < urlList.size(); ++i)
133  {
134  pathList.append(urlList.at(i).toLocalFile());
135  }
136 
137  std::list<te::map::AbstractLayerPtr> layers;
138 
139  te::qt::plugins::gdal::CreateLayers(pathList, layers);
140 
142 
143  if (mtmd)
144  {
145  std::list<te::map::AbstractLayerPtr> curList = mtmd->getLayerList();
146  std::list<te::map::AbstractLayerPtr>::const_iterator it = layers.begin();
147 
148  while (it != layers.end())
149  {
150  (*it)->setVisibility(te::map::VISIBLE);
151 
152  curList.push_back(*it);
153 
154  ++it;
155  }
156 
157  if (mtmd->getSRID() == TE_UNKNOWN_SRS)
158  {
159  configSRS(curList, mtmd);
160  }
161 
162  te::gm::Envelope displayExtent = te::map::GetExtent(curList, mtmd->getSRID(), true);
163  mtmd->setExtent(displayExtent, false);
164 
165  mtmd->setLayerList(curList);
166  mtmd->refresh(true);
167  }
168 
169  return true;
170  }
171 
172  return QObject::eventFilter(watched, e);
173 }
174 
175 void te::qt::plugins::gdal::GeoFileDragAndDropHandler::configSRS(const std::list<te::map::AbstractLayerPtr>& layers, te::qt::widgets::MapDisplay* mapDisplay)
176 {
177  if (layers.size() == 1 && (*layers.begin())->getSRID() == TE_UNKNOWN_SRS && mapDisplay->getSRID() != TE_UNKNOWN_SRS)
178  {
179  const te::map::AbstractLayerPtr& layer = *layers.begin();
180 
181  mapDisplay->setSRID(TE_UNKNOWN_SRS, false);
182 
183  std::pair<int, std::string> srid(layer->getSRID(), "EPSG");
184  te::qt::af::evt::MapSRIDChanged mapSRIDChanged(srid);
185  emit triggered(&mapSRIDChanged);
186  }
187  else if (mapDisplay->getSRID() == TE_UNKNOWN_SRS)
188  {
189  std::list<te::map::AbstractLayerPtr>::const_iterator it;
190 
191  for (it = layers.begin(); it != layers.end(); ++it)
192  {
193  const te::map::AbstractLayerPtr& layer = *it;
194 
195  if (layer->getSRID() == TE_UNKNOWN_SRS)
196  continue;
197 
198  mapDisplay->setSRID(layer->getSRID(), false);
199 
200  std::pair<int, std::string> srid(layer->getSRID(), "EPSG");
201 
202  te::qt::af::evt::MapSRIDChanged mapSRIDChanged(srid);
203  emit triggered(&mapSRIDChanged);
204 
205  break;
206  }
207  }
208 }
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
void CreateLayers(QStringList fileNames, std::list< te::map::AbstractLayerPtr > &layers)
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
TEMAPEXPORT te::gm::Envelope GetExtent(const std::list< te::map::AbstractLayerPtr > &layers, int srid, bool onlyVisibles)
It calculates the extent of the given layers in the given SRID.
virtual std::list< AbstractLayerPtr > getLayerList() const
void refresh(bool redraw=false)
It updates the contents in the map display.
This event signals that the srid of the map display changed.
Definition: MapEvents.h:54
void setExtent(te::gm::Envelope &e, bool doRefresh=true)
It sets the world visible area and refreshes the contents in the map display.
A widget to control the display of a set of layers.
static te::dt::Date ds(2010, 01, 01)
void setLayerList(const std::list< te::map::AbstractLayerPtr > &layers)
An Envelope defines a 2D rectangular region.
virtual int getSRID() const
It return the Spatial Reference System used by the Map Display.
bool IsSupported(const std::string &fileName)
void triggered(te::qt::af::evt::Event *e)
void configSRS(const std::list< te::map::AbstractLayerPtr > &layers, te::qt::widgets::MapDisplay *mapDisplay)
Utility functions for MapTools module.
virtual void setSRID(const int &srid, bool doRefresh=true)
It sets a new Spatial Reference System to be used by the Map Display.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
A multi thread Qt4 widget to control the display of a set of layers.