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"
48 #include "ui_GroupingWidgetForm.h"
54 #include <QDialogButtonBox>
55 #include <QMessageBox>
57 #define MAX_SLICES 200
59 #define NO_TITLE "No Value"
65 m_ui(new Ui::GroupingWidgetForm),
70 QGridLayout* l =
new QGridLayout(
m_ui->m_colorBarWidget);
71 l->setContentsMargins(0,0,0,0);
97 if(m_ui->m_importGroupBox->isChecked())
99 QVariant varLayer = m_ui->m_layersComboBox->itemData(m_ui->m_layersComboBox->currentIndex(), Qt::UserRole);
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();
113 int index = m_ui->m_typeComboBox->currentIndex();
114 int type = m_ui->m_typeComboBox->itemData(index).toInt();
118 group->setPropertyType(attrType);
120 group->setNumSlices(m_ui->m_slicesSpinBox->value());
122 group->setPrecision(m_ui->m_precSpinBox->value());
124 group->setStdDeviation(m_ui->m_stdDevDoubleSpinBox->value());
126 std::vector<te::map::GroupingItem*> groupingItems;
127 for(std::size_t t = 0; t < m_legend.size(); ++t)
131 groupingItems.push_back(gi);
133 group->setGroupingItems(groupingItems);
141 m_colorBar->getColorBar()->setHeight(20);
142 m_colorBar->getColorBar()->setScaleVisible(
false);
150 onTypeComboBoxActivated(0);
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);
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);
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);
171 m_ui->m_tableWidget->resizeColumnsToContents();
172 #if (QT_VERSION >= 0x050000)
173 m_ui->m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
175 m_ui->m_tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
183 disconnect(m_ui->m_tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
this, SLOT(onTableWidgetItemChanged(QTableWidgetItem*)));
185 m_ui->m_tableWidget->setRowCount(0);
187 int index = m_ui->m_typeComboBox->currentIndex();
188 int type = m_ui->m_typeComboBox->itemData(index).toInt();
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"));
199 m_ui->m_tableWidget->setColumnCount(5);
200 m_ui->m_tableWidget->setHorizontalHeaderLabels(list);
205 list.append(tr(
"Symbol"));
206 list.append(tr(
"Title"));
207 list.append(tr(
"Value"));
208 list.append(tr(
"Count"));
210 m_ui->m_tableWidget->setColumnCount(4);
211 m_ui->m_tableWidget->setHorizontalHeaderLabels(list);
218 if(!m_legend.empty() && !m_legend[0]->getSymbolizers().empty() && !m_legend[m_legend.size() - 1]->getSymbolizers().empty())
222 scf.
find(m_legend[0]->getSymbolizers()[0]);
225 scf.
find(m_legend[m_legend.size() - 1]->getSymbolizers()[0]);
234 for(std::size_t t = 0; t < m_legend.size(); ++t)
238 int newrow = m_ui->m_tableWidget->rowCount();
239 m_ui->m_tableWidget->insertRow(newrow);
243 const std::vector<te::se::Symbolizer*>& ss = gi->
getSymbolizers();
246 QTableWidgetItem* item =
new QTableWidgetItem(icon,
"");
247 item->setFlags(Qt::ItemIsEnabled);
248 m_ui->m_tableWidget->setItem(newrow, 0, item);
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);
260 if(count != 0 && count != m_legend.size() - 1)
262 double pos = (1. / (m_legend.size() - 1)) * count;
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);
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);
300 QTableWidgetItem* item =
new QTableWidgetItem(QString::number(gi->
getCount()));
301 item->setFlags(Qt::ItemIsEnabled);
302 m_ui->m_tableWidget->setItem(newrow, 4, item);
310 QTableWidgetItem* item =
new QTableWidgetItem(QString::fromStdString(gi->
getValue()));
311 item->setFlags(Qt::ItemIsEnabled);
312 m_ui->m_tableWidget->setItem(newrow, 2, item);
316 QTableWidgetItem* item =
new QTableWidgetItem(QString::number(gi->
getCount()));
317 item->setFlags(Qt::ItemIsEnabled);
318 m_ui->m_tableWidget->setItem(newrow, 3, item);
325 disconnect(m_colorBar, SIGNAL(colorBarChanged()),
this, SLOT(onColorBarChanged()));
330 connect(m_colorBar, SIGNAL(colorBarChanged()),
this, SLOT(onColorBarChanged()));
333 m_ui->m_tableWidget->resizeColumnsToContents();
334 #if (QT_VERSION >= 0x050000)
335 m_ui->m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
337 m_ui->m_tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
340 connect(m_ui->m_tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
this, SLOT(onTableWidgetItemChanged(QTableWidgetItem*)));
352 setGrouping(grouping);
354 emit applyPushButtonClicked();
365 for(
int i = 0; i < m_ui->m_typeComboBox->count(); ++i)
367 if(type == m_ui->m_typeComboBox->itemData(i).toInt())
369 m_ui->m_typeComboBox->setCurrentIndex(i);
371 onTypeComboBoxActivated(i);
380 for(
int i = 0; i < m_ui->m_attrComboBox->count(); ++i)
382 if(attrName == m_ui->m_attrComboBox->itemText(i).toStdString())
384 m_ui->m_attrComboBox->setCurrentIndex(i);
392 m_ui->m_precSpinBox->setValue((
int)prec);
397 m_ui->m_slicesSpinBox->setValue((
int)slices);
402 m_ui->m_stdDevDoubleSpinBox->setValue((
double)stdDev);
412 m_legend.push_back(gi);
417 onApplyPushButtonClicked();
424 int reply = QMessageBox::question(
this, tr(
"Classification"), tr(
"Manual changes will be lost. Continue?"), QMessageBox::Yes | QMessageBox::Cancel);
426 if(reply != QMessageBox::Yes)
430 int index = m_ui->m_typeComboBox->currentIndex();
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();
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();
444 std::string mean =
"";
452 std::vector<double> vec;
454 getDataAsDouble(vec, attr, attrType, nullValues);
458 buildSymbolizer(mean);
460 createDoubleNullGroupingItem(nullValues);
464 std::vector<double> vec;
466 getDataAsDouble(vec, attr, attrType, nullValues);
470 buildSymbolizer(mean);
472 createDoubleNullGroupingItem(nullValues);
476 std::vector<double> vec;
478 getDataAsDouble(vec, attr, attrType, nullValues);
482 buildSymbolizer(mean);
484 createDoubleNullGroupingItem(nullValues);
490 std::vector<std::string> vec;
492 getDataAsString(vec, attr, nullValues);
496 buildSymbolizer(mean);
498 createStringNullGroupingItem(nullValues);
505 emit applyPushButtonClicked();
510 int type = m_ui->m_typeComboBox->itemData(idx).toInt();
514 m_ui->m_slicesSpinBox->setEnabled(
true);
515 m_ui->m_precSpinBox->setEnabled(
true);
516 m_ui->m_stdDevDoubleSpinBox->setEnabled(
false);
520 m_ui->m_slicesSpinBox->setEnabled(
true);
521 m_ui->m_precSpinBox->setEnabled(
true);
522 m_ui->m_stdDevDoubleSpinBox->setEnabled(
false);
526 m_ui->m_slicesSpinBox->setEnabled(
false);
527 m_ui->m_precSpinBox->setEnabled(
true);
528 m_ui->m_stdDevDoubleSpinBox->setEnabled(
true);
532 m_ui->m_slicesSpinBox->setEnabled(
false);
533 m_ui->m_precSpinBox->setEnabled(
true);
534 m_ui->m_stdDevDoubleSpinBox->setEnabled(
false);
558 int index = m_ui->m_typeComboBox->currentIndex();
559 int type = m_ui->m_typeComboBox->itemData(index).toInt();
561 int curRow = m_ui->m_tableWidget->currentRow();
562 int curCol = m_ui->m_tableWidget->currentColumn();
564 QString str = item->text();
568 m_legend[curRow]->setTitle(str.toStdString());
572 else if(curCol == 2 || curCol == 3)
583 item->setText(m_legend[curRow]->getLowerLimit().c_str());
585 item->setText(m_legend[curRow]->getUpperLimit().c_str());
590 m_legend[curRow]->setLowerLimit(item->text().toStdString());
592 m_legend[curRow]->setUpperLimit(item->text().toStdString());
602 int index = m_ui->m_typeComboBox->currentIndex();
603 int type = m_ui->m_typeComboBox->itemData(index).toInt();
605 int curRow = m_ui->m_tableWidget->currentRow();
606 int curCol = m_ui->m_tableWidget->currentColumn();
614 QDialog* dialog =
new QDialog(
this);
615 QBoxLayout* layout =
new QBoxLayout(QBoxLayout::TopToBottom, dialog);
617 QDialogButtonBox* bbox =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, dialog);
619 QWidget* symbWidget = 0;
621 if(symbVec[0]->getType() ==
"PolygonSymbolizer")
627 else if(symbVec[0]->getType() ==
"LineSymbolizer")
633 else if(symbVec[0]->getType() ==
"PointSymbolizer")
640 layout->addWidget(symbWidget);
641 layout->addWidget(bbox);
643 connect(bbox, SIGNAL(accepted()), dialog, SLOT(accept()));
644 connect(bbox, SIGNAL(rejected()), dialog, SLOT(reject()));
646 if(dialog->exec() == QDialog::Rejected)
652 if(symbVec[0]->getType() ==
"PolygonSymbolizer")
658 else if(symbVec[0]->getType() ==
"LineSymbolizer")
664 else if(symbVec[0]->getType() ==
"PointSymbolizer")
676 QTableWidgetItem* newItem =
new QTableWidgetItem(icon,
"");
677 newItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
679 m_ui->m_tableWidget->setItem(curRow, 0, newItem);
685 emit applyPushButtonClicked();
691 assert(m_layer.get());
693 std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
697 for(std::size_t t = 0; t < dsType->getProperties().size(); ++t)
699 if(dsType->getProperty(t)->getName() == attrName)
706 std::auto_ptr<te::da::DataSet> ds(m_layer->getData());
708 ds->moveBeforeFirst();
710 while(ds->moveNext())
719 vec.push_back((
double)ds->getInt16(idx));
721 vec.push_back((
double)ds->getInt32(idx));
723 vec.push_back((
double)ds->getInt64(idx));
725 vec.push_back((
double)ds->getFloat(idx));
727 vec.push_back(ds->getDouble(idx));
730 QString strNum = ds->getNumeric(idx).c_str();
734 double value = strNum.toDouble(&ok);
737 vec.push_back(value);
744 assert(m_layer.get());
746 std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
750 for(std::size_t t = 0; t < dsType->getProperties().size(); ++t)
752 if(dsType->getProperty(t)->getName() == attrName)
759 std::auto_ptr<te::da::DataSet> ds(m_layer->getData());
761 ds->moveBeforeFirst();
763 while(ds->moveNext())
766 vec.push_back(ds->getAsString(idx));
783 int geomType = getGeometryType();
784 std::vector<te::se::Symbolizer*> symbVec;
786 symbVec.push_back(s);
789 m_legend.push_back(legendItem);
802 int geomType = getGeometryType();
803 std::vector<te::se::Symbolizer*> symbVec;
805 symbVec.push_back(s);
808 m_legend.push_back(legendItem);
813 assert(m_layer.get());
822 m_cb = m_colorBar->getColorBar()->getColorBar();
824 int legendSize = m_legend.size();
826 std::vector<te::color::RGBAColor> colorVec;
828 if(meanTitle.empty())
830 colorVec = m_cb->getSlices(legendSize);
838 for(
size_t t = 0; t < m_legend.size(); ++t)
840 if(m_legend[t]->getTitle() != meanTitle)
847 afterMean = m_legend.size() - t - 1;
852 std::vector<te::color::RGBAColor> lowerColorVec = m_cb->getLowerMeanSlices(beforeMean);
854 std::vector<te::color::RGBAColor> upperColorVec = m_cb->getUpperMeanSlices(afterMean);
856 for(
size_t t = 0; t < lowerColorVec.size(); ++t)
857 colorVec.push_back(lowerColorVec[t]);
859 colorVec.push_back(meanColor);
861 for(
size_t t = 0; t < upperColorVec.size(); ++t)
862 colorVec.push_back(upperColorVec[t]);
865 if(colorVec.size() != m_legend.size())
868 int geomType = getGeometryType();
870 for(
size_t t = 0; t < colorVec.size(); ++t)
872 std::vector<te::se::Symbolizer*> symbVec;
876 symbVec.push_back(s);
878 m_legend[t]->setSymbolizers(symbVec);
884 QString curValue = m_ui->m_attrComboBox->currentText();
886 m_ui->m_attrComboBox->clear();
888 std::auto_ptr<te::map::LayerSchema> dsType(m_layer->getSchema());
891 int index = m_ui->m_typeComboBox->currentIndex();
892 int type = m_ui->m_typeComboBox->itemData(index).toInt();
896 for(
size_t t = 0; t < dsType->getProperties().size(); ++t)
910 m_ui->m_attrComboBox->addItem(p->
getName().c_str(), p->
getType());
919 for(
size_t t = 0; t < dsType->getProperties().size(); ++t)
934 m_ui->m_attrComboBox->addItem(p->
getName().c_str(), p->
getType());
942 if(curValue.isEmpty() ==
false)
944 int idx = m_ui->m_attrComboBox->findText(curValue);
947 m_ui->m_attrComboBox->setCurrentIndex(idx);
953 m_layer = selectedLayer;
961 for(std::size_t i = 0; i < allLayers.size(); ++i)
963 if(!allLayers[i]->isValid())
966 std::auto_ptr<te::da::DataSetType> dt(allLayers[i]->getSchema());
968 if(dt->hasGeom() && allLayers[i]->getGrouping() && allLayers[i]->getId() != selectedLayer->getId())
970 m_ui->m_layersComboBox->addItem(allLayers[i]->getTitle().c_str(), QVariant::fromValue(allLayers[i]));
977 if(m_ui->m_layersComboBox->currentText() ==
"")
979 QMessageBox::warning(
this, tr(
"Grouping"), tr(
"There are no other layers with Grouping!"));
985 int reply = QMessageBox::question(
this, tr(
"Grouping"), tr(
"Manual changes will be lost. Continue?"), QMessageBox::Yes | QMessageBox::Cancel);
987 if(reply != QMessageBox::Yes)
991 QVariant varLayer = m_ui->m_layersComboBox->itemData(m_ui->m_layersComboBox->currentIndex(), Qt::UserRole);
996 std::auto_ptr<te::da::DataSetType> dt = m_layer->getSchema();
998 std::vector<te::dt::Property*> props = dt->getProperties();
1000 bool isValid =
false;
1001 for(std::size_t i = 0; i < props.size(); ++i)
1004 if((prop->
getName() == ref->getPropertyName()) && (prop->
getType() == ref->getPropertyType()))
1013 QMessageBox::warning(
this, tr(
"Grouping"), tr(
"In existing layers, there is no grouping that can be imported!"));
1019 setGrouping(newGrouping);
1025 emit applyPushButtonClicked();
void setValue(const std::string &value)
It sets value of the legend item.
const double getStdDeviation() const
It gets the standard deviation used in the Standard Deviation grouping.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
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.
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.
A Symbolizer describes how a feature is to appear on a map.
std::string getPropertyName() const
It gets the property name whose values will be grouped.
TEMAPEXPORT te::gm::GeomType GetGeomType(const te::map::AbstractLayerPtr &layer)
It gets the geometry type of the given layer.
void addColor(const RGBAColor &color, const double &pos)
It adds a color in the color bar.
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.
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.
A GroupingItem contains information about a grouping item associated to a layer.
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 ...
int getType() const
It returns the property data type.
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.
GroupingType
The grouping type associated to the layer.
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.
void setCount(std::size_t count)
It It sets the number of objects whose values are between the lower and upper limits.
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
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.
It models the concept of color bar.
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.
std::size_t getCount() const
It gets the number of objects whose values are between the lower and upper limits.
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...
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.
const std::string & getName() const
It returns the property name.
void setLowerLimit(const std::string &from)
It sets the lower limit value of the legend item.