GeostatisticalMethodsDialog.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/GeostatisticalMethodsDialog.cpp
22 
23  \brief A dialog with geostatistical methods to measure the spatial variability of attribute 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/dataset/DataSet.h"
32 #include "../../dataaccess/utils/Utils.h"
33 #include "../../geometry/GeometryProperty.h"
34 #include "../core/GeostatisticalFunctions.h"
35 #include "../core/GeostatisticalMethodSemivariogram.h"
36 #include "../core/GeostatisticalModel.h"
37 #include "../core/GeostatisticalModelExponential.h"
38 #include "../core/GeostatisticalModelGaussian.h"
39 #include "../core/GeostatisticalModelSpherical.h"
40 #include "../core/Utils.h"
41 #include "../Enums.h"
42 #include "../Exception.h"
44 #include "ui_GeostatisticalMethodsDialogForm.h"
45 
46 // Qt
47 #include <QGridLayout>
48 #include <QMessageBox>
49 #include <QValidator>
50 
51 //QWT
52 #include <qwt_legend.h>
53 #include <qwt_plot.h>
54 #include <qwt_symbol.h>
55 
56 // STL
57 #include <memory>
58 
60 
61 te::sa::GeostatisticalMethodsDialog::GeostatisticalMethodsDialog(QWidget* parent, Qt::WindowFlags f)
62  : QDialog(parent, f),
63  m_ui(new Ui::GeostatisticalMethodsDialogForm),
64  m_method(nullptr)
65 {
66 // add controls
67  m_ui->setupUi(this);
68 
69  m_ui->m_nLagsLineEdit->setValidator(new QIntValidator(this));
70  m_ui->m_lagsIncrementLineEdit->setValidator(new QDoubleValidator(this));
71  m_ui->m_angleDirLineEdit->setValidator(new QDoubleValidator(this));
72  m_ui->m_angleTolLineEdit->setValidator(new QDoubleValidator(this));
73 
74  m_ui->m_adjustGroupBox->setEnabled(false);
75  m_ui->m_changeAttrToolButton->setEnabled(false);
76 
77  fillParameters();
78 
79 // add icons
80  m_ui->m_imgLabel->setPixmap(QIcon::fromTheme("sa-measurespatialvar-hint").pixmap(112,48));
81  m_ui->m_changeAttrToolButton->setIcon(QIcon::fromTheme("view-refresh"));
82 
83 // connectors
84  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(int)), this, SLOT(onInputLayerComboBoxActivated(int)));
85  connect(m_ui->m_changeAttrToolButton, SIGNAL(clicked()), this, SLOT(onChangeAttrToolButtonClicked()));
86  connect(m_ui->m_applyPushButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
87  connect(m_ui->m_modelComboBox, SIGNAL(activated(int)), this, SLOT(calculate()));
88  connect(m_ui->m_nuggetHorizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(calculate()));
89  connect(m_ui->m_sillHorizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(calculate()));
90  connect(m_ui->m_rangeHorizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(calculate()));
91 
92  //create chart
93  QGridLayout* chartLayout = new QGridLayout(m_ui->m_chartWidget);
94  m_chartDisplay = new te::qt::widgets::ChartDisplay(m_ui->m_chartWidget);
95  chartLayout->addWidget(m_chartDisplay);
96 
97 
98  m_chartDisplay->setAxisTitle(QwtPlot::xBottom, tr("h"));
99  m_chartDisplay->setAxisTitle(QwtPlot::yLeft, tr("Y(h)"));
100 
101  //start plot objects
102  m_scatterMethod = new te::qt::widgets::Scatter();
103  m_scatterChartMethod = new te::qt::widgets::ScatterChart(m_scatterMethod);
104  m_scatterChartMethod->setSymbol(new QwtSymbol( QwtSymbol::XCross, QBrush( Qt::red ), QPen( Qt::red, 3 ), QSize( 8, 8 )));
105  m_scatterChartMethod->attach(m_chartDisplay);
106  m_scatterChartMethod->setTitle(tr("Data"));
107 
108  m_scatterModel = new te::qt::widgets::Scatter();
109  m_scatterChartModel = new te::qt::widgets::ScatterChart(m_scatterModel);
110  m_scatterChartModel->setPen(Qt::blue);
111  m_scatterChartModel->setSymbol(nullptr);
112  m_scatterChartModel->setStyle(QwtPlotCurve::Lines);
113  m_scatterChartModel->attach(m_chartDisplay);
114  m_scatterChartModel->setTitle(tr("Model"));
115 
116  m_chartDisplay->insertLegend(new QwtLegend(), QwtPlot::RightLegend);
117 
118  // help info
119  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
120  m_ui->m_helpPushButton->setPageReference("plugins/sa/sa_geostatisticalmethods.html");
121 }
122 
124 {
125  delete m_method;
126 
127  m_methodMatrix.clear();
128 
129  m_modelMatrix.clear();
130 }
131 
132 void te::sa::GeostatisticalMethodsDialog::setLayers(std::list<te::map::AbstractLayerPtr> layers)
133 {
134  std::list<te::map::AbstractLayerPtr>::iterator it = layers.begin();
135 
136  while(it != layers.end())
137  {
139 
140  if(l->isValid())
141  {
142  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
143 
144  if (dsType->hasGeom())
145  m_ui->m_inputLayerComboBox->addItem(it->get()->getTitle().c_str(), QVariant::fromValue(l));
146  }
147 
148  ++it;
149  }
150 
151 // fill attributes combo
152  if(m_ui->m_inputLayerComboBox->count() > 0)
154 }
155 
157 {
158  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
159 
161 
162  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
163 
164  std::vector<te::dt::Property*> propVec = dsType->getProperties();
165 
166  m_ui->m_attributeComboBox->clear();
167 
168  for(std::size_t t = 0; t < propVec.size(); ++t)
169  {
170  int dataType = propVec[t]->getType();
171 
172  if (dataType == te::dt::INT16_TYPE || dataType == te::dt::UINT16_TYPE ||
173  dataType == te::dt::INT32_TYPE || dataType == te::dt::UINT32_TYPE ||
174  dataType == te::dt::INT64_TYPE || dataType == te::dt::UINT64_TYPE ||
175  dataType == te::dt::FLOAT_TYPE || dataType == te::dt::DOUBLE_TYPE)
176  {
177  m_ui->m_attributeComboBox->addItem(propVec[t]->getName().c_str(), dataType);
178  }
179  }
180 
181  //reset lag increment information
182  std::unique_ptr<te::da::DataSet> ds = l->getData();
183  double lagIncrement = l->getExtent().getWidth() / ds->size();
184 
185  QString strLagIncrement;
186  strLagIncrement.setNum(lagIncrement);
187 
188  m_ui->m_lagsIncrementLineEdit->setText(strLagIncrement);
189 }
190 
192 {
193  //disable adjust options
194  m_ui->m_adjustGroupBox->setEnabled(false);
195  m_ui->m_changeAttrToolButton->setEnabled(false);
196 
197  //check input interface parameters
198  if(m_ui->m_nLagsLineEdit->text().isEmpty())
199  {
200  QMessageBox::warning(this, tr("Warning"), tr("Number of lags not defined."));
201  return;
202  }
203 
204  if(m_ui->m_lagsIncrementLineEdit->text().isEmpty())
205  {
206  QMessageBox::warning(this, tr("Warning"), tr("Lag increment not defined."));
207  return;
208  }
209 
210  if(m_ui->m_angleDirLineEdit->text().isEmpty())
211  {
212  QMessageBox::warning(this, tr("Warning"), tr("Angular direction not defined."));
213  return;
214  }
215 
216  if(m_ui->m_angleTolLineEdit->text().isEmpty())
217  {
218  QMessageBox::warning(this, tr("Warning"), tr("Angular tolerance not defined."));
219  return;
220  }
221 
222  //get selected layer
223  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(m_ui->m_inputLayerComboBox->currentIndex(), Qt::UserRole);
225 
226  //get dataset and dataset type
227  std::unique_ptr<te::da::DataSet> dataSet = l->getData();
228  std::unique_ptr<te::da::DataSetType> dataSetType = l->getSchema();
229 
230  //get properties information
231  std::string attrName = m_ui->m_attributeComboBox->currentText().toUtf8().data();
232  int attrIdx = te::da::GetPropertyIndex(dataSet.get(), attrName);
233 
234  te::gm::GeometryProperty* geomProp = te::da::GetFirstGeomProperty(dataSetType.get());
235  int geomIdx = te::da::GetPropertyIndex(dataSet.get(), geomProp->getName());
236 
237  //create geostatistical method
238  delete m_method;
239 
240  int typeIdx = m_ui->m_typeComboBox->currentIndex();
241  te::sa::GeostatisticalMethodType type = (te::sa::GeostatisticalMethodType)m_ui->m_typeComboBox->itemData(typeIdx).toInt();
242 
243  if(type == te::sa::Semivariogram)
244  {
246  }
247  else
248  {
249  m_method = nullptr;
250  return;
251  }
252 
253  //set geostatistical method parameters
254  m_method->setNumberOfLags((std::size_t)m_ui->m_nLagsLineEdit->text().toInt());
255  m_method->setLagIncrement(m_ui->m_lagsIncrementLineEdit->text().toDouble());
256  m_method->setAngleDirection(m_ui->m_angleDirLineEdit->text().toDouble());
257  m_method->setAngleTolerance(m_ui->m_angleTolLineEdit->text().toDouble());
258  m_method->setMatrix(te::sa::CreateMatrixFromDataSet(dataSet.get(), attrIdx, geomIdx));
259 
260  //calculate moments
261  double mean = 0.;
262  double variance = 0.;
263 
264  te::sa::CalculateMoments(m_method->getMatrix(), mean, variance);
265 
266  //reset adjust values
267  resetAdjustParameters(mean, variance);
268 
269  //run
270  calculate();
271 
272  //enable adjust options
273  m_ui->m_adjustGroupBox->setEnabled(true);
274  m_ui->m_changeAttrToolButton->setEnabled(true);
275 }
276 
278 {
279  //get selected layer
280  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(m_ui->m_inputLayerComboBox->currentIndex(), Qt::UserRole);
282 
283  //get dataset and dataset type
284  std::unique_ptr<te::da::DataSet> dataSet = l->getData();
285 
286  //get properties information
287  std::string attrName = m_ui->m_attributeComboBox->currentText().toUtf8().data();
288  int attrIdx = te::da::GetPropertyIndex(dataSet.get(), attrName);
289 
290  te::sa::SetMainDiagonal(m_method->getMatrix(), dataSet.get(), attrIdx);
291 
292  //calculate moments
293  double mean = 0.;
294  double variance = 0.;
295 
296  te::sa::CalculateMoments(m_method->getMatrix(), mean, variance);
297 
298  //reset adjust values
299  resetAdjustParameters(mean, variance);
300 
301  //run
302  calculate();
303 }
304 
306 {
307  //create geostatistical model
308  int modelIdx = m_ui->m_modelComboBox->currentIndex();
309  te::sa::GeostatisticalModelType type = (te::sa::GeostatisticalModelType)m_ui->m_modelComboBox->itemData(modelIdx).toInt();
310 
311  te::sa::GeostatisticalModel* model = nullptr;
312 
313  if(type == te::sa::Spherical)
315  else if(type == te::sa::Exponential)
317  else if(type == te::sa::Gaussian)
319 
320  model->setNugget((double)m_ui->m_nuggetHorizontalSlider->value());
321  model->setSill((double)m_ui->m_sillHorizontalSlider->value());
322  model->setRange((double)m_ui->m_rangeHorizontalSlider->value());
323 
324  //generate output matrix
327 
328  delete model;
329 
330  //plot
331  plot();
332 }
333 
335 {
336  //fill msv types
337  m_ui->m_typeComboBox->clear();
338 
339  m_ui->m_typeComboBox->addItem("Semivariogram", QVariant(te::sa::Semivariogram));
340 
341  //fill msv models
342  m_ui->m_modelComboBox->clear();
343 
344  m_ui->m_modelComboBox->addItem("Spherical", QVariant(te::sa::Spherical));
345  m_ui->m_modelComboBox->addItem("Exponential", QVariant(te::sa::Exponential));
346  m_ui->m_modelComboBox->addItem("Gaussian", QVariant(te::sa::Gaussian));
347 }
348 
350 {
351  //set nugget value
352  double min = 0.;
353  double max = variance;
354  double nuggetVar = (max - min)/mean;
355 
356  m_ui->m_nuggetHorizontalSlider->setRange(min - nuggetVar, max + nuggetVar);
357  m_ui->m_nuggetHorizontalSlider->setValue(min);
358  m_ui->m_nuggetLabel->setNum(min);
359 
360  //set sill value
361  min = 0;
362  max = max + variance;
363  double sillVar = (max - min)/mean;
364 
365  m_ui->m_sillHorizontalSlider->setRange(min - sillVar, max + sillVar);
366  m_ui->m_sillHorizontalSlider->setValue(min);
367  m_ui->m_sillLabel->setNum(min);
368 
369  //set range value
370  double rangeVar = m_ui->m_nLagsLineEdit->text().toDouble();
371  min = m_ui->m_lagsIncrementLineEdit->text().toDouble();
372  max = min * rangeVar;
373 
374  m_ui->m_rangeHorizontalSlider->setRange(min - rangeVar, max + rangeVar);
375  m_ui->m_rangeHorizontalSlider->setValue(min);
376  m_ui->m_rangeLabel->setNum(min);
377 }
378 
380 {
381  m_chartDisplay->setTitle(m_ui->m_typeComboBox->currentText());
382 
383  //plot method curve
384  std::vector<double> methodh;
385  std::vector<double> methodyh;
386 
387  for(std::size_t t = 1; t < m_methodMatrix.size1(); ++t)
388  {
389  methodh.push_back(m_methodMatrix(t, 0));
390  methodyh.push_back(m_methodMatrix(t, 1));
391  }
392 
393  m_scatterMethod->setXValues(methodh);
394  m_scatterMethod->setYValues(methodyh);
397 
398  //plot model curve
399  std::vector<double> modelh;
400  std::vector<double> modelyh;
401 
402  for(std::size_t t = 0; t < m_modelMatrix.size1(); ++t)
403  {
404  modelh.push_back(m_modelMatrix(t, 0));
405  modelyh.push_back(m_modelMatrix(t, 1));
406  }
407 
408  m_scatterModel->setXValues(modelh);
409  m_scatterModel->setYValues(modelyh);
412 
413  //replot the chart display
414  m_chartDisplay->replot();
415 }
void setSill(double value)
Function to set the sill value.
Class that represents the geostatistical exponential model.
te::qt::widgets::ScatterChart * m_scatterChartModel
Geometric property.
Class that represents the geostatistical spherical model.
The empirical variogram cannot be computed at every lag distance h and due to variation in the estima...
static te::dt::Date ds(2010, 01, 01)
te::qt::widgets::ChartDisplay * m_chartDisplay
TESAEXPORT void SetMainDiagonal(boost::numeric::ublas::matrix< double > &matrix, te::da::DataSet *dataSet, int attrIdx)
Function used to set new values in the matrix main diagonal.
TEDATAACCESSEXPORT int GetPropertyIndex(te::da::DataSet *dataSet, const std::string propName)
TESAEXPORT boost::numeric::ublas::matrix< double > CreateMatrixFromDataSet(te::da::DataSet *dataSet, int attrIdx, int geomIdx)
Function used to create a matrix with values, distance and angle for each element from dataset...
Class that represents the geostatistical gaussian model.
void setYValues(std::vector< double > yValues)
It sets the values of the Y axis.
Definition: Scatter.cpp:157
TESAEXPORT void CalculateMoments(const boost::numeric::ublas::matrix< double > &matrix, double &mean, double &variance)
Function used to calculate mean and variance from a matrix.
boost::numeric::ublas::matrix< double > m_modelMatrix
A class to represent a scatter.
Definition: Scatter.h:51
boost::numeric::ublas::matrix< double > m_methodMatrix
Semivariogram is a function describing the degree of spatial dependence of a spatial random field...
A dialog with geostatistical methods to measure the spatial variability of attribute of a dataset...
URI C++ Library.
Definition: Attributes.h:37
A class to represent a chart display.
Definition: ChartDisplay.h:65
virtual boost::numeric::ublas::matrix< double > calculate(boost::numeric::ublas::matrix< double > matrix)=0
Function to calculate the geostatistical information from model.
virtual boost::numeric::ublas::matrix< double > calculate()=0
Function to calculate the geostatistical information.
void setLayers(std::list< te::map::AbstractLayerPtr > layers)
Set the layer that can be used.
A class to represent a scatter chart.
Definition: ScatterChart.h:55
boost::numeric::ublas::matrix< double > & getMatrix()
Function to get the input matrix with data information.
GeostatisticalModelType
Geostatistical models for measure of Spatial Variability.
std::unique_ptr< Ui::GeostatisticalMethodsDialogForm > m_ui
void setXValues(std::vector< double > xValues)
It sets the values of the X axis.
Definition: Scatter.cpp:142
GeostatisticalMethodType
Geostatistical methods for measure of Spatial Variability.
void calculateMinMaxValues()
Calculates the minimum and maximum values for both the X and Y axis.
Definition: Scatter.cpp:59
void resetAdjustParameters(double mean, double variance)
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void setNugget(double value)
Function to set the nugget value.
void setRange(double value)
Function to set the range value.
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
te::qt::widgets::ScatterChart * m_scatterChartMethod