/**************************************************************************** Copyright (C) 2010-2012 the Office National des Forêts (ONF), France All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Alexandre PIBOULE (ONF) This file is part of PluginONF library. PluginONF is free library: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PluginONF is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PluginONF. If not, see . *****************************************************************************/ #include "onf_steploadtreemap.h" #include "ct_view/ct_asciifilechoicebutton.h" #include "ct_view/ct_combobox.h" #include "ct_log/ct_logmanager.h" #include #include ONF_StepLoadTreeMap::ONF_StepLoadTreeMap() : CT_AbstractStepCanBeAddedFirst() { _mode = 1; _neededFields.append(CT_TextFileConfigurationFields("ID_Plot", QRegExp("([pP][lL][oO][tT]|[pP][lL][aA][cC][eE][tT][tT][eE]|[pP][lL][aA][cC]|[iI][dD][_][pP][lL][oO][tT]|[iI][dD][_][pP][lL][aA][cC][eE][tT][tT][eE]|[iI][dD][_][pP][lL][aA][cC])"), false)); _neededFields.append(CT_TextFileConfigurationFields("ID_Tree", QRegExp("([tT][rR][eE][eE]|[aA][rR][bB][rR][eE]|[iI][dD][_][tT][rR][eE][eE]|[iI][dD][_][aA][rR][bB][rR][eE])"), false)); _neededFields.append(CT_TextFileConfigurationFields("X", QRegExp("[xX]"), false)); _neededFields.append(CT_TextFileConfigurationFields("Y", QRegExp("[yY]"), false)); _neededFields.append(CT_TextFileConfigurationFields("DBH (cm)", QRegExp("([dD][bB][hH]|[dD][iI][aA][mM]|[D])"), false)); _neededFields.append(CT_TextFileConfigurationFields("H (m)", QRegExp("([hH]*|[hH][eE][iI][gG][hH][tT]|[hH][aA][uU][tT][eE][uU][uR])"), false)); _neededFields.append(CT_TextFileConfigurationFields("Species", QRegExp("([sS][pP][eE][cC][iI][eE][sS]|[eE][sS][sS][eE][nN][cC][eE]|[eéE][sS][pP][eèE][cC][eE])|[eéE][sS][pP]|[eE][sS][sS]"), true)); _neededFields.append(CT_TextFileConfigurationFields("Comment", QRegExp("([cC][oO][mM][mM][eE][nN][tT]|[rR][eE][mM][aA][rR]|[oO][bB][sS])"), true)); _refFileName = ""; _refHeader = true; _refSeparator = "\t"; _refDecimal = "."; _refLocale = QLocale(QLocale::English, QLocale::UnitedKingdom).name(); _refSkip = 0; _plotID = ""; _cbox = nullptr; } QString ONF_StepLoadTreeMap::description() const { return tr("Placette d'inventaire forestier (Tree Map)"); } QString ONF_StepLoadTreeMap::detailledDescription() const { return tr("Charge des données d'inventaire forestier depuis un fichier ASCII.
" "L'import est configurable, le fichier devant contenir les champs suivants :
" "- IDplot : Identifiant placette
" "- IDtree : Identifiant arbre
" "- X : Coordonnée X de l'arbre
" "- Y : Coordonnée Y de l'arbre
" "- DBH : Diamètre à 1.30 m de l'arbre
" "- H : Hauteur de l'arbre
" "- Species: Espèce de l'arbre
" "
Une fois le format de fichier paramétré, l'utilisateur indique quelle placette doit être chargée.
" "Seules les données de la placette choisie seront chargées."); } QString ONF_StepLoadTreeMap::inputDescription() const { return SuperClass::inputDescription() + tr("

"); } QString ONF_StepLoadTreeMap::outputDescription() const { return SuperClass::outputDescription() + tr("

"); } QString ONF_StepLoadTreeMap::detailsDescription() const { return tr(""); } QString ONF_StepLoadTreeMap::URL() const { //return tr("STEP URL HERE"); return CT_AbstractStepCanBeAddedFirst::URL(); //by default URL of the plugin } CT_VirtualAbstractStep* ONF_StepLoadTreeMap::createNewInstance() const { return new ONF_StepLoadTreeMap(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepLoadTreeMap::fillPreInputConfigurationDialog(CT_StepConfigurableDialog* preInputConfigDialog) { CT_ButtonGroup &bg_mode = preInputConfigDialog->addButtonGroup(_mode); preInputConfigDialog->addExcludeValue("", "", tr("IDplacette à partir du nom de tour (boucles)"), bg_mode, 0); preInputConfigDialog->addExcludeValue("", "", tr("Sélection manuelle de l'IDplacette"), bg_mode, 1); } void ONF_StepLoadTreeMap::declareInputModels(CT_StepInModelStructureManager& manager) { if (_mode == 0) { manager.addResult(_inResultCounter, tr("Résultat compteur"), "", true); manager.setZeroOrMoreRootGroup(_inResultCounter, _inZeroOrMoreRootGroupCounter); manager.addItem(_inZeroOrMoreRootGroupCounter, _inCounter, tr("Compteur")); } else { manager.setNotNeedInputResult(); } } void ONF_StepLoadTreeMap::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResult(_outResultRef, tr("Positions de référence")); manager.setRootGroup(_outResultRef, _outGrpPlot, tr("Plot")); manager.addGroup(_outGrpPlot, _outGrpRef, tr("Tree")); manager.addItem(_outGrpRef, _outRef, tr("Position")); manager.addItemAttribute(_outRef, _outRefDbh, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_NUMBER), tr("DBH")); manager.addItemAttribute(_outRef, _outRefHeight, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_NUMBER), tr("Height")); manager.addItemAttribute(_outRef, _outRefID, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_ID), tr("IDtree")); manager.addItemAttribute(_outRef, _outRefIDplot, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_ID), tr("IDplot")); manager.addItemAttribute(_outRef, _outSpecies, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("Species")); manager.addItemAttribute(_outRef, _outComment, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("Comment")); } void ONF_StepLoadTreeMap::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { CT_AsciiFileChoiceButton *fileChoice = postInputConfigDialog->addAsciiFileChoice("Fichier des arbres", "Fichier ASCII (*.txt ; *.asc)", true, _neededFields, _refFileName, _refHeader, _refSeparator, _refDecimal, _refLocale, _refSkip, _refColumns); if (_mode == 1) { _cbox = postInputConfigDialog->addStringChoice(tr("Choix de la placette"), "", QStringList(), _plotID); //connect(postInputConfigDialog, SIGNAL(openned()), this, SLOT(fileChanged())); connect(fileChoice, SIGNAL(fileChanged()), this, SLOT(fileChanged())); //connect(this, SIGNAL(updateComboBox(QStringList, QString)), _cbox, SLOT(changeValues(QStringList, QString))); } } void ONF_StepLoadTreeMap::finalizePostSettings() { fileChanged(); } void ONF_StepLoadTreeMap::fileChanged() { QString oldPlotID = _plotID; if (oldPlotID.isEmpty() && _mode == 1) { oldPlotID = _cbox->getValue().toString(); } _plotsIds.clear(); int colIDplot_ref = _refColumns.value("ID_Plot", -1); if (colIDplot_ref < 0) {_plotID = ""; return;} QFile fRef(_refFileName); if (fRef.exists() && fRef.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&fRef); stream.setLocale(_refLocale); for (int i = 0 ; i < _refSkip ; i++) {stream.readLine();} if (_refHeader) {stream.readLine();} while (!stream.atEnd()) { QString line = stream.readLine(); if (!line.isEmpty()) { QStringList values = line.split(_refSeparator); if (values.size() > colIDplot_ref) { const QString &val = values.at(colIDplot_ref); if (!_plotsIds.contains(val)) {_plotsIds.append(val);} } } } fRef.close(); } QString val = ""; if (_plotsIds.size() > 0) {std::sort(_plotsIds.begin(), _plotsIds.end()); val = _plotsIds.first();} if (_plotsIds.contains(oldPlotID)) {val = oldPlotID;} if (_mode == 1) { _cbox->changeValues(_plotsIds, val); } //emit updateComboBox(); } void ONF_StepLoadTreeMap::compute() { QString turnName = ""; if (_mode == 0) { // use only first turn for (const CT_LoopCounter* counter : _inCounter.iterateInputs(_inResultCounter)) { QFileInfo fileInfo(counter->turnName()); turnName = fileInfo.baseName(); } if (turnName != "") {_plotID = turnName;} } for (CT_ResultGroup* resOut : _outResultRef.iterateOutputs()) { CT_StandardItemGroup* grp_Plot= new CT_StandardItemGroup(); resOut->addRootGroup(_outGrpPlot, grp_Plot); PS_LOG->addMessage(LogInterface::info, LogInterface::step, QString(tr("Placette en cours de traitement : %1")).arg(_plotID)); int colIDplot_ref = _refColumns.value("ID_Plot", -1); if (colIDplot_ref < 0) {_plotID = "";} QFile fRef(_refFileName); if (fRef.exists() && fRef.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&fRef); stream.setLocale(_refLocale); int colID = _refColumns.value("ID_Tree", -1); int colX = _refColumns.value("X", -1); int colY = _refColumns.value("Y", -1); int colVal = _refColumns.value("DBH (cm)", -1); int colHeight = _refColumns.value("H (m)", -1); int colSpecies = _refColumns.value("Species", -1); int colComment = _refColumns.value("Comment", -1); if (colID < 0) {PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Champ IDtree non défini")));} if (colX < 0) {PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Champ X non défini")));} if (colY < 0) {PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Champ Y non défini")));} if (colVal < 0) {PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Champ DBH non défini")));} if (colHeight < 0) {PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Champ H non défini")));} if (colSpecies < 0) {PS_LOG->addMessage(LogInterface::warning, LogInterface::step, QString(tr("Champ Espèce non défini")));} if (colComment < 0) {PS_LOG->addMessage(LogInterface::warning, LogInterface::step, QString(tr("Champ Commentaire non défini")));} if (colID >=0 && colX >= 0 && colY >= 0 && colVal >= 0) { int colMax = colID; if (colX > colMax) {colMax = colX;} if (colY > colMax) {colMax = colY;} if (colVal > colMax) {colMax = colVal;} if (colHeight > colMax) {colMax = colHeight;} if (colSpecies > colMax) {colMax = colSpecies;} if (colComment > colMax) {colMax = colComment;} if (colIDplot_ref > colMax) {colMax = colIDplot_ref;} for (int i = 0 ; i < _refSkip ; i++) {stream.readLine();} if (_refHeader) {stream.readLine();} size_t cpt = 1; while (!stream.atEnd()) { QString line = stream.readLine(); cpt++; if (!line.isEmpty()) { QStringList values = line.split(_refSeparator); if (values.size() >= colMax) { QString plot = ""; if (colIDplot_ref >= 0) { plot = values.at(colIDplot_ref); } if (plot == _plotID) { bool okX, okY, okVal, okHeight; double x = _refLocale.toDouble(values.at(colX), &okX); double y = _refLocale.toDouble(values.at(colY), &okY); float val = _refLocale.toFloat(values.at(colVal), &okVal); float height = -1; if (colHeight >= 0) { height = _refLocale.toFloat(values.at(colHeight), &okHeight); if (!okHeight) {height = -1;} } QString species; if (colSpecies >= 0) { species = values.at(colSpecies); } QString comment; if (colComment >= 0) { comment = values.at(colComment); } QString id = values.at(colID); if (okX && okY && okVal) { CT_StandardItemGroup* grp_Tree= new CT_StandardItemGroup(); grp_Plot->addGroup(_outGrpRef, grp_Tree); CT_Circle2D* item_ref = new CT_Circle2D(new CT_Circle2DData(Eigen::Vector2d(x,y), double(val)/200.0)); grp_Tree->addSingularItem(_outRef, item_ref); item_ref->addItemAttribute(_outRefDbh, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_NUMBER, val)); item_ref->addItemAttribute(_outRefHeight, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_NUMBER, height)); item_ref->addItemAttribute(_outRefID, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_ID, id)); item_ref->addItemAttribute(_outRefIDplot,new CT_StdItemAttributeT( CT_AbstractCategory::DATA_ID, plot)); item_ref->addItemAttribute(_outSpecies, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE, species)); item_ref->addItemAttribute(_outComment, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE, comment)); } else { PS_LOG->addMessage(LogInterface::info, LogInterface::step, QString(tr("Ligne %1 du fichier REF non valide")).arg(cpt)); } } } } } } fRef.close(); } } }