BayesLocalDialog.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/sa/qt/BayesLocalDialog.cpp
22 
23  \brief A dialog to calculate the local empirical bayes of a dataset.
24 */
25 
26 // TerraLib
27 #include "../../core/logger/Logger.h"
28 #include "../../common/progress/ProgressManager.h"
29 #include "../../core/translator/Translator.h"
30 #include "../../common/STLUtils.h"
31 #include "../../dataaccess/datasource/DataSource.h"
32 #include "../../dataaccess/utils/Utils.h"
33 #include "../../geometry/GeometryProperty.h"
34 #include "../../maptools/DataSetLayer.h"
35 #include "../../qt/widgets/datasource/selector/DataSourceSelectorDialog.h"
36 #include "../../qt/widgets/progress/ProgressViewerDialog.h"
37 #include "../core/BayesLocalOperation.h"
38 #include "../core/BayesParams.h"
39 #include "../core/GPMBuilder.h"
40 #include "../core/GPMConstructorAdjacencyStrategy.h"
41 #include "../core/GPMWeightsNoWeightsStrategy.h"
42 #include "../core/SpatialWeightsExchanger.h"
43 #include "../core/Utils.h"
44 #include "../Exception.h"
45 #include "BayesLocalDialog.h"
46 #include "Utils.h"
47 #include "ui_BayesLocalDialogForm.h"
48 
49 // Qt
50 #include <QFileDialog>
51 #include <QFileInfo>
52 #include <QMessageBox>
53 #include <QValidator>
54 
55 // STL
56 #include <memory>
57 
58 // Boost
59 #include <boost/filesystem.hpp>
60 
62 
63 te::sa::BayesLocalDialog::BayesLocalDialog(QWidget* parent, Qt::WindowFlags f)
64  : QDialog(parent, f),
65  m_ui(new Ui::BayesLocalDialogForm)
66 {
67 // add controls
68  m_ui->setupUi(this);
69 
70  fillRateCorrection();
71 
72 // add icons
73  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("sa-bayeslocal-hint").pixmap(112,48));
74  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
75 
76 // connectors
77  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(int)), this, SLOT(onInputLayerComboBoxActivated(int)));
78  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
79  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
80  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
81  connect(m_ui->m_gpmToolButton, SIGNAL(clicked()), this, SLOT(onGPMToolButtonClicked()));
82 
83 // help info
84  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
85  m_ui->m_helpPushButton->setPageReference("plugins/sa/sa_bayeslocal.html");
86 }
87 
89 
90 void te::sa::BayesLocalDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
91 {
92  std::list<te::map::AbstractLayerPtr>::iterator it = layers.begin();
93 
94  while(it != layers.end())
95  {
97 
98  if(l->isValid())
99  {
100  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
101 
102  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
103 
104  if(dsLayer && dsType->hasGeom())
105  m_ui->m_inputLayerComboBox->addItem(it->get()->getTitle().c_str(), QVariant::fromValue(l));
106  }
107 
108  ++it;
109  }
110 
111 // fill attributes combo
112  if(m_ui->m_inputLayerComboBox->count() > 0)
114 }
115 
117 {
118  return m_outputLayer;
119 }
120 
122 {
123  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
124 
126 
127  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
128 
129  std::vector<te::dt::Property*> propVec = dsType->getProperties();
130 
131  m_ui->m_attrEventComboBox->clear();
132  m_ui->m_attrPopComboBox->clear();
133  m_ui->m_attrLinkComboBox->clear();
134 
135  for(std::size_t t = 0; t < propVec.size(); ++t)
136  {
137  int dataType = propVec[t]->getType();
138 
139  if (dataType == te::dt::INT16_TYPE || dataType == te::dt::UINT16_TYPE ||
140  dataType == te::dt::INT32_TYPE || dataType == te::dt::UINT32_TYPE ||
141  dataType == te::dt::INT64_TYPE || dataType == te::dt::UINT64_TYPE ||
142  dataType == te::dt::FLOAT_TYPE || dataType == te::dt::DOUBLE_TYPE)
143  {
144  m_ui->m_attrEventComboBox->addItem(propVec[t]->getName().c_str(), dataType);
145  m_ui->m_attrPopComboBox->addItem(propVec[t]->getName().c_str(), dataType);
146  }
147 
148  m_ui->m_attrLinkComboBox->addItem(propVec[t]->getName().c_str(), dataType);
149  }
150 }
151 
153 {
154  // check input parameters
155  if(m_ui->m_repositoryLineEdit->text().isEmpty())
156  {
157  QMessageBox::information(this, tr("Warning"), tr("Define a repository for the result."));
158  return;
159  }
160 
161  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
162  {
163  QMessageBox::information(this, tr("Warning"), tr("Define a name for the resulting layer."));
164  return;
165  }
166 
167  //get GPM
168  std::unique_ptr<te::sa::GeneralizedProximityMatrix> gpm;
169 
170  try
171  {
172  gpm = loadGPM();
173  }
174  catch(...)
175  {
176  QMessageBox::warning(this, tr("Warning"), tr("Internal error. GPM not loaded."));
177  return;
178  }
179 
180  if(!gpm.get())
181  return;
182 
183 //get selected layer
184  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(m_ui->m_inputLayerComboBox->currentIndex(), Qt::UserRole);
186 
187  std::unique_ptr<te::da::DataSetType> dataSetType = l->getSchema();
188  std::unique_ptr<te::da::DataSet> dataSet = l->getData();
189 
190 //create datasource to save the output information
191  std::string dataSetName = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
192 
193  std::size_t idx = dataSetName.find(".");
194  if (idx != std::string::npos)
195  dataSetName=dataSetName.substr(0,idx);
196 
197  te::da::DataSourcePtr outputDataSource;
198 
199  if(m_toFile)
200  {
201  outputDataSource = te::sa::CreateOGRDataSource(m_ui->m_repositoryLineEdit->text().toUtf8().data());
202  }
203  else
204  {
205  outputDataSource = te::da::GetDataSource(m_outputDatasource->getId());
206  }
207 
209 
210  inParams->m_ds = std::move(dataSet);
211  inParams->m_dsType = std::move(dataSetType);
212  inParams->m_eventAttrName = m_ui->m_attrEventComboBox->currentText().toUtf8().data();
213  inParams->m_populationAttrName = m_ui->m_attrPopComboBox->currentText().toUtf8().data();
214  inParams->m_rate = m_ui->m_rateComboBox->currentText().toDouble();
215  inParams->m_gpmAttrLink = gpm->getAttributeName();
216  inParams->m_gpm = std::move(gpm);
217 
219 
220  outParams->m_ds = outputDataSource;
221  outParams->m_outputDataSetName = dataSetName;
222 
223  //progress
225 
226  QApplication::setOverrideCursor(Qt::WaitCursor);
227 
228  try
229  {
231 
232  op.setParameters(inParams, outParams);
233 
234  op.execute();
235  }
236  catch(const std::exception& e)
237  {
238  QMessageBox::warning(this, tr("Warning"), e.what());
239 
240  QApplication::restoreOverrideCursor();
241 
242  return;
243  }
244  catch(...)
245  {
246  QMessageBox::warning(this, tr("Warning"), tr("Internal error. Global Bayes not calculated."));
247 
248  QApplication::restoreOverrideCursor();
249 
250  return;
251  }
252 
253  QApplication::restoreOverrideCursor();
254 
255  //create layer
256  m_outputLayer = te::sa::CreateLayer(outputDataSource, dataSetName);
257 
258  //create legend
260 
261  accept();
262 }
263 
265 {
266  m_ui->m_newLayerNameLineEdit->clear();
267  m_ui->m_newLayerNameLineEdit->setEnabled(true);
268 
270  dlg.exec();
271 
272  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
273 
274  if(dsPtrList.empty())
275  return;
276 
277  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
278 
279  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
280 
281  m_outputDatasource = *it;
282 
283  m_toFile = false;
284 }
285 
287 {
288  m_ui->m_newLayerNameLineEdit->clear();
289  m_ui->m_repositoryLineEdit->clear();
290 
291  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."), QString(), tr("Shapefile (*.shp *.SHP);;"),nullptr, QFileDialog::DontConfirmOverwrite);
292 
293  if (fileName.isEmpty())
294  return;
295 
296  boost::filesystem::path outfile(fileName.toUtf8().data());
297 
298  m_ui->m_repositoryLineEdit->setText(outfile.string().c_str());
299 
300  m_ui->m_newLayerNameLineEdit->setText(outfile.leaf().string().c_str());
301 
302  m_ui->m_newLayerNameLineEdit->setEnabled(false);
303 
304  m_toFile = true;
305 }
306 
308 {
309  QString fileName = QFileDialog::getOpenFileName(this, tr("Open Generalized Proximity Matrix File"), "", tr("GAL Files (*.gal *.GAL);; GWT Files (*.gwt *.GWT)"));
310 
311  if(fileName.isEmpty())
312  return;
313 
314  //get selected layer
315  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(m_ui->m_inputLayerComboBox->currentIndex(), Qt::UserRole);
317  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
318 
319  //check if the selected gpm is valid for selected layer
320  std::string path = fileName.toUtf8().data();
321  std::string dataSetName;
322  std::string attrName;
323 
325 
326  if(dsLayer->getDataSetName() != dataSetName)
327  {
328  QMessageBox::warning(this, tr("Warning"), tr("Invalid GPM file for selected layer."));
329  return;
330  }
331 
332  if(m_ui->m_attrLinkComboBox->currentText().toUtf8().data() != attrName)
333  {
334  QMessageBox::warning(this, tr("Warning"), tr("Invalid GPM file for selected Attr Link."));
335  return;
336  }
337 
338  m_ui->m_gpmLineEdit->setText(fileName);
339 }
340 
342 {
343  m_ui->m_rateComboBox->clear();
344 
345  m_ui->m_rateComboBox->addItem("1");
346  m_ui->m_rateComboBox->addItem("10");
347  m_ui->m_rateComboBox->addItem("100");
348  m_ui->m_rateComboBox->addItem("1000");
349  m_ui->m_rateComboBox->addItem("10000");
350  m_ui->m_rateComboBox->addItem("100000");
351 }
352 
353 std::unique_ptr<te::sa::GeneralizedProximityMatrix> te::sa::BayesLocalDialog::loadGPM()
354 {
355  std::unique_ptr<te::sa::GeneralizedProximityMatrix> gpm;
356 
357  //get selected layer
358  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(m_ui->m_inputLayerComboBox->currentIndex(), Qt::UserRole);
360 
361  if(!l.get())
362  {
363  QMessageBox::warning(this, tr("Warning"), tr("Invalid selected layer."));
364  return gpm;
365  }
366 
367  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
368 
369  //get gpm necessary parameters
371 
372  std::string dataSetName = dsLayer->getDataSetName();
373 
374  if(!m_ui->m_gpmGroupBox->isChecked())
375  {
376  //create gpm
377  if(QMessageBox::question(this, tr("Spatial Analysis"), tr("GPM not selected. Create default GPM?"), QMessageBox::No, QMessageBox::Yes) == QMessageBox::No)
378  return gpm;
379 
380  //get attrlink
381  std::unique_ptr<te::da::DataSetType> dsType = dsLayer->getSchema();
382 
383  if(!dsType->getPrimaryKey() || dsType->getPrimaryKey()->getProperties().empty())
384  {
385  QMessageBox::warning(this, tr("Warning"), tr("Invalid Data Set Primary Key."));
386  return gpm;
387  }
388 
389  std::string attrLink = dsType->getPrimaryKey()->getProperties()[0]->getName();
390 
391  //create default gpm
394 
395  te::sa::GPMBuilder builder(constructor, weights);
396 
397  builder.setGPMInfo(ds, dataSetName, attrLink);
398 
399  builder.build();
400  gpm.reset(builder.getGPM());
401  }
402  else
403  {
404  if(m_ui->m_gpmLineEdit->text().isEmpty())
405  {
406  QMessageBox::warning(this, tr("Warning"), tr("GPM File not selected."));
407  return gpm;
408  }
409 
410  //load gpm
411  QFileInfo file(m_ui->m_gpmLineEdit->text());
412 
413  std::string extension = file.suffix().toUtf8().data();
414 
416 
417  if(extension == "gal" || extension == "GAL")
418  {
419  gpm.reset(swe.importFromGAL(m_ui->m_gpmLineEdit->text().toUtf8().data(), ds.get()));
420  }
421  else if(extension == "gwt" || extension == "GWT")
422  {
423  gpm.reset(swe.importFromGWT(m_ui->m_gpmLineEdit->text().toUtf8().data(), ds.get()));
424  }
425  }
426 
427  return gpm;
428 }
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
This class defines a an adjacency strategy class for a GPM constructor.
GeneralizedProximityMatrix * getGPM()
Function used to return the generated gpm.
Definition: GPMBuilder.cpp:91
Class that represents the Bayes output parameters.
Definition: BayesParams.h:94
boost::shared_ptr< DataSource > DataSourcePtr
TESAEXPORT te::da::DataSourcePtr CreateOGRDataSource(std::string repository)
bool setGPMInfo(te::da::DataSourcePtr ds, const std::string &dataSetName, const std::string &attributeName)
Function used to create an empty gpm (using a MEMORY DIRECT graph)
Definition: GPMBuilder.cpp:49
This class defines a class to calculates a weight for a GPM using No Weights strategy.
std::unique_ptr< LayerSchema > getSchema() const
It returns the layer schema.
static te::dt::Date ds(2010, 01, 01)
te::sa::GeneralizedProximityMatrix * importFromGAL(std::string pathFileName, te::da::DataSource *ds=0)
Function used to import a gpm from a Spatial Weights File GAL Format.
te::sa::GeneralizedProximityMatrix * importFromGWT(std::string pathFileName, te::da::DataSource *ds=0)
Function used to import a gpm from a Spatial Weights File GWT Format.
std::string m_outputDataSetName
Attribute that defines the output dataset name.
Definition: BayesParams.h:113
TESAEXPORT void CreateBayesGrouping(te::map::AbstractLayerPtr layer)
std::unique_ptr< te::sa::GeneralizedProximityMatrix > loadGPM()
URI C++ Library.
Definition: Attributes.h:37
void onInputLayerComboBoxActivated(int index)
te::map::AbstractLayerPtr m_outputLayer
Generated Layer.
static void getSpatialWeightsFileInfo(std::string pathFileName, std::string &dataSetName, std::string &attrName)
Function used to get information of how a Spatial Weights was generated.
Utility functions for the data access module.
std::unique_ptr< Ui::BayesLocalDialogForm > m_ui
te::da::DataSourcePtr m_ds
Pointer to the output datasource.
Definition: BayesParams.h:111
This class defines a an Abstract class for a GPM constructor.
This class defines a an Abstract class to calculates a weight for a GPM.
const std::string & getDataSetName() const
Class that represents the Bayes input parameters.
Definition: BayesParams.h:56
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
TESAEXPORT te::map::AbstractLayerPtr CreateLayer(te::da::DataSourcePtr ds, std::string dataSetName)
A dialog for selecting a data source.
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
te::map::AbstractLayerPtr getOutputLayer()
This class defines functions used to load and save gpm&#39;s using GAL and GWT formats, both formats use a &#39; &#39; as separator.
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
This class defines the GPM Builder class.
Definition: GPMBuilder.h:54
A dialog to calculate the local empirical bayes of a dataset.
void setParameters(te::sa::BayesInputParams *inParams, te::sa::BayesOutputParams *outParams)
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
te::da::DataSourceInfoPtr m_outputDatasource
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
virtual const std::string & getDataSourceId() const
file(WRITE ${CMAKE_BINARY_DIR}/config_qhelp.cmake"configure_file (${TERRALIB_ABSOLUTE_ROOT_DIR}/doc/qhelp/help.qhcp.in ${CMAKE_BINARY_DIR}/share/terraview/help/help.qhcp @ONLY)") add_custom_command(OUTPUT del_dir COMMAND $
void execute()
Function to execute the bayes operation.