All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GroupingWidget.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011-2012 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/se/GroupingWidget.cpp
22 
23  \brief A widget used to build a grouping.
24 */
25 
26 // TerraLib
27 #include "../../../color/ColorBar.h"
28 #include "../../../common/Globals.h"
29 #include "../../../common/STLUtils.h"
30 #include "../../../dataaccess/dataset/DataSet.h"
31 #include "../../../dataaccess/dataset/DataSetType.h"
32 #include "../../../dataaccess/utils/Utils.h"
33 #include "../../../geometry/GeometryProperty.h"
34 #include "../../../maptools/Enums.h"
35 #include "../../../maptools/Grouping.h"
36 #include "../../../maptools/GroupingAlgorithms.h"
37 #include "../../../maptools/GroupingItem.h"
38 #include "../../../maptools/Utils.h"
39 #include "../../../se/SymbolizerColorFinder.h"
40 #include "../../../se/Utils.h"
41 #include "../colorbar/ColorBar.h"
42 #include "../colorbar/ColorCatalogWidget.h"
43 #include "../se/LineSymbolizerWidget.h"
44 #include "../se/PointSymbolizerWidget.h"
45 #include "../se/PolygonSymbolizerWidget.h"
46 #include "../se/SymbologyPreview.h"
47 #include "GroupingWidget.h"
48 #include "ui_GroupingWidgetForm.h"
49 
50 // STL
51 #include <cassert>
52 
53 // QT
54 #include <QDialogButtonBox>
55 #include <QMessageBox>
56 
57 #define MAX_SLICES 200
58 #define PRECISION 15
59 #define NO_TITLE "No Value"
60 
62 
63 te::qt::widgets::GroupingWidget::GroupingWidget(QWidget* parent, Qt::WindowFlags f)
64  : QWidget(parent, f),
65  m_ui(new Ui::GroupingWidgetForm),
66  m_cb(0)
67 {
68  m_ui->setupUi(this);
69 
70  QGridLayout* l = new QGridLayout(m_ui->m_colorBarWidget);
71  l->setContentsMargins(0,0,0,0);
72  m_colorBar = new te::qt::widgets::ColorCatalogWidget(m_ui->m_colorBarWidget);
73  l->addWidget(m_colorBar);
74 
75 //connects
76  connect(m_colorBar, SIGNAL(colorBarChanged()), this, SLOT(onColorBarChanged()));
77  connect(m_ui->m_typeComboBox, SIGNAL(activated(int)), this, SLOT(onTypeComboBoxActivated(int)));
78  connect(m_ui->m_attrComboBox, SIGNAL(activated(int)), this, SLOT(onAttrComboBoxActivated(int)));
79  connect(m_ui->m_applyPushButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
80  connect(m_ui->m_tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(onTableWidgetItemDoubleClicked(QTableWidgetItem*)));
81  connect(m_ui->m_importPushButton, SIGNAL(clicked()), this, SLOT(onImportPushButtonClicked()));
82 
83  //m_importGroupingGroupBox
84  initialize();
85 }
86 
88 {
89  delete m_cb;
90 
91  te::common::FreeContents(m_legend);
92  m_legend.clear();
93 }
94 
95 std::auto_ptr<te::map::Grouping> te::qt::widgets::GroupingWidget::getGrouping()
96 {
97  if(m_ui->m_importGroupBox->isChecked())
98  {
99  QVariant varLayer = m_ui->m_layersComboBox->itemData(m_ui->m_layersComboBox->currentIndex(), Qt::UserRole);
100  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
101 
102  te::map::Grouping* ref = layer->getGrouping();
103 
104  std::auto_ptr<te::map::Grouping> group(new te::map::Grouping(*ref));
105 
106  return group;
107  }
108 
109  std::string attr = m_ui->m_attrComboBox->currentText().toStdString();
110  int attrIdx = m_ui->m_attrComboBox->currentIndex();
111  int attrType = m_ui->m_attrComboBox->itemData(attrIdx).toInt();
112 
113  int index = m_ui->m_typeComboBox->currentIndex();
114  int type = m_ui->m_typeComboBox->itemData(index).toInt();
115 
116  std::auto_ptr<te::map::Grouping> group(new te::map::Grouping(attr, (te::map::GroupingType)type));
117 
118  group->setPropertyType(attrType);
119 
120  group->setNumSlices(m_ui->m_slicesSpinBox->value());
121 
122  group->setPrecision(m_ui->m_precSpinBox->value());
123 
124  group->setStdDeviation(m_ui->m_stdDevDoubleSpinBox->value());
125 
126  std::vector<te::map::GroupingItem*> groupingItems;
127  for(std::size_t t = 0; t < m_legend.size(); ++t)
128  {
129  te::map::GroupingItem* gi = new te::map::GroupingItem(*m_legend[t]);
130 
131  groupingItems.push_back(gi);
132  }
133  group->setGroupingItems(groupingItems);
134 
135  return group;
136 }
137 
139 {
140  // create color bar
141  m_colorBar->getColorBar()->setHeight(20);
142  m_colorBar->getColorBar()->setScaleVisible(false);
143 
144  // fill grouping type combo box
145  m_ui->m_typeComboBox->addItem(tr("Equal Steps"), te::map::EQUAL_STEPS);
146  m_ui->m_typeComboBox->addItem(tr("Quantil"), te::map::QUANTIL);
147  m_ui->m_typeComboBox->addItem(tr("Standard Deviation"), te::map::STD_DEVIATION);
148  m_ui->m_typeComboBox->addItem(tr("Unique Value"), te::map::UNIQUE_VALUE);
149 
150  onTypeComboBoxActivated(0);
151 
152  //set number of slices
153  m_ui->m_slicesSpinBox->setMinimum(1);
154  m_ui->m_slicesSpinBox->setMaximum(MAX_SLICES);
155  m_ui->m_slicesSpinBox->setValue(5);
156  m_ui->m_slicesSpinBox->setSingleStep(1);
157 
158  //set standard deviation values
159  m_ui->m_stdDevDoubleSpinBox->setMinimum(0.25);
160  m_ui->m_stdDevDoubleSpinBox->setMaximum(1.0);
161  m_ui->m_stdDevDoubleSpinBox->setValue(0.5);
162  m_ui->m_stdDevDoubleSpinBox->setSingleStep(0.25);
163 
164  //set number of precision
165  m_ui->m_precSpinBox->setMinimum(1);
166  m_ui->m_precSpinBox->setMaximum(PRECISION);
167  m_ui->m_precSpinBox->setValue(6);
168  m_ui->m_precSpinBox->setSingleStep(1);
169 
170  //adjust table
171  m_ui->m_tableWidget->resizeColumnsToContents();
172 #if (QT_VERSION >= 0x050000)
173  m_ui->m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
174 #else
175  m_ui->m_tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
176 #endif
177 
178  m_manual = false;
179 }
180 
182 {
183  disconnect(m_ui->m_tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(onTableWidgetItemChanged(QTableWidgetItem*)));
184 
185  m_ui->m_tableWidget->setRowCount(0);
186 
187  int index = m_ui->m_typeComboBox->currentIndex();
188  int type = m_ui->m_typeComboBox->itemData(index).toInt();
189 
190  if(type == te::map::EQUAL_STEPS || type == te::map::QUANTIL || type == te::map::STD_DEVIATION)
191  {
192  QStringList list;
193  list.append(tr("Symbol"));
194  list.append(tr("Title"));
195  list.append(tr("Min"));
196  list.append(tr("Max"));
197  list.append(tr("Count"));
198 
199  m_ui->m_tableWidget->setColumnCount(5);
200  m_ui->m_tableWidget->setHorizontalHeaderLabels(list);
201  }
202  else if(type == te::map::UNIQUE_VALUE)
203  {
204  QStringList list;
205  list.append(tr("Symbol"));
206  list.append(tr("Title"));
207  list.append(tr("Value"));
208  list.append(tr("Count"));
209 
210  m_ui->m_tableWidget->setColumnCount(4);
211  m_ui->m_tableWidget->setHorizontalHeaderLabels(list);
212  }
213 
214  te::color::ColorBar* cb = 0;
215 
216  if(loadColorBar)
217  {
218  if(!m_legend.empty() && !m_legend[0]->getSymbolizers().empty() && !m_legend[m_legend.size() - 1]->getSymbolizers().empty())
219  {
221 
222  scf.find(m_legend[0]->getSymbolizers()[0]);
223  te::color::RGBAColor initColor = scf.getColor();
224 
225  scf.find(m_legend[m_legend.size() - 1]->getSymbolizers()[0]);
226  te::color::RGBAColor endColor = scf.getColor();
227 
228  cb = new te::color::ColorBar(initColor, endColor, 256);
229  }
230  }
231 
232  int count = 0;
233 
234  for(std::size_t t = 0; t < m_legend.size(); ++t)
235  {
236  te::map::GroupingItem* gi = m_legend[t];
237 
238  int newrow = m_ui->m_tableWidget->rowCount();
239  m_ui->m_tableWidget->insertRow(newrow);
240 
241  //symbol
242  {
243  const std::vector<te::se::Symbolizer*>& ss = gi->getSymbolizers();
244  QPixmap pix = te::qt::widgets::SymbologyPreview::build(ss, QSize(24, 24));
245  QIcon icon(pix);
246  QTableWidgetItem* item = new QTableWidgetItem(icon, "");
247  item->setFlags(Qt::ItemIsEnabled);
248  m_ui->m_tableWidget->setItem(newrow, 0, item);
249  }
250 
251  //title
252  {
253  QTableWidgetItem* item = new QTableWidgetItem(QString::fromStdString(gi->getTitle()));
254  item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
255  m_ui->m_tableWidget->setItem(newrow, 1, item);
256  }
257 
258  if(loadColorBar)
259  {
260  if(count != 0 && count != m_legend.size() - 1)
261  {
262  double pos = (1. / (m_legend.size() - 1)) * count;
263 
264  if(!gi->getSymbolizers().empty())
265  {
267 
268  scf.find(gi->getSymbolizers()[0]);
269 
270  te::color::RGBAColor color = scf.getColor();
271 
272  if(cb)
273  cb->addColor(color, pos);
274  }
275  }
276  }
277 
278  ++count;
279 
280  if(type == te::map::EQUAL_STEPS || type == te::map::QUANTIL || type == te::map::STD_DEVIATION)
281  {
282  if(gi->getTitle() != NO_TITLE)
283  {
284  //Min
285  {
286  QTableWidgetItem* item = new QTableWidgetItem(QString::fromStdString(gi->getLowerLimit()));
287  item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
288  m_ui->m_tableWidget->setItem(newrow, 2, item);
289  }
290 
291  //Max
292  {
293  QTableWidgetItem* item = new QTableWidgetItem(QString::fromStdString(gi->getUpperLimit()));
294  item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
295  m_ui->m_tableWidget->setItem(newrow, 3, item);
296  }
297  }
298 
299  //Count
300  QTableWidgetItem* item = new QTableWidgetItem(QString::number(gi->getCount()));
301  item->setFlags(Qt::ItemIsEnabled);
302  m_ui->m_tableWidget->setItem(newrow, 4, item);
303 
304  }
305  else if(type == te::map::UNIQUE_VALUE)
306  {
307  if(gi->getTitle() != NO_TITLE)
308  {
309  //Value
310  QTableWidgetItem* item = new QTableWidgetItem(QString::fromStdString(gi->getValue()));
311  item->setFlags(Qt::ItemIsEnabled);
312  m_ui->m_tableWidget->setItem(newrow, 2, item);
313  }
314 
315  //Count
316  QTableWidgetItem* item = new QTableWidgetItem(QString::number(gi->getCount()));
317  item->setFlags(Qt::ItemIsEnabled);
318  m_ui->m_tableWidget->setItem(newrow, 3, item);
319 
320  }
321  }
322 
323  if(cb)
324  {
325  disconnect(m_colorBar, SIGNAL(colorBarChanged()), this, SLOT(onColorBarChanged()));
326 
328  cbW->setColorBar(cb);
329 
330  connect(m_colorBar, SIGNAL(colorBarChanged()), this, SLOT(onColorBarChanged()));
331  }
332 
333  m_ui->m_tableWidget->resizeColumnsToContents();
334 #if (QT_VERSION >= 0x050000)
335  m_ui->m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
336 #else
337  m_ui->m_tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
338 #endif
339 
340  connect(m_ui->m_tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(onTableWidgetItemChanged(QTableWidgetItem*)));
341 }
342 
344 {
345  listAttributes();
346 }
347 
349 {
350  te::map::Grouping* grouping = m_layer->getGrouping();
351 
352  setGrouping(grouping);
353 
354  emit applyPushButtonClicked();
355 }
356 
358 {
359  if(!grouping)
360  return;
361 
362  //type
363  te::map::GroupingType type = grouping->getType();
364 
365  for(int i = 0; i < m_ui->m_typeComboBox->count(); ++i)
366  {
367  if(type == m_ui->m_typeComboBox->itemData(i).toInt())
368  {
369  m_ui->m_typeComboBox->setCurrentIndex(i);
370 
371  onTypeComboBoxActivated(i);
372 
373  break;
374  }
375  }
376 
377  //attr name
378  std::string attrName = grouping->getPropertyName();
379 
380  for(int i = 0; i < m_ui->m_attrComboBox->count(); ++i)
381  {
382  if(attrName == m_ui->m_attrComboBox->itemText(i).toStdString())
383  {
384  m_ui->m_attrComboBox->setCurrentIndex(i);
385  break;
386  }
387  }
388 
389  //precision
390  size_t prec = grouping->getPrecision();
391 
392  m_ui->m_precSpinBox->setValue((int)prec);
393 
394  //slices
395  size_t slices = grouping->getNumSlices();
396 
397  m_ui->m_slicesSpinBox->setValue((int)slices);
398 
399  //std dev
400  float stdDev = grouping->getStdDeviation();
401 
402  m_ui->m_stdDevDoubleSpinBox->setValue((double)stdDev);
403 
404  //grouping items
405  te::common::FreeContents(m_legend);
406  m_legend.clear();
407 
408  for(size_t t = 0; t < grouping->getGroupingItems().size(); ++t)
409  {
411 
412  m_legend.push_back(gi);
413  }
414 
415  updateUi(true);
416 
417  onApplyPushButtonClicked();
418 }
419 
421 {
422  if(m_manual)
423  {
424  int reply = QMessageBox::question(this, tr("Classification"), tr("Manual changes will be lost. Continue?"), QMessageBox::Yes | QMessageBox::Cancel);
425 
426  if(reply != QMessageBox::Yes)
427  return;
428  }
429 
430  int index = m_ui->m_typeComboBox->currentIndex();
431 
432  int type = m_ui->m_typeComboBox->itemData(index).toInt();
433  int slices = m_ui->m_slicesSpinBox->value();
434  int prec = m_ui->m_precSpinBox->value();
435  double stdDev = m_ui->m_stdDevDoubleSpinBox->value();
436 
437  std::string attr = m_ui->m_attrComboBox->currentText().toStdString();
438  int attrIdx = m_ui->m_attrComboBox->currentIndex();
439  int attrType = m_ui->m_attrComboBox->itemData(attrIdx).toInt();
440 
441  te::common::FreeContents(m_legend);
442  m_legend.clear();
443 
444  std::string mean = "";
445 
446  int nullValues = 0;
447 
448  bool update = false;
449 
450  if(type == te::map::EQUAL_STEPS)
451  {
452  std::vector<double> vec;
453 
454  getDataAsDouble(vec, attr, attrType, nullValues);
455 
456  te::map::GroupingByEqualSteps(vec.begin(), vec.end(), slices, m_legend, prec);
457 
458  buildSymbolizer(mean);
459 
460  createDoubleNullGroupingItem(nullValues);
461  }
462  else if(type == te::map::QUANTIL)
463  {
464  std::vector<double> vec;
465 
466  getDataAsDouble(vec, attr, attrType, nullValues);
467 
468  te::map::GroupingByQuantil(vec.begin(), vec.end(), slices, m_legend, prec);
469 
470  buildSymbolizer(mean);
471 
472  createDoubleNullGroupingItem(nullValues);
473  }
474  else if(type == te::map::STD_DEVIATION)
475  {
476  std::vector<double> vec;
477 
478  getDataAsDouble(vec, attr, attrType, nullValues);
479 
480  te::map::GroupingByStdDeviation(vec.begin(), vec.end(), stdDev, m_legend, mean, prec);
481 
482  buildSymbolizer(mean);
483 
484  createDoubleNullGroupingItem(nullValues);
485 
486  update = false;
487  }
488  else if(type == te::map::UNIQUE_VALUE)
489  {
490  std::vector<std::string> vec;
491 
492  getDataAsString(vec, attr, nullValues);
493 
494  te::map::GroupingByUniqueValues(vec, attrType, m_legend, prec);
495 
496  buildSymbolizer(mean);
497 
498  createStringNullGroupingItem(nullValues);
499  }
500 
501  updateUi(update);
502 
503  m_manual = false;
504 
505  emit applyPushButtonClicked();
506 }
507 
509 {
510  int type = m_ui->m_typeComboBox->itemData(idx).toInt();
511 
512  if(type == te::map::EQUAL_STEPS)
513  {
514  m_ui->m_slicesSpinBox->setEnabled(true);
515  m_ui->m_precSpinBox->setEnabled(true);
516  m_ui->m_stdDevDoubleSpinBox->setEnabled(false);
517  }
518  else if(type == te::map::QUANTIL)
519  {
520  m_ui->m_slicesSpinBox->setEnabled(true);
521  m_ui->m_precSpinBox->setEnabled(true);
522  m_ui->m_stdDevDoubleSpinBox->setEnabled(false);
523  }
524  else if(type == te::map::STD_DEVIATION)
525  {
526  m_ui->m_slicesSpinBox->setEnabled(false);
527  m_ui->m_precSpinBox->setEnabled(true);
528  m_ui->m_stdDevDoubleSpinBox->setEnabled(true);
529  }
530  else if(type == te::map::UNIQUE_VALUE)
531  {
532  m_ui->m_slicesSpinBox->setEnabled(false);
533  m_ui->m_precSpinBox->setEnabled(true);
534  m_ui->m_stdDevDoubleSpinBox->setEnabled(false);
535  }
536 
537  if(m_layer.get())
538  listAttributes();
539 }
540 
542 {
543 // int attrType = m_ui->m_attrComboBox->itemData(idx).toInt();
544 }
545 
547 {
548  if(m_layer.get())
549  {
550  buildSymbolizer();
551 
552  updateUi();
553  }
554 }
555 
557 {
558  int index = m_ui->m_typeComboBox->currentIndex();
559  int type = m_ui->m_typeComboBox->itemData(index).toInt();
560 
561  int curRow = m_ui->m_tableWidget->currentRow();
562  int curCol = m_ui->m_tableWidget->currentColumn();
563 
564  QString str = item->text();
565 
566  if(curCol == 1) // title
567  {
568  m_legend[curRow]->setTitle(str.toStdString());
569 
570  m_manual = true;
571  }
572  else if(curCol == 2 || curCol == 3) // min and max
573  {
574  if(type == te::map::EQUAL_STEPS || type == te::map::QUANTIL || type == te::map::STD_DEVIATION)
575  {
576  bool ok = false;
577 
578  str.toDouble(&ok);
579 
580  if(!ok)
581  {
582  if(curCol == 2)
583  item->setText(m_legend[curRow]->getLowerLimit().c_str());
584  else if(curCol ==3)
585  item->setText(m_legend[curRow]->getUpperLimit().c_str());
586  }
587  else
588  {
589  if(curCol == 2)
590  m_legend[curRow]->setLowerLimit(item->text().toStdString());
591  else if(curCol ==3)
592  m_legend[curRow]->setUpperLimit(item->text().toStdString());
593 
594  m_manual = true;
595  }
596  }
597  }
598 }
599 
601 {
602  int index = m_ui->m_typeComboBox->currentIndex();
603  int type = m_ui->m_typeComboBox->itemData(index).toInt();
604 
605  int curRow = m_ui->m_tableWidget->currentRow();
606  int curCol = m_ui->m_tableWidget->currentColumn();
607 
608  if(curCol == 0)
609  {
610  te::map::GroupingItem* gi = m_legend[curRow];
611 
612  std::vector<te::se::Symbolizer*> symbVec = gi->getSymbolizers();
613 
614  QDialog* dialog = new QDialog(this);
615  QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, dialog);
616 
617  QDialogButtonBox* bbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, dialog);
618 
619  QWidget* symbWidget = 0;
620 
621  if(symbVec[0]->getType() == "PolygonSymbolizer")
622  {
623  symbWidget = new te::qt::widgets::PolygonSymbolizerWidget(dialog);
625  polygonSymbolizerWidget->setSymbolizer((te::se::PolygonSymbolizer*)symbVec[0]);
626  }
627  else if(symbVec[0]->getType() == "LineSymbolizer")
628  {
629  symbWidget = new te::qt::widgets::LineSymbolizerWidget(dialog);
631  lineSymbolizerWidget->setSymbolizer((te::se::LineSymbolizer*)symbVec[0]);
632  }
633  else if(symbVec[0]->getType() == "PointSymbolizer")
634  {
635  symbWidget = new te::qt::widgets::PointSymbolizerWidget(dialog);
637  pointSymbolizerWidget->setSymbolizer((te::se::PointSymbolizer*)symbVec[0]);
638  }
639 
640  layout->addWidget(symbWidget);
641  layout->addWidget(bbox);
642 
643  connect(bbox, SIGNAL(accepted()), dialog, SLOT(accept()));
644  connect(bbox, SIGNAL(rejected()), dialog, SLOT(reject()));
645 
646  if(dialog->exec() == QDialog::Rejected)
647  {
648  delete dialog;
649  return;
650  }
651 
652  if(symbVec[0]->getType() == "PolygonSymbolizer")
653  {
654  symbVec.clear();
656  symbVec.push_back(polygonSymbolizerWidget->getSymbolizer());
657  }
658  else if(symbVec[0]->getType() == "LineSymbolizer")
659  {
660  symbVec.clear();
662  symbVec.push_back(lineSymbolizerWidget->getSymbolizer());
663  }
664  else if(symbVec[0]->getType() == "PointSymbolizer")
665  {
666  symbVec.clear();
668  symbVec.push_back(pointSymbolizerWidget->getSymbolizer());
669  }
670 
671  gi->setSymbolizers(symbVec);
672 
673  QPixmap pix = te::qt::widgets::SymbologyPreview::build(symbVec, QSize(24, 24));
674  QIcon icon(pix);
675 
676  QTableWidgetItem* newItem = new QTableWidgetItem(icon, "");
677  newItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
678 
679  m_ui->m_tableWidget->setItem(curRow, 0, newItem);
680 
681  delete dialog;
682 
683  updateUi(true);
684 
685  emit applyPushButtonClicked();
686  }
687 }
688 
689 void te::qt::widgets::GroupingWidget::getDataAsDouble(std::vector<double>& vec, const std::string& attrName, const int& dataType, int& nullValues)
690 {
691  assert(m_layer.get());
692 
693  std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
694 
695  std::size_t idx;
696 
697  for(std::size_t t = 0; t < dsType->getProperties().size(); ++t)
698  {
699  if(dsType->getProperty(t)->getName() == attrName)
700  {
701  idx = t;
702  break;
703  }
704  }
705 
706  std::auto_ptr<te::da::DataSet> ds(m_layer->getData());
707 
708  ds->moveBeforeFirst();
709 
710  while(ds->moveNext())
711  {
712  if(ds->isNull(idx))
713  {
714  ++nullValues;
715  continue;
716  }
717 
718  if(dataType == te::dt::INT16_TYPE)
719  vec.push_back((double)ds->getInt16(idx));
720  else if(dataType == te::dt::INT32_TYPE)
721  vec.push_back((double)ds->getInt32(idx));
722  else if(dataType == te::dt::INT64_TYPE)
723  vec.push_back((double)ds->getInt64(idx));
724  else if(dataType == te::dt::FLOAT_TYPE)
725  vec.push_back((double)ds->getFloat(idx));
726  else if(dataType == te::dt::DOUBLE_TYPE)
727  vec.push_back(ds->getDouble(idx));
728  else if(dataType == te::dt::NUMERIC_TYPE)
729  {
730  QString strNum = ds->getNumeric(idx).c_str();
731 
732  bool ok = false;
733 
734  double value = strNum.toDouble(&ok);
735 
736  if(ok)
737  vec.push_back(value);
738  }
739  }
740 }
741 
742 void te::qt::widgets::GroupingWidget::getDataAsString(std::vector<std::string>& vec, const std::string& attrName, int& nullValues)
743 {
744  assert(m_layer.get());
745 
746  std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
747 
748  std::size_t idx;
749 
750  for(std::size_t t = 0; t < dsType->getProperties().size(); ++t)
751  {
752  if(dsType->getProperty(t)->getName() == attrName)
753  {
754  idx = t;
755  break;
756  }
757  }
758 
759  std::auto_ptr<te::da::DataSet> ds(m_layer->getData());
760 
761  ds->moveBeforeFirst();
762 
763  while(ds->moveNext())
764  {
765  if(!ds->isNull(idx))
766  vec.push_back(ds->getAsString(idx));
767  else
768  ++nullValues;
769  }
770 }
771 
773 {
774  if(count == 0)
775  return;
776 
780  legendItem->setTitle(NO_TITLE);
781  legendItem->setCount(count);
782 
783  int geomType = getGeometryType();
784  std::vector<te::se::Symbolizer*> symbVec;
786  symbVec.push_back(s);
787  legendItem->setSymbolizers(symbVec);
788 
789  m_legend.push_back(legendItem);
790 }
791 
793 {
794  if(count == 0)
795  return;
796 
799  legendItem->setTitle(NO_TITLE);
800  legendItem->setCount(count);
801 
802  int geomType = getGeometryType();
803  std::vector<te::se::Symbolizer*> symbVec;
805  symbVec.push_back(s);
806  legendItem->setSymbolizers(symbVec);
807 
808  m_legend.push_back(legendItem);
809 }
810 
812 {
813  assert(m_layer.get());
814 
815  return te::map::GetGeomType(m_layer);
816 }
817 
819 {
820  delete m_cb;
821 
822  m_cb = m_colorBar->getColorBar()->getColorBar();
823 
824  int legendSize = m_legend.size();
825 
826  std::vector<te::color::RGBAColor> colorVec;
827 
828  if(meanTitle.empty())
829  {
830  colorVec = m_cb->getSlices(legendSize);
831  }
832  else
833  {
834  int beforeMean = 0;
835  int afterMean = 0;
836  int meanIdx = 0;
837 
838  for(size_t t = 0; t < m_legend.size(); ++t)
839  {
840  if(m_legend[t]->getTitle() != meanTitle)
841  {
842  beforeMean++;
843  }
844  else
845  {
846  meanIdx = t;
847  afterMean = m_legend.size() - t - 1;
848  break;
849  }
850  }
851 
852  std::vector<te::color::RGBAColor> lowerColorVec = m_cb->getLowerMeanSlices(beforeMean);
853  te::color::RGBAColor meanColor = m_cb->getMeanSlice();
854  std::vector<te::color::RGBAColor> upperColorVec = m_cb->getUpperMeanSlices(afterMean);
855 
856  for(size_t t = 0; t < lowerColorVec.size(); ++t)
857  colorVec.push_back(lowerColorVec[t]);
858 
859  colorVec.push_back(meanColor);
860 
861  for(size_t t = 0; t < upperColorVec.size(); ++t)
862  colorVec.push_back(upperColorVec[t]);
863  }
864 
865  if(colorVec.size() != m_legend.size())
866  return;
867 
868  int geomType = getGeometryType();
869 
870  for(size_t t = 0; t < colorVec.size(); ++t)
871  {
872  std::vector<te::se::Symbolizer*> symbVec;
873 
874  te::se::Symbolizer* s = te::se::CreateSymbolizer((te::gm::GeomType)geomType, colorVec[t].getColor());
875 
876  symbVec.push_back(s);
877 
878  m_legend[t]->setSymbolizers(symbVec);
879  }
880 }
881 
883 {
884  QString curValue = m_ui->m_attrComboBox->currentText();
885 
886  m_ui->m_attrComboBox->clear();
887 
888  std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
889 
890  //grouping type
891  int index = m_ui->m_typeComboBox->currentIndex();
892  int type = m_ui->m_typeComboBox->itemData(index).toInt();
893 
894  if(type == te::map::EQUAL_STEPS ||type == te::map::QUANTIL || type == te::map::STD_DEVIATION)
895  {
896  for(size_t t = 0; t < dsType->getProperties().size(); ++t)
897  {
898  te::dt::Property* p = dsType->getProperty(t);
899 
900  int dataType = p->getType();
901 
902  switch(dataType)
903  {
904  case te::dt::INT16_TYPE:
905  case te::dt::INT32_TYPE:
906  case te::dt::INT64_TYPE:
907  case te::dt::FLOAT_TYPE:
908  case te::dt::DOUBLE_TYPE:
910  m_ui->m_attrComboBox->addItem(p->getName().c_str(), p->getType());
911 
912  default:
913  continue;
914  }
915  }
916  }
917  else if(type == te::map::UNIQUE_VALUE)
918  {
919  for(size_t t = 0; t < dsType->getProperties().size(); ++t)
920  {
921  te::dt::Property* p = dsType->getProperty(t);
922 
923  int dataType = p->getType();
924 
925  switch(dataType)
926  {
927  case te::dt::INT16_TYPE:
928  case te::dt::INT32_TYPE:
929  case te::dt::INT64_TYPE:
930  case te::dt::FLOAT_TYPE:
931  case te::dt::DOUBLE_TYPE:
933  case te::dt::STRING_TYPE:
934  m_ui->m_attrComboBox->addItem(p->getName().c_str(), p->getType());
935 
936  default:
937  continue;
938  }
939  }
940  }
941 
942  if(curValue.isEmpty() == false)
943  {
944  int idx = m_ui->m_attrComboBox->findText(curValue);
945 
946  if(idx != -1)
947  m_ui->m_attrComboBox->setCurrentIndex(idx);
948  }
949 }
950 
951 void te::qt::widgets::GroupingWidget::setLayers(te::map::AbstractLayerPtr selectedLayer, std::vector<te::map::AbstractLayerPtr> allLayers)
952 {
953  m_layer = selectedLayer;
954 
955  //set data type
956  setDataSetType();
957 
958  //set grouping
959  setGrouping();
960 
961  for(std::size_t i = 0; i < allLayers.size(); ++i)
962  {
963  if(!allLayers[i]->isValid())
964  continue;
965 
966  std::auto_ptr<te::da::DataSetType> dt(allLayers[i]->getSchema());
967 
968  if(dt->hasGeom() && allLayers[i]->getGrouping() && allLayers[i]->getId() != selectedLayer->getId())
969  {
970  m_ui->m_layersComboBox->addItem(allLayers[i]->getTitle().c_str(), QVariant::fromValue(allLayers[i]));
971  }
972  }
973 }
974 
976 {
977  if(m_ui->m_layersComboBox->currentText() == "")
978  {
979  QMessageBox::warning(this, tr("Grouping"), tr("There are no other layers with Grouping!"));
980  return;
981  }
982 
983  if(m_manual)
984  {
985  int reply = QMessageBox::question(this, tr("Grouping"), tr("Manual changes will be lost. Continue?"), QMessageBox::Yes | QMessageBox::Cancel);
986 
987  if(reply != QMessageBox::Yes)
988  return;
989  }
990 
991  QVariant varLayer = m_ui->m_layersComboBox->itemData(m_ui->m_layersComboBox->currentIndex(), Qt::UserRole);
992  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
993 
994  te::map::Grouping* ref = layer->getGrouping();
995 
996  std::auto_ptr<te::da::DataSetType> dt = m_layer->getSchema();
997 
998  std::vector<te::dt::Property*> props = dt->getProperties();
999 
1000  bool isValid = false;
1001  for(std::size_t i = 0; i < props.size(); ++i)
1002  {
1003  te::dt::Property* prop = props[i];
1004  if((prop->getName() == ref->getPropertyName()) && (prop->getType() == ref->getPropertyType()))
1005  {
1006  isValid = true;
1007  break;
1008  }
1009  }
1010 
1011  if(!isValid)
1012  {
1013  QMessageBox::warning(this, tr("Grouping"), tr("In existing layers, there is no grouping that can be imported!"));
1014  return;
1015  }
1016 
1017  te::map::Grouping* newGrouping = new te::map::Grouping(*ref);
1018 
1019  setGrouping(newGrouping);
1020 
1021  updateUi(true);
1022 
1023  m_manual = false;
1024 
1025  emit applyPushButtonClicked();
1026 }
void createStringNullGroupingItem(int count)
void setValue(const std::string &value)
It sets value of the legend item.
void onTableWidgetItemChanged(QTableWidgetItem *item)
std::auto_ptr< te::map::Grouping > getGrouping()
const double getStdDeviation() const
It gets the standard deviation used in the Standard Deviation grouping.
Definition: Grouping.cpp:118
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
A widget used to build a point symbolizer element.
A PolygonSymbolizer is used to draw a polygon (or other area-type geometries), including filling its ...
TESEEXPORT Symbolizer * CreateSymbolizer(const te::gm::GeomType &geomType)
Try creates an appropriate symbolizer based on given geometry type.
Definition: Utils.cpp:220
const std::string & getValue() const
It gets the value of the legend item.
const size_t getPrecision() const
It gets the precision used for the property values.
Definition: Grouping.cpp:98
A Symbolizer describes how a feature is to appear on a map.
Definition: Symbolizer.h:80
#define PRECISION
std::string getPropertyName() const
It gets the property name whose values will be grouped.
Definition: Grouping.cpp:66
void setSymbolizer(const te::se::PointSymbolizer *symb)
Sets a point symbolizer element to this widget.
TEMAPEXPORT te::gm::GeomType GetGeomType(const te::map::AbstractLayerPtr &layer)
It gets the geometry type of the given layer.
Definition: Utils.cpp:717
void addColor(const RGBAColor &color, const double &pos)
It adds a color in the color bar.
Definition: ColorBar.cpp:264
A widget used to build a line symbolizer element.
A PointSymbolizer specifies the rendering of a graphic Symbolizer at a point.
void setTitle(const std::string &title)
It sets the title of the legend item.
void GroupingByEqualSteps(iterator begin, iterator end, int nSteps, std::vector< te::map::GroupingItem * > &legend, int precision=0, bool countElements=true)
It groups the values defined by a range of iterators using the equal steps algorithm.
It models a property definition.
Definition: Property.h:59
void setColorBar(te::color::ColorBar *cb)
It sets the color bar.
Definition: ColorBar.cpp:108
#define MAX_SLICES
te::se::Symbolizer * getSymbolizer() const
Gets the configured point symbolizer element.
void GroupingByStdDeviation(iterator begin, iterator end, double nDevs, std::vector< te::map::GroupingItem * > &legend, std::string &meanTitle, int precision=0, bool countElements=true)
It groups the values defined by a range of iterators using the standard deviation algorithm...
This class contains the parameters needed for grouping the values of a Property.
Definition: Grouping.h:59
std::auto_ptr< Ui::GroupingWidgetForm > m_ui
Widget form.
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
A GroupingItem contains information about a grouping item associated to a layer.
Definition: GroupingItem.h:48
GroupingWidget(QWidget *parent=0, Qt::WindowFlags f=0)
Constructs a basic fill widget which is a child of parent, with widget flags set to f...
It QWidget implementation of color bar.
Definition: ColorBar.h:67
te::se::Symbolizer * getSymbolizer() const
Gets the configured line symbolizer element.
void buildSymbolizer(std::string meanTitle="")
void GroupingByQuantil(iterator begin, iterator end, int nSteps, std::vector< te::map::GroupingItem * > &legend, int precision=0, bool countElements=true)
It groups the values defined by a range of iterators using the quantil algorithm. ...
A Symbology Enconding visitor that finds a color given a symbolizer element. If you want to use this ...
void initialize()
Internal method to initialize the widget (e.g.: color, combos, icons, etc.)
A widget used to build a polygon symbolizer element.
void onTableWidgetItemDoubleClicked(QTableWidgetItem *item)
void createDoubleNullGroupingItem(int count)
int getType() const
It returns the property data type.
Definition: Property.h:143
void find(const te::se::Symbolizer *symbolizer)
It find the color based on given symbolizer.
const std::vector< te::map::GroupingItem * > & getGroupingItems() const
It gets the vector of grouping items.
Definition: Grouping.cpp:128
GroupingType
The grouping type associated to the layer.
Definition: Enums.h:150
void updateUi(bool loadColorBar=false)
Updates the widget form based on internal fill element.
const std::string & getUpperLimit() const
It gets the upper limit value of the legend item.
TEMAPEXPORT void GroupingByUniqueValues(std::vector< std::string > &inputValues, int dataType, std::vector< te::map::GroupingItem * > &legend, int precision)
It groups the values using the unique value algorithm.
#define NO_TITLE
void setCount(std::size_t count)
It It sets the number of objects whose values are between the lower and upper limits.
void getDataAsString(std::vector< std::string > &vec, const std::string &attrName, int &nullValues)
void setLayers(te::map::AbstractLayerPtr selectedLayer, std::vector< te::map::AbstractLayerPtr > allLayers)
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
te::color::ColorBar * getColorBar()
It returns the colorbar.
Definition: ColorBar.cpp:117
void setUpperLimit(const std::string &to)
It sets the upper limit value of the legend item.
const GroupingType getType() const
It gets the grouping type.
Definition: Grouping.cpp:88
void setSymbolizer(const te::se::PolygonSymbolizer *symb)
Sets a polygon symbolizer element to this widget.
It models the concept of color bar.
Definition: ColorBar.h:49
void getDataAsDouble(std::vector< double > &vec, const std::string &attrName, const int &dataType, int &nullValues)
A widget used to build a grouping.
A LineSymbolizer is used to style a stroke along a linear geometry type, such as a string of line seg...
const size_t getNumSlices() const
It gets the number of slices used in the Equal Steps and Quantil groupings.
Definition: Grouping.cpp:108
std::size_t getCount() const
It gets the number of objects whose values are between the lower and upper limits.
te::qt::widgets::ColorCatalogWidget * m_colorBar
Widget used to pick a color.
std::string getTitle()
It gets the title of the legend item.
const std::string & getLowerLimit() const
It gets the lower limit value of the legend item.
te::color::RGBAColor getColor()
Get the color.
const std::vector< te::se::Symbolizer * > & getSymbolizers() const
It gets the symbolizer of the legend item.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
static QPixmap build(const te::se::Symbolizer *symb, const QSize &size)
Generates the preview of given symbolizer element.
te::se::Symbolizer * getSymbolizer() const
Gets the configured polygon symbolizer element.
void setSymbolizer(const te::se::LineSymbolizer *symb)
Sets a line symbolizer element to this widget.
void setSymbolizers(const std::vector< te::se::Symbolizer * > &symbolizers)
It sets the symbolizers of the legend item.
static const std::string sm_nanStr
Not a number string value.
Definition: Globals.h:56
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
void setLowerLimit(const std::string &from)
It sets the lower limit value of the legend item.