31 #include "../../../maptools/MarkRendererManager.h" 32 #include "../../../se/Fill.h" 33 #include "../../../se/Mark.h" 34 #include "../../../se/Stroke.h" 35 #include "../../../se/Utils.h" 36 #include "../../widgets/tools/AbstractTool.h" 37 #include "../../widgets/tools/PointPicker.h" 38 #include "../../widgets/utils/ScopedCursor.h" 39 #include "../../widgets/Utils.h" 42 #include <QFileDialog> 43 #include <QInputDialog> 44 #include <QMessageBox> 47 #include <qwt_legend.h> 54 #include <boost/format.hpp> 57 #include <wtss-cxx/wtss.hpp> 62 #include "ui_WtssDialogForm.h" 64 namespace cxx = wtss::cxx;
69 m_ui(new
Ui::WtssDialogForm),
74 m_mapDisplay(nullptr),
75 m_chartDisplay(nullptr),
76 m_timeSeriesChartVec(0),
81 this->setWindowTitle(tr(
"Web Time Series Services"));
83 m_ui->m_addToolButton->setIcon(QIcon::fromTheme(
"list-add"));
84 m_ui->m_removeToolButton->setIcon(QIcon::fromTheme(
"list-remove"));
85 m_ui->m_refreshToolButton->setIcon(QIcon::fromTheme(
"view-refresh"));
86 m_ui->m_hideToolButton->setIcon(QIcon::fromTheme(
"hide"));
87 m_ui->m_importToolButton->setIcon(QIcon::fromTheme(
"document-open"));
88 m_ui->m_exportToolButton->setIcon(QIcon::fromTheme(
"document-save-as"));
89 m_ui->m_queryToolButton->setIcon(QIcon::fromTheme(
"media-playback-start-green"));
93 connect(
m_ui->m_addToolButton, SIGNAL(clicked()),
this,
95 connect(
m_ui->m_removeToolButton, SIGNAL(clicked()),
this,
100 connect(
m_ui->m_closePushButton, SIGNAL(clicked()),
this, SLOT(
close()));
101 connect(
m_ui->m_hideToolButton, SIGNAL(clicked()),
this,
103 connect(
m_ui->m_refreshToolButton, SIGNAL(clicked()),
this,
105 connect(
m_ui->m_importToolButton, SIGNAL(clicked()),
this,
107 connect(
m_ui->m_exportToolButton, SIGNAL(clicked()),
this,
109 connect(
m_ui->m_queryToolButton, SIGNAL(clicked()),
this,
111 connect(
m_ui->m_coordSListWidget, SIGNAL(itemClicked(QListWidgetItem *)),
113 connect(
m_ui->m_pointToolButton, SIGNAL(toggled(
bool)),
this,
145 m_ui->m_pointToolButton->setVisible(
true);
153 QInputDialog *inputDialog =
new QInputDialog();
154 inputDialog->setOptions(QInputDialog::NoButtons);
158 QString uri = inputDialog->getText(
nullptr,
"Add Server",
"Server URI:",
182 QMessageBox::warning(
this, tr(
"Web Time Series"),
183 tr(
"An error has occurred, " 184 "please retype the wtss " 190 QMessageBox::warning(
this, tr(
"Web Time Series"),
191 tr(
"Please, input a server."));
201 if(
m_ui->m_serverTreeWidget->currentItem() &&
202 !
m_ui->m_serverTreeWidget->currentItem()->parent())
204 QMessageBox::StandardButton reply = QMessageBox::question(
205 this,
"Remove server",
206 "Remove '" +
m_ui->m_serverTreeWidget->currentItem()->text(0) +
208 QMessageBox::Yes | QMessageBox::No);
210 if(reply == QMessageBox::Yes)
215 m_ui->m_serverTreeWidget->currentItem()->text(0));
221 delete m_ui->m_serverTreeWidget->currentItem();
225 QMessageBox::information(
this, tr(
"Web Time Series"),
226 tr(
"The server was removed with success."));
230 QMessageBox::warning(
this, tr(
"Web Time Series"),
231 tr(
"An error has occurred, please try again."));
237 QMessageBox::warning(
this, tr(
"Web Time Series"),
238 tr(
"Please, select a server."));
247 if(
m_ui->m_serverTreeWidget->currentItem() &&
248 !
m_ui->m_serverTreeWidget->currentItem()->parent())
252 QString uri =
m_ui->m_serverTreeWidget->currentItem()->text(0);
256 delete m_ui->m_serverTreeWidget->currentItem();
262 QMessageBox::warning(
this, tr(
"Web Time Series"),
263 tr(
"An error has occurred, " 264 "please check server list."));
269 QMessageBox::warning(
this, tr(
"Web Time Series"),
270 tr(
"Please, select a server."));
282 QString serverUri = item->parent()->parent()->text(0);
283 QString cvName = item->parent()->text(0);
291 bool attributeChecked =
false;
293 for(
int i = 0; i < item->parent()->parent()->childCount(); ++i)
298 if(attributeItem->checkState(0))
300 attributeChecked =
true;
304 if(attribute.toUtf8().data() ==
316 if(!attributeChecked)
325 QString serverUri = item->parent()->text(0);
326 QString cvName = item->text(0);
330 for(
int i = 0; i < item->parent()->childCount(); ++i)
333 if(cv->text(0) != cvName)
335 if(cv->checkState(0))
336 cv->setCheckState(0, Qt::Unchecked);
343 QString serverUri = item->text(0);
348 int size =
m_ui->m_serverTreeWidget->topLevelItemCount();
349 for(
int i = 0; i < size; ++i)
352 QString
server = sv->text(0);
353 if(server != serverUri)
354 sv->setCheckState(0, Qt::Unchecked);
363 if(
m_ui->m_serverFrame->isVisible())
365 m_ui->m_serverFrame->hide();
366 m_ui->m_hideToolButton->setIcon(QIcon::fromTheme(
"show"));
370 m_ui->m_serverFrame->show();
371 m_ui->m_hideToolButton->setIcon(QIcon::fromTheme(
"hide"));
382 QFileDialog::getOpenFileName(
this, tr(
"Select a TimeSeries CSV file"),
385 if(csvFile.isEmpty())
388 QFileInfo
file(csvFile);
392 std::ifstream csv(csvFile.toUtf8().data());
395 std::getline(csv, str);
402 while(std::getline(csv, str))
404 QString qstr = QString::fromUtf8(str.c_str());
405 QStringList fields = qstr.split(
',');
406 QStringList date = fields.front().split(
"/");
409 date.at(2).toInt(), date.at(1).toInt(), date.at(0).toInt()));
411 double value = fields.back().toDouble();
420 if(
m_result.query.attributes.empty())
423 QString cvName(QString::fromUtf8(
m_result.coverage.name.c_str()));
425 std::vector<cxx::queried_attribute_t> attributes =
426 m_result.coverage.queried_attributes;
428 for(
unsigned int i = 0; i < attributes.size(); i++)
430 cxx::queried_attribute_t
attribute = attributes[i];
432 QString csvFile = QFileDialog::getSaveFileName(
433 this, tr(
"Save File"),
435 "long" +
m_ui->m_longLineEdit->text() +
"_" +
"lat" +
436 m_ui->m_latLineEdit->text() +
"_" + attribute.name.c_str() +
".csv",
439 if(csvFile.isEmpty())
442 QFileInfo info(csvFile);
446 if(info.suffix().isEmpty())
447 csvFile.append(
".csv");
449 std::ofstream myfile(csvFile.toUtf8().data());
451 myfile <<
"Timeline,Value" << std::endl;
453 for(
unsigned int j = 0; j < attribute.values.size(); ++j)
455 QJsonObject j_attribute =
458 QString::fromUtf8(attribute.name.c_str()));
460 cxx::date
d =
m_result.coverage.timeline[j];
463 attribute.values[j] * j_attribute[
"scale_factor"].toDouble();
465 myfile << d.day <<
"/" << d.month <<
"/" << d.year <<
"," << value
474 cxx::timeseries_query_t query;
476 if(
m_ui->m_latLineEdit->text().isEmpty() &&
477 m_ui->m_longLineEdit->text().isEmpty())
479 QMessageBox::warning(
this, tr(
"Web Time Series"),
480 tr(
"Input the latitude and longitude coordinate."));
483 else if(
m_ui->m_latLineEdit->text().isEmpty())
485 QMessageBox::warning(
this, tr(
"Web Time Series"),
486 tr(
"Input the latitude coordinate."));
489 else if(
m_ui->m_longLineEdit->text().isEmpty())
491 QMessageBox::warning(
this, tr(
"Web Time Series"),
492 tr(
"Input the longitude coordinate."));
496 query.latitude =
m_ui->m_latLineEdit->text().toDouble();
497 query.longitude =
m_ui->m_longLineEdit->text().toDouble();
499 QDate startDate =
m_ui->m_startDateEdit->date();
500 QDate endDate =
m_ui->m_endDateEdit->date();
502 if(!startDate.operator<=(endDate))
504 QMessageBox::warning(
this, tr(
"Web Time Series"),
505 tr(
"The date informed is invalid."));
510 startDate.toString(
"dd/MM/yyyy"), endDate.toString(
"dd/MM/yyyy"));
512 query.start_date = startDate.toString(
"yyyy-MM-dd").toUtf8().data();
513 query.end_date = endDate.toString(
"yyyy-MM-dd").toUtf8().data();
517 addMarker(query.longitude, query.latitude);
521 QListWidgetItem *coordSelected)
523 cxx::timeseries_query_t query;
526 QStringList selectedCoord = coordSelected->text().split(
",");
528 query.longitude = selectedCoord.front().toDouble();
529 query.latitude = selectedCoord.back().toDouble();
532 QDate startDate =
m_ui->m_startDateEdit->date();
533 QDate endDate =
m_ui->m_endDateEdit->date();
535 if(!startDate.operator<=(endDate))
537 QMessageBox::warning(
this, tr(
"Web Time Series"),
538 tr(
"The date informed is invalid."));
543 startDate.toString(
"dd/MM/yyyy"), endDate.toString(
"dd/MM/yyyy"));
545 query.start_date = startDate.toString(
"yyyy-MM-dd").toUtf8().data();
546 query.end_date = endDate.toString(
"yyyy-MM-dd").toUtf8().data();
552 converter->setSourceSRID(4326);
557 converter->convert(query.longitude, query.latitude, coord.
x, coord.
y);
561 double auxX = (currEnv.
m_urx - currEnv.
m_llx) / 2;
562 double auxY = (currEnv.
m_ury - currEnv.
m_lly) / 2;
566 env.
m_llx = coord.
x - auxX;
567 env.
m_lly = coord.
y - auxY;
568 env.
m_urx = coord.
x + auxX;
569 env.
m_ury = coord.
y + auxY;
573 addMarker(query.longitude, query.latitude);
583 converter->setTargetSRID(4326);
587 QMessageBox::warning(
this, tr(
"Web Time Series"), tr(
"The display SRS is unknown."));
593 converter->convert(coord.x(), coord.y(), c.
x, c.
y);
595 cxx::timeseries_query_t query;
597 query.longitude = c.
x;
598 query.latitude = c.
y;
600 QDate startDate =
m_ui->m_startDateEdit->date();
601 QDate endDate =
m_ui->m_endDateEdit->date();
603 if(!startDate.operator <=(endDate))
605 QMessageBox::warning(
this, tr(
"Web Time Series"),
606 tr(
"The date informed is invalid."));
611 startDate.toString(
"dd/MM/yyyy"), endDate.toString(
"dd/MM/yyyy"));
613 query.start_date = startDate.toString(
"yyyy-MM-dd").toUtf8().data();
614 query.end_date = endDate.toString(
"yyyy-MM-dd").toUtf8().data();
616 if(
m_ui->m_serverTreeWidget->topLevelItemCount() > 0)
620 addMarker(query.longitude, query.latitude);
644 chartStyle->
setTitle(QString::fromUtf8(
"Web Time Series"));
645 chartStyle->
setAxisX(QString::fromUtf8(
"Timeline"));
646 chartStyle->
setAxisY(QString::fromUtf8(
"Value"));
649 m_ui->m_timeSeriesFrame, QString::fromUtf8(
"Web Time Series"),
652 QGridLayout *m_layout =
new QGridLayout(
m_ui->m_timeSeriesFrame);
654 m_layout->setContentsMargins(0, 0, 0, 0);
668 QJsonObject j_servers =
j_config.find(
"servers").value().toObject();
670 if(j_servers.isEmpty())
673 for(QJsonObject::iterator it = j_servers.begin(); it != j_servers.end(); ++it)
677 QJsonObject j_datefilter =
j_config.find(
"date_filter").value().toObject();
679 if(j_datefilter.isEmpty())
682 QString startDate = j_datefilter.find(
"start_date").value().toString();
684 QString endDate = j_datefilter.find(
"end_date").value().toString();
686 m_ui->m_startDateEdit->setDate(QDate::fromString(startDate,
"dd/MM/yyyy"));
688 m_ui->m_endDateEdit->setDate(QDate::fromString(endDate,
"dd/MM/yyyy"));
692 QMessageBox::warning(
this, tr(
"Web Time Series"),
693 tr(
"An error has occurred, " 694 "when try to load settings."));
700 QJsonObject j_servers =
j_config.find(
"servers").value().toObject();
702 QJsonObject j_server = j_servers.find(server).value().toObject();
707 serverItem->setText(0, server);
709 serverItem->setFlags(serverItem->flags() | Qt::ItemIsUserCheckable);
711 bool active = j_server.find(
"active").value().toBool();
714 serverItem->setCheckState(0, Qt::Checked);
716 serverItem->setCheckState(0, Qt::Unchecked);
724 QJsonObject j_coverages = j_server[
"coverages"].toObject();
726 for(QJsonObject::iterator it = j_coverages.begin(); it != j_coverages.end();
729 bool active = it.value().toObject().find(
"active").value().toBool();
733 coverageItem->setText(0, it.key());
735 coverageItem->setFlags(coverageItem->flags() | Qt::ItemIsUserCheckable);
738 coverageItem->setCheckState(0, Qt::Checked);
740 coverageItem->setCheckState(0, Qt::Unchecked);
742 serverItem->addChild(coverageItem);
751 QJsonObject j_attributes = j_coverage.find(
"attributes").value().toObject();
753 for(QJsonObject::iterator it = j_attributes.begin(); it != j_attributes.end();
758 bool active = it.value().toObject().find(
"active").value().toBool();
762 attributeItem->setText(0, attribute);
763 attributeItem->setFlags(attributeItem->flags() | Qt::ItemIsUserCheckable);
766 attributeItem->setCheckState(0, Qt::Checked);
768 attributeItem->setCheckState(0, Qt::Unchecked);
770 coverageItem->addChild(attributeItem);
778 QMessageBox::warning(
this, tr(
"Web Time Series"),
779 tr(
"Please, select a server"));
784 QMessageBox::warning(
this, tr(
"Web Time Series"),
785 tr(
"Please, select a coverage."));
790 QMessageBox::warning(
this, tr(
"Web Time Series"),
791 tr(
"Please, select an attribute."));
799 cxx::timeseries_query_t query)
803 m_ui->m_latLineEdit->setText(QString::number(query.latitude));
804 m_ui->m_longLineEdit->setText(QString::number(query.longitude));
812 if(j_object.isEmpty())
815 QJsonObject j_servers = j_object.find(
"servers").value().toObject();
817 QJsonObject j_server;
823 for(QJsonObject::iterator it_server = j_servers.begin();
824 it_server != j_servers.end(); ++it_server)
826 j_server = it_server.value().toObject();
828 if(j_server.find(
"active").value().toBool())
830 std::string serverUri = it_server.key().toStdString();
832 QJsonObject j_coverages = j_server[
"coverages"].toObject();
834 for(QJsonObject::iterator it_coverages = j_coverages.begin();
835 it_coverages != j_coverages.end(); it_coverages++)
837 if(it_coverages.value().toObject().find(
"active").value().toBool())
839 cxx::timeseries_query_t new_q;
841 new_q.latitude = query.latitude;
842 new_q.longitude = query.longitude;
843 new_q.coverage_name = it_coverages.key().toUtf8().data();
844 new_q.start_date = query.start_date;
845 new_q.end_date = query.end_date;
847 QJsonObject j_attributes = it_coverages.value()
853 for(QJsonObject::iterator it_attributes = j_attributes.begin();
854 it_attributes != j_attributes.end(); it_attributes++)
856 QJsonObject j_attribute = it_attributes.value().toObject();
858 if(j_attribute[
"active"].toBool() ==
true)
860 new_q.attributes.push_back(it_attributes.key().toUtf8().data());
865 if(new_q.attributes.size() > 0)
867 cxx::client remote(serverUri);
871 m_result = remote.time_series(new_q);
875 catch(
const std::exception&)
877 QMessageBox::warning(
this, tr(
"Web Time Series"),
878 tr(
"The coordinates " 879 "informed are invalid."));
902 cxx::timeseries_query_result_t result)
904 QString cvName(QString::fromUtf8(result.coverage.name.c_str()));
906 std::vector<cxx::queried_attribute_t> attributes =
907 result.coverage.queried_attributes;
911 for(
unsigned int i = 0; i < attributes.size(); i++)
913 cxx::queried_attribute_t
attribute = attributes[i];
917 for(
unsigned int j = 0; j < attribute.values.size(); ++j)
919 QJsonObject j_attribute =
922 QString::fromUtf8(attribute.name.c_str()));
924 cxx::date
d = result.coverage.timeline[j];
926 new te::dt::Date(boost::gregorian::date(d.year, d.month, d.day));
929 attribute.values[j] * j_attribute[
"scale_factor"].toDouble();
969 m_chartDisplay->insertLegend(
new QwtLegend(), QwtPlot::RightLegend);
986 converter->setSourceSRID(4326);
991 converter->convert(x, y, coord.
x, coord.
y);
1003 int r = rand() % 255;
1004 int g = rand() % 255;
1005 int b = rand() % 255;
1006 return QColor(r, g, b);
1011 QList<QListWidgetItem *> coord =
m_ui->m_coordSListWidget->findItems(
1012 QString::number(x) +
"," + QString::number(y), Qt::MatchExactly);
1013 if(coord.length() != 0)
1016 m_ui->m_coordSListWidget->addItem(QString::number(x) +
"," +
1017 QString::number(y));
1033 m_ui->m_coordSListWidget->clear();
1035 m_ui->m_latLineEdit->clear();
1036 m_ui->m_longLineEdit->clear();
void doTimeseriesQuery(cxx::timeseries_query_t query)
void onQueryButtonClicked()
QJsonDocument loadSettings()
void onGetPointCoordinate(QPointF &coord)
cxx::timeseries_query_result_t m_result
void addServer(const QString &server_uri)
void addServer(QString server)
QJsonObject getAttribute(const QString &server_uri, const QString &cv_name, const QString &attribute)
A Mark specifies a geometric shape and applies coloring to it.
std::vector< te::st::TimeSeries * > m_timeSeriesVec
std::string m_lastQueriedServer
te::qt::widgets::ChartDisplay * m_chartDisplay
void addCoverage(QTreeWidgetItem *serverItem, QJsonObject j_server)
void addLocation(double x, double y)
double m_urx
Upper right corner x-coordinate.
void changeStatusAttribute(const QString &server_uri, const QString &cv_name, const QString &attribute)
void convertToTimeSeries(cxx::timeseries_query_result_t result)
void onHelpButtonClicked()
QActionGroup * m_actionGroup
void onServerRemoveButtonClicked()
Base Exception class Exceptions in WTSS.TL.
void onHideButtonClicked()
An utility struct for representing 2D coordinates.
void setMapDisplay(te::qt::widgets::MapDisplay *mapDisplay)
void setActionGroup(QActionGroup *actionGroup)
void onPointPickerToggled(bool checked)
Manage the JSON file for services configuration of the Web Time Series Services plugin.
void removeServer(const QString &server_uri)
double m_llx
Lower left corner x-coordinate.
static MarkRendererManager & getInstance()
It returns a reference to the singleton instance.
A point with x and y coordinate values.
te::qt::widgets::MapDisplay * m_mapDisplay
An Envelope defines a 2D rectangular region.
A base class for date data types.
virtual int getSRID() const
It return the Spatial Reference System used by the Map Display.
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
void addMarker(double x, double y)
virtual const te::gm::Envelope & getExtent() const
It returns the world extent showned by the MapDisplay.
void onExportGraphClicked()
void changeStatusServer(const QString &server_uri)
A Fill specifies the pattern for filling an area geometry.
void onServerAddButtonClicked()
TESEEXPORT Mark * CreateMark(const std::string &wellKnownName, Stroke *stroke, Fill *fill)
Creates a mark.
std::unique_ptr< Ui::WtssDialogForm > m_ui
void onItemChecked(QTreeWidgetItem *item)
double m_lly
Lower left corner y-coordinate.
void refreshServer(const QString &server_uri)
A Converter is responsible for the conversion of coordinates between different Coordinate Systems (CS...
TESEEXPORT Stroke * CreateStroke(const std::string &color, const std::string &width)
Creates a stroke.
double m_ury
Upper right corner y-coordinate.
te::color::RGBAColor ** m_rgbaMarker
A Stroke specifies the appearance of a linear geometry.
A class to represent time series.
void closeEvent(QCloseEvent *e)
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
void addDateFilter(const QString startDate, const QString endDate)
WtssDialog(QWidget *parent=0, Qt::WindowFlags f=0)
QVector< te::qt::widgets::TimeSeriesChart * > m_timeSeriesChartVec
void onImportGraphClicked()
Configuration dialog for Web Time Series Services plugin.
void changeStatusCoverage(const QString &server_uri, const QString &cv_name)
static ServerManager & getInstance()
void onAddCoordToList(QListWidgetItem *coordSelected)
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 $
void addAtributes(QTreeWidgetItem *coverageItem, QJsonObject j_coverage)
TESEEXPORT Fill * CreateFill(const std::string &color, const std::string &opacity)
Creates a fill.
void onServerRefreshButtonClicked()