LoadArithmeticOpDialog.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/rp/LoadArithmeticOpDialog.cpp
22 
23  \brief This file defines a class for a ArithmeticOp Dialog.
24 */
25 
26 // TerraLib
27 #include "../../../common/PlatformUtils.h"
28 #include "../../../common/StringUtils.h"
29 #include "../../../core/utils/Platform.h"
30 #include "../../../core/translator/Translator.h"
31 #include "../../../dataaccess/dataset/DataSet.h"
32 #include "../../../dataaccess/utils/Utils.h"
33 #include "LoadArithmeticOpDialog.h"
34 #include "ui_LoadArithmeticOpDialogForm.h"
35 
36 //Boost
37 #include <boost/algorithm/string.hpp>
38 #include <boost/property_tree/json_parser.hpp>
39 
40 // Qt
41 #include <QApplication>
42 #include <QGridLayout>
43 #include <QMessageBox>
44 #include <QComboBox>
45 #include <QFile>
46 #include <QTextStream>
47 
48 // stl
49 #include <memory>
50 
52 
53 te::qt::widgets::LoadArithmeticOpDialog::LoadArithmeticOpDialog(QWidget* parent, Qt::WindowFlags f)
54  : QDialog(parent, f),
55  m_ui(new Ui::LoadArithmeticOpDialogForm)
56 {
57 // setup controls
58  m_ui->setupUi(this);
59 
60  m_ui->m_removeToolButton->setIcon(QIcon::fromTheme("list-remove"));
61 
62  //connects
63  connect(m_ui->m_operationComboBox, SIGNAL(activated(QString)), this, SLOT(onOperationComboBoxActivated(QString)));
64  connect(m_ui->m_removeToolButton, SIGNAL(clicked()), this, SLOT(onRemoveOperation()));
65  connect(m_ui->m_okPushButton, SIGNAL(clicked()), this, SLOT(onOkPushButtonClicked()));
66 }
67 
69 
71 {
72  m_ui->m_layersTableWidget->clear();
73  m_ui->m_operationComboBox->clear();
74 
75  m_ui->m_layersTableWidget->setRowCount(0);
76 
77  QStringList list;
78  list.append(tr("Layer"));
79  list.append(tr("Band"));
80 
81  m_ui->m_layersTableWidget->setHorizontalHeaderLabels(list);
82  m_ui->m_layersTableWidget->setColumnCount(2);
83 
84  std::string jsonfile = m_userPath + "/arithmeticOperations.json";
85 
86  if (jsonfile.empty())
87  throw te::common::Exception(TE_TR("Could not find arithmeticOperations.json file!"));
88 
89  try
90  {
91  // Reading JSON
92  boost::property_tree::ptree pt;
93 
94  boost::property_tree::json_parser::read_json(jsonfile, pt);
95 
96  for(boost::property_tree::ptree::value_type &v: pt.get_child("operations"))
97  {
98  std::string op = v.second.get<std::string>("operation");
99  m_ui->m_operationComboBox->addItem(op.c_str());
100  }
101  }
102  catch(boost::property_tree::json_parser::json_parser_error& e)
103  {
104  std::string msg = "Error parsing: " + e.filename() + ": " + e.message();
105  te::common::Exception ex(TE_TR(msg));
106  throw(ex);
107  }
108  catch(boost::property_tree::ptree_error& e)
109  {
110  throw te::common::Exception(TE_TR(e.what()));
111  }
112  catch(...)
113  {
114  throw te::common::Exception(TE_TR("Load arithmetic operations error."));
115  }
116 }
117 
118 void te::qt::widgets::LoadArithmeticOpDialog::setList(std::list<te::map::AbstractLayerPtr>& layerList)
119 {
120  m_layerList = layerList;
121 }
122 
124 {
125  m_userPath = path;
126 }
127 
129 {
130  return m_operationExt;
131 }
132 
133 std::map<std::string, te::map::AbstractLayer*> te::qt::widgets::LoadArithmeticOpDialog::getLayers()
134 {
135  return m_mapLayer;
136 }
137 
139 {
140  return m_operation;
141 }
142 
144 {
145  int r = 0;
146 
147  m_layersComboBox.clear();
148  m_bandsComboBox.clear();
149  m_ui->m_layersTableWidget->setRowCount(0);
150 
151  m_ui->m_gainLineEdit->setEnabled(false);
152  m_ui->m_offsetLineEdit->setEnabled(false);
153  m_ui->m_gainLineEdit->setText("");
154  m_ui->m_offsetLineEdit->setText("");
155 
156  std::string op = operation.toUtf8().data();
157 
158  std::vector<std::string> arithExpVec;
159  boost::split(arithExpVec, op, boost::is_any_of(" "));
160 
161  for (size_t i = 0; i < arithExpVec.size(); i++)
162  {
163  if (arithExpVec[i].find(":") != std::string::npos)
164  {
165  std::vector<std::string> rasterVec;
166  boost::split(rasterVec, arithExpVec[i], boost::is_any_of(":"));
167 
168  bool exist = false;
169  for (int j = 0; j < m_ui->m_layersTableWidget->rowCount(); j++)
170  {
171  std::string header = m_ui->m_layersTableWidget->verticalHeaderItem(j)->text().toUtf8().data();
172  if (rasterVec[0] == header)
173  exist = true;
174  }
175 
176  if (!exist)
177  {
178  m_ui->m_layersTableWidget->setRowCount(r + 1);
179 
180  QTableWidgetItem* item = new QTableWidgetItem(rasterVec[0].c_str());
181  m_ui->m_layersTableWidget->setVerticalHeaderItem(r, item);
182 
183  QComboBox* layerComboBox = new QComboBox(m_ui->m_layersTableWidget);
184  m_layersComboBox.push_back(layerComboBox);
185 
186  QComboBox* bandComboBox = new QComboBox(m_ui->m_layersTableWidget);
187  m_bandsComboBox.push_back(bandComboBox);
188 
189  connect(m_layersComboBox[r], SIGNAL(activated(int)), this, SLOT(onLayerComboBoxActivated(int)));
190 
191  r++;
192  }
193  }
194  else if (te::common::Convert2LCase(arithExpVec[i]) == "gain")
195  {
196  m_ui->m_gainLineEdit->setEnabled(true);
197  m_ui->m_gainLineEdit->setText("1");
198  }
199  else if (te::common::Convert2LCase(arithExpVec[i]) == "offset")
200  {
201  m_ui->m_offsetLineEdit->setEnabled(true);
202  m_ui->m_offsetLineEdit->setText("0");
203  }
204  }
205 
206  std::list<te::map::AbstractLayerPtr>::iterator it = m_layerList.begin();
207 
208  m_layers.clear();
209 
210  int count = 0;
211 
212  while (it != m_layerList.end())
213  {
215 
216  std::unique_ptr<te::da::DataSet> ds = l->getData();
217  std::unique_ptr<te::da::DataSetType> dst = l->getSchema();
218 
219  if (dst.get() && dst->hasRaster())
220  {
221  if (count == 0)
222  {
223  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
224  std::unique_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
225 
226  int nbands = static_cast<int>(inputRst->getNumberOfBands());
227 
228  for (int i = 0; i < static_cast<int>(m_layersComboBox.size()); i++)
229  {
230  for (int b = 0; b < nbands; b++)
231  m_bandsComboBox[i]->addItem(te::common::Convert2String(b).c_str());
232  }
233  }
234 
235  m_layers.push_back(l);
236 
237  for (size_t i = 0; i < m_layersComboBox.size(); i++)
238  {
239  m_layersComboBox[i]->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
240  }
241 
242  ++count;
243  }
244 
245  ++it;
246  }
247 
248  for (int i = 0; i < static_cast<int>(m_layersComboBox.size()); i++)
249  {
250  m_ui->m_layersTableWidget->setCellWidget(i, 0, m_layersComboBox[i]);
251  m_ui->m_layersTableWidget->setCellWidget(i, 1, m_bandsComboBox[i]);
252  }
253 
254  m_ui->m_layersTableWidget->resizeColumnsToContents();
255 }
256 
258 {
259  int row = -1;
260 
261  int nrows = m_ui->m_layersTableWidget->rowCount();
262  for (int i = 0; i < nrows; i++)
263  {
264  if (QObject::sender() == m_layersComboBox[i])
265  {
266  row = i;
267  break;
268  }
269  }
270 
271  te::map::AbstractLayerPtr layer = m_layers[index];
272 
273  std::unique_ptr<te::da::DataSet> ds = layer->getData();
274  std::unique_ptr<te::da::DataSetType> dst = layer->getSchema();
275 
276  if (dst.get() && dst->hasRaster())
277  {
278  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
279  std::unique_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
280 
281  m_bandsComboBox[row]->clear();
282 
283  int nbands = static_cast<int>(inputRst->getNumberOfBands());
284 
285  for (int i = 0; i < nbands; i++)
286  {
287  m_bandsComboBox[row]->addItem(te::common::Convert2String(i).c_str());
288  }
289  }
290 }
291 
293 {
294  int index = m_ui->m_operationComboBox->currentIndex();
295 
296  std::string selectedOperation = m_ui->m_operationComboBox->itemText(index).toUtf8().data();
297 
298  int reply = QMessageBox::question(this, tr("Arithmetic Operations"),
299  tr("The operation ") + QString::fromStdString(selectedOperation) + (" will be removed from the list, are you certain?"),
300  QMessageBox::Yes | QMessageBox::No);
301 
302  if(reply == QMessageBox::No)
303  return;
304 
305  try
306  {
307  if(isDefaultArithmeticOperation(selectedOperation))
308  {
309  QMessageBox::warning(this, tr("Warning"), tr("The default operation can not be removed from the list."));
310  return;
311  }
312 
313  QString path = QString::fromStdString(m_userPath) + "/arithmeticOperations.json";
314 
315  QFile file(path);
316 
317  if(!file.exists())
318  {
319  QMessageBox::warning(this, tr("Warning"), tr("File not found."));
320  return;
321  }
322 
323  boost::property_tree::ptree pt;
324 
325  boost::property_tree::json_parser::read_json(path.toUtf8().data(), pt);
326 
327  for(boost::property_tree::ptree::value_type &v: pt.get_child("operations"))
328  {
329  std::string op = v.second.get<std::string>("operation");
330 
331  if (te::common::Convert2UCase(op) == te::common::Convert2UCase(selectedOperation))
332  pt.get_child("operations").erase(v.first);
333  }
334 
335  boost::property_tree::write_json(path.toUtf8().data(), pt);
336 
337  loadOperations();
338 
339  QMessageBox::information(this, tr("Arithmetic Operation"), tr("The operation was deleted sucessfully."));
340  }
341  catch(te::common::Exception& e)
342  {
343  QMessageBox::warning(this, tr("Warning"), tr(e.what()));
344  return;
345  }
346  catch(...)
347  {
348  QMessageBox::warning(this, tr("Arithmetic Operations"), tr("An error has occurred."));
349  return;
350  }
351 }
352 
354 {
355  if (m_ui->m_gainLineEdit->isEnabled() && m_ui->m_gainLineEdit->text().isEmpty())
356  {
357  QMessageBox::warning(this, tr("Warning"), tr("Gain value is not defined."));
358  return;
359  }
360 
361  if (m_ui->m_offsetLineEdit->isEnabled() && m_ui->m_offsetLineEdit->text().isEmpty())
362  {
363  QMessageBox::warning(this, tr("Warning"), tr("Offset value is not defined."));
364  return;
365  }
366 
367  if(m_ui->m_layersTableWidget->rowCount() != 0)
368  {
369  m_operationExt = "";
370  m_operation = "";
371 
372  std::string operation = m_ui->m_operationComboBox->currentText().toUtf8().data();
373 
374  std::vector<std::string> arithExpVec;
375  boost::split(arithExpVec, operation, boost::is_any_of(" "));
376 
377  for (int i = 0; i < static_cast<int>(arithExpVec.size()); i++)
378  {
379  if (te::common::Convert2LCase(arithExpVec[static_cast<size_t>(i)]) == "gain")
380  {
381  m_operationExt += " " + std::string(m_ui->m_gainLineEdit->text().toUtf8().data());
382  m_operation += " " + std::string(m_ui->m_gainLineEdit->text().toUtf8().data());
383  }
384  else if (te::common::Convert2LCase(arithExpVec[i]) == "offset")
385  {
386  m_operationExt += " " + std::string(m_ui->m_offsetLineEdit->text().toUtf8().data());
387  m_operation += " " + std::string(m_ui->m_offsetLineEdit->text().toUtf8().data());
388  }
389  else
390  {
391  std::vector<std::string> layerVec;
392  boost::split(layerVec, arithExpVec[i], boost::is_any_of(":"));
393 
394  if (layerVec.size() == 1)
395  {
396  m_operationExt += " " + arithExpVec[i];
397  m_operation += " " + arithExpVec[i];
398  }
399  else
400  {
401  int nrows = m_ui->m_layersTableWidget->rowCount();
402 
403  for (int j = 0; j < nrows; j++)
404  {
405  std::string header = m_ui->m_layersTableWidget->verticalHeaderItem(j)->text().toUtf8().data();
406 
407  if (header == layerVec[0])
408  {
409  int index = m_layersComboBox[j]->currentIndex();
410  m_mapLayer.insert(std::map<std::string, te::map::AbstractLayer*>::value_type(header, m_layers[index].get()));
411 
412  m_operationExt += " " + std::string(m_layersComboBox[j]->currentText().toUtf8().data()) + ":B" + m_bandsComboBox[j]->currentText().toUtf8().data();
413  m_operation += " " + std::string(m_ui->m_layersTableWidget->verticalHeaderItem(j)->text().toUtf8().data()) + ":" + m_bandsComboBox[j]->currentText().toUtf8().data();
414  break;
415  }
416  }
417  }
418  }
419  }
420  }
421 
422  accept();
423 }
424 
426 {
427  std::string path = te::core::FindInTerraLibPath("share/terralib/json/arithmeticOperations.json");
428 
429  QFile file(QString::fromStdString(path));
430 
431  if(!file.exists())
432  throw te::common::Exception(TE_TR("The file with default operations was not found."));
433 
434  bool isDefaultOperation = false;
435 
436  boost::property_tree::ptree pt;
437 
438  boost::property_tree::json_parser::read_json(path, pt);
439 
440  for(boost::property_tree::ptree::value_type &v: pt.get_child("operations"))
441  {
442  std::string op = v.second.get<std::string>("operation");
443 
445  isDefaultOperation = true;
446  }
447 
448  return isDefaultOperation;
449 }
This file defines a class for a ArithmeticOp Dialog.
std::string Convert2LCase(const std::string &value)
It converts a string to lower case.
Definition: StringUtils.h:202
std::map< std::string, te::map::AbstractLayer * > getLayers()
virtual const char * what() const
It outputs the exception message.
std::list< te::map::AbstractLayerPtr > m_layerList
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:168
static te::dt::Date ds(2010, 01, 01)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
std::map< std::string, te::map::AbstractLayer * > m_mapLayer
void setList(std::list< te::map::AbstractLayerPtr > &layerList)
std::vector< te::map::AbstractLayerPtr > m_layers
int b
Definition: TsRtree.cpp:32
URI C++ Library.
Definition: Attributes.h:37
std::unique_ptr< Ui::LoadArithmeticOpDialogForm > m_ui
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
TECOREEXPORT std::string FindInTerraLibPath(const std::string &path)
Returns the path relative to a directory or file in the context of TerraLib.
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:56
bool isDefaultArithmeticOperation(const std::string &operation)
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
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 $