27 #include "../../../common/STLUtils.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/utils/Utils.h"
30 #include "../../../geometry/Point.h"
31 #include "../../../maptools/MarkRendererManager.h"
32 #include "../../../raster/Raster.h"
33 #include "../../../rp/MixtureModel.h"
34 #include "../../../rp/MixtureModelLinearStrategy.h"
35 #include "../../../rp/MixtureModelPCAStrategy.h"
36 #include "../../../rp/Functions.h"
37 #include "../../../se/Fill.h"
38 #include "../../../se/Mark.h"
39 #include "../../../se/Stroke.h"
40 #include "../../../se/Utils.h"
41 #include "../canvas/Canvas.h"
42 #include "../canvas/MapDisplay.h"
46 #include "ui_MixtureModelWizardPageForm.h"
49 #include <QFileDialog>
50 #include <QGridLayout>
51 #include <QMessageBox>
54 #include <boost/foreach.hpp>
55 #include <boost/property_tree/ptree.hpp>
56 #include <boost/property_tree/json_parser.hpp>
57 #include <boost/uuid/random_generator.hpp>
58 #include <boost/uuid/uuid_io.hpp>
64 #define PATTERN_SIZE 12
67 : QWizardPage(parent),
68 m_ui(new Ui::MixtureModelWizardPageForm),
75 m_ui->m_loadToolButton->setIcon(QIcon::fromTheme(
"document-open"));
76 m_ui->m_saveToolButton->setIcon(QIcon::fromTheme(
"document-save"));
88 connect(
m_ui->m_tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
this, SLOT(
onItemChanged(QTableWidgetItem*)));
90 connect(
m_ui->m_acquireToolButton, SIGNAL(toggled(
bool)),
this, SLOT(
showNavigator(
bool)));
109 this->setTitle(tr(
"Mixture Model"));
110 this->setSubTitle(tr(
"Select the type of mixture model and set their specific parameters."));
112 m_ui->m_removeToolButton->setIcon(QIcon::fromTheme(
"list-remove"));
113 m_ui->m_acquireToolButton->setIcon(QIcon::fromTheme(
"wand"));
118 m_components.clear();
127 if(m_ui->m_tableWidget->rowCount() == 0)
130 int nBands = m_ui->m_bandTableWidget->rowCount();
132 bool isChecked =
false;
134 std::size_t count = 0;
135 for(
int i = 0; i < nBands; ++i)
137 QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
139 if(checkBox->isChecked())
149 if(count != m_components.size())
159 m_navigatorDlg->set(m_layer);
171 int idx = m_ui->m_typeComboBox->currentIndex();
172 int type = m_ui->m_typeComboBox->itemData(idx).toInt();
176 if(type == MIXMODEL_LINEAR)
183 else if(type == MIXMODEL_PCA)
192 unsigned selectedBands = 0;
193 std::vector<bool> selectedBandsVector;
195 for (
int i = 0; i < m_ui->m_bandTableWidget->rowCount(); ++i)
197 QCheckBox* bandCheckBox = (QCheckBox*) m_ui->m_bandTableWidget->cellWidget(i, 0);
199 if (bandCheckBox->isChecked())
201 selectedBandsVector.push_back(
true);
206 QComboBox *sensorComboBox = (QComboBox*) m_ui->m_bandTableWidget->cellWidget(i, 1);
207 algoInputParams.
m_inputSensorBands.push_back(std::string(sensorComboBox->currentText().toStdString()));
210 selectedBandsVector.push_back(
false);
214 std::map<std::string, MixModelComponent>::iterator it = m_components.begin();
215 std::vector<double> components;
217 while(it != m_components.end())
221 for (
unsigned int i = 0; i < selectedBandsVector.size(); i++)
222 if (selectedBandsVector[i])
223 components.push_back(it->second.m_values[i]);
225 algoInputParams.
m_components[it->second.m_name] = components;
231 return algoInputParams;
238 algoOutputParams.
m_normalizeOutput = m_ui->m_normalizeOutputCheckBox->isChecked();
241 return algoOutputParams;
246 boost::property_tree::ptree pt;
248 std::map<std::string, MixModelComponent >::iterator it = m_components.begin();
250 boost::property_tree::ptree children;
252 while(it != m_components.end())
254 boost::property_tree::ptree child;
256 child.put(
"id", it->first);
257 child.put(
"name", it->second.m_name);
259 boost::property_tree::ptree coordGrid;
260 coordGrid.put(
"xGrid", it->second.m_coordGrid.getX());
261 coordGrid.put(
"yGrid", it->second.m_coordGrid.getY());
262 child.push_back(std::make_pair(
"coordGrid", coordGrid));
264 boost::property_tree::ptree coordGeo;
265 coordGeo.put(
"xGeo", it->second.m_coordGeo.getX());
266 coordGeo.put(
"yGeo", it->second.m_coordGeo.getY());
267 child.push_back(std::make_pair(
"coordGeo", coordGeo));
269 boost::property_tree::ptree values;
271 for(std::size_t t = 0; t < it->second.m_values.size(); ++t)
273 boost::property_tree::ptree val;
274 val.put(
"value", it->second.m_values[t]);
275 values.push_back(std::make_pair(
"", val));
278 child.add_child(
"Values", values);
280 children.push_back(std::make_pair(
"Component", child));
285 pt.add_child(
"MixModel_Components", children);
287 boost::property_tree::json_parser::write_json(fileName, pt);
294 boost::property_tree::ptree pt;
295 boost::property_tree::json_parser::read_json(fileName, pt);
297 BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child(
"MixModel_Components"))
299 std::string
id = v.second.get<std::string>(
"id");
300 std::string name = v.second.get<std::string>(
"name");
302 int xGrid = v.second.get<
int>(
"coordGrid.xGrid");
303 int yGrid = v.second.get<
int>(
"coordGrid.yGrid");
305 double xGeo = v.second.get<
double>(
"coordGeo.xGeo");
306 double yGeo = v.second.get<
double>(
"coordGeo.yGeo");
308 std::vector<double> valuesVec;
309 BOOST_FOREACH(boost::property_tree::ptree::value_type &c, v.second.get_child(
"Values"))
311 double val = c.second.get<
double>(
"value");
313 valuesVec.push_back(val);
323 m_components.insert(std::map<std::string, MixModelComponent >::value_type(
id, mmc));
328 catch(boost::property_tree::json_parser::json_parser_error &je)
330 QString errmsg = tr(
"Error parsing: ") + je.filename().c_str() +
": " + je.message().c_str();
332 QMessageBox::warning(
this, tr(
"Warning"), errmsg);
336 catch (std::exception
const& e)
338 QString errmsg = e.what();
340 QMessageBox::warning(
this, tr(
"Warning"), errmsg);
346 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save MixModel Components"),
"",
"JSON File (*.json)");
348 if(!fileName.isEmpty())
349 saveMixtureModelComponents(fileName.toStdString());
354 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Load MixModel Components"),
"",
"JSON File (*.json)");
356 if(!fileName.isEmpty())
357 loadMixtureModelComponents(fileName.toStdString());
362 if(m_components.empty() ==
false)
368 assert(m_layer.get());
371 std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
376 std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
382 int currentColumn = pixelLocation.
x;
383 int currentRow = pixelLocation.
y;
385 if (currentColumn < 0 || currentColumn >= (
int) inputRst->getNumberOfColumns())
387 if (currentRow < 0 || currentRow >= (
int) inputRst->getNumberOfRows())
391 static boost::uuids::basic_random_generator<boost::mt19937> gen;
392 boost::uuids::uuid u = gen();
393 std::string
id = boost::uuids::to_string(u);
396 QString className = QString(tr(
"Component ") + QString::number(m_countComponents++));
399 std::vector<double> componentsVector;
402 for(
unsigned b = 0 ; b < inputRst->getNumberOfBands(); b++)
404 inputRst->getValue(currentColumn, currentRow, value, b);
406 componentsVector.push_back(value);
415 mmc.
m_name = className.toStdString();
420 m_components.insert(std::map<std::string, MixModelComponent >::value_type(
id, mmc));
429 std::string
id = item->data(Qt::UserRole).toString().toStdString();
431 std::string name = item->text().toStdString();
433 std::map<std::string, MixModelComponent >::iterator it = m_components.find(
id);
437 if(it != m_components.end())
439 if(it->second.m_name != name)
441 it->second.m_name = name;
452 if(m_ui->m_tableWidget->currentRow() == -1)
455 std::string
id = m_ui->m_tableWidget->item(m_ui->m_tableWidget->currentRow(), 0)->data(Qt::UserRole).toString().toStdString();
457 std::map<std::string, MixModelComponent >::iterator it = m_components.find(
id);
459 if(it != m_components.end())
461 m_components.erase(it);
463 if(m_components.empty())
464 m_countComponents = 0;
473 m_navigatorDlg->show();
475 m_navigatorDlg->hide();
480 m_ui->m_acquireToolButton->setChecked(
false);
485 m_ui->m_typeComboBox->clear();
487 m_ui->m_typeComboBox->addItem(tr(
"Linear"), MIXMODEL_LINEAR);
488 m_ui->m_typeComboBox->addItem(tr(
"PCA - Principal Component Analysis"), MIXMODEL_PCA);
493 assert(m_layer.get());
496 std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
501 std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
506 QStringList sensorsDescriptions;
509 for(
unsigned int i = 0; i < bandNames.size(); i++)
510 sensorsDescriptions.append(bandNames[i].c_str());
512 m_ui->m_bandTableWidget->setRowCount(0);
515 for(
unsigned b = 0 ; b < inputRst->getNumberOfBands(); b++)
517 int newrow = m_ui->m_bandTableWidget->rowCount();
518 m_ui->m_bandTableWidget->insertRow(newrow);
520 QString bName(tr(
"Band "));
521 bName.append(QString::number(b));
523 QCheckBox* bandCheckBox =
new QCheckBox(bName,
this);
525 connect(bandCheckBox, SIGNAL(stateChanged(
int)),
this, SIGNAL(completeChanged()));
527 bandCheckBox->setChecked(
true);
529 QComboBox* sensorDescriptionComboBox =
new QComboBox(
this);
530 sensorDescriptionComboBox->addItems(sensorsDescriptions);
532 m_ui->m_bandTableWidget->setCellWidget(newrow, 0, bandCheckBox);
533 m_ui->m_bandTableWidget->setCellWidget(newrow, 1, sensorDescriptionComboBox);
536 m_ui->m_bandTableWidget->resizeColumnToContents(0);
554 std::map<std::string, MixModelComponent>::iterator it = m_components.begin();
556 while(it != m_components.end())
564 canvasInstance.draw(&point);
569 mapDisplay->repaint();
574 m_ui->m_tableWidget->setRowCount(0);
576 std::map<std::string, MixModelComponent>::iterator it = m_components.begin();
578 while(it != m_components.end())
580 int newrow = m_ui->m_tableWidget->rowCount();
581 m_ui->m_tableWidget->insertRow(newrow);
584 QTableWidgetItem* itemName =
new QTableWidgetItem(QString::fromStdString(it->second.m_name));
585 itemName->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
586 itemName->setData(Qt::UserRole, QVariant(it->second.m_id.c_str()));
587 m_ui->m_tableWidget->setItem(newrow, 0, itemName);
590 QComboBox* combo =
new QComboBox(m_ui->m_tableWidget);
592 for(
size_t t = 0; t < it->second.m_values.size(); ++t)
594 combo->addItem(QString::number(it->second.m_values[t]));
597 m_ui->m_tableWidget->setCellWidget(newrow, 1, combo);
622 m_ui->m_tableWidget->sortByColumn(0, Qt::AscendingOrder);
626 emit completeChanged();
te::color::RGBAColor ** m_rgbaMark
This file defines a class for a MixtureModel Wizard page.
te::rp::MixtureModel::InputParameters getInputParams()
void saveMixtureModelComponents(std::string fileName)
std::auto_ptr< te::qt::widgets::RasterNavigatorDialog > m_navigatorDlg
std::vector< double > m_values
std::vector< std::string > GetBandNames()
Returns a vector os with band's names.
double m_urx
Upper right corner x-coordinate.
void fillMixtureModelTypes()
An utility struct for representing 2D coordinates.
void onItemChanged(QTableWidgetItem *item)
void onRemoveToolButtonClicked()
void onMapDisplayExtentChanged()
te::map::AbstractLayerPtr get()
void showNavigator(bool show)
void loadMixtureModelComponents(std::string fileName)
This file defines a class for a Raster Navigator Dialog.
void Free(std::vector< T * > *v)
This function can be applied to a pointer to a vector of pointers.
double m_llx
Lower left corner x-coordinate.
void onLoadToolButtonClicked()
static MarkRendererManager & getInstance()
It returns a reference to the singleton instance.
bool m_normalizeOutput
A flag to indicate that output raster will be normalized, by default [0, 255].
A point with x and y coordinate values.
An Envelope defines a 2D rectangular region.
std::auto_ptr< Ui::MixtureModelWizardPageForm > m_ui
virtual const te::gm::Envelope & getExtent() const
It returns the world extent showned by the MapDisplay.
void set(te::map::AbstractLayerPtr layer)
This method is used to set the selected layer for mixture model operation.
A Fill specifies the pattern for filling an area geometry.
TESEEXPORT Mark * CreateMark(const std::string &wellKnownName, Stroke *stroke, Fill *fill)
Creates a mark.
MixtureModelWizardPage(QWidget *parent=0)
double m_lly
Lower left corner y-coordinate.
TESEEXPORT Stroke * CreateStroke(const std::string &color, const std::string &width)
Creates a stroke.
te::rp::MixtureModel::OutputParameters getOutputParams()
MixtureModel output parameters.
void onPointPicked(double x, double y)
void setX(const double &x)
It sets the Point x-coordinate value.
double m_ury
Upper right corner y-coordinate.
A Stroke specifies the appearance of a linear geometry.
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
void setY(const double &y)
It sets the Point y-coordinate value.
bool m_createErrorRaster
A flag to indicate that output raster will include the error bands.
te::gm::Coord2D m_coordGrid
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
~MixtureModelWizardPage()
te::gm::Coord2D m_coordGeo
void onSaveToolButtonClicked()
TESEEXPORT Fill * CreateFill(const std::string &color, const std::string &opacity)
Creates a fill.