/**************************************************************************** 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_stepexportrastersintable.h" #include "ct_global/ct_context.h" #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/ct_outresultmodelgroupcopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" #include "ct_result/ct_resultgroup.h" #include "ct_itemdrawable/ct_loopcounter.h" #include "ct_itemdrawable/abstract/ct_abstractareashape2d.h" #include "ct_itemdrawable/ct_scene.h" #include "ct_itemdrawable/ct_triangulation2d.h" #include "ct_triangulation/ct_delaunayt.h" #include "ct_triangulation/ct_nodet.h" #include "ct_triangulation/ct_trianglet.h" #include "ct_itemdrawable/ct_image2d.h" #include "ct_pointcloudindex/ct_pointcloudindexvector.h" #include "ct_iterator/ct_pointiterator.h" #include "ct_view/ct_stepconfigurabledialog.h" #include "ct_itemdrawable/tools/image2dtools/ct_image2dnaturalneighboursinterpolator.h" #include #include #include #include #include #define DEF_SearchInResult "ires" #define DEF_SearchInGroup "igrp" #define DEF_SearchInRaster "iraster" #define DEFin_resFootprint "resFootprint" #define DEFin_grpFootprint "grpFootprint" #define DEFin_footprint "footprint" #define DEF_inResultCounter "rcounter" #define DEF_inCounter "counter" ONF_StepExportRastersInTable::ONF_StepExportRastersInTable(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { _noprefix = true; } QString ONF_StepExportRastersInTable::getStepDescription() const { return tr("Exporter multi-raster dans une table"); } QString ONF_StepExportRastersInTable::getStepDetailledDescription() const { return tr("Cette étape permet d'exporter une série de rasters (cohérents) dans une table." "La résolution est celle du raster avec la résolution la plus faible." "Une emprise peut être fournie pour filtrer les données à exporter."); } CT_VirtualAbstractStep* ONF_StepExportRastersInTable::createNewInstance(CT_StepInitializeData &dataInit) { // cree une copie de cette etape return new ONF_StepExportRastersInTable(dataInit); } /////////////////////// PROTECTED /////////////////////// void ONF_StepExportRastersInTable::createInResultModelListProtected() { CT_InResultModelGroupToCopy *resultModel = createNewInResultModelForCopy(DEF_SearchInResult, tr("Rasters"), "", true); resultModel->setZeroOrMoreRootGroup(); resultModel->addGroupModel("", DEF_SearchInGroup, CT_AbstractItemGroup::staticGetType(), tr("Rasters"), "", CT_InAbstractGroupModel::CG_ChooseMultipleIfMultiple); resultModel->addItemModel(DEF_SearchInGroup, DEF_SearchInRaster, CT_AbstractImage2D::staticGetType(), tr("Raster"), "", CT_InAbstractModel::C_ChooseMultipleIfMultiple); CT_InResultModelGroup *resin_footprint = createNewInResultModel(DEFin_resFootprint, tr("Emprise (optionnel)"), "", true); resin_footprint->setZeroOrMoreRootGroup(); resin_footprint->addGroupModel("", DEFin_grpFootprint); resin_footprint->addItemModel(DEFin_grpFootprint, DEFin_footprint, CT_AbstractAreaShape2D::staticGetType(), tr("Emprise")); resin_footprint->setMinimumNumberOfPossibilityThatMustBeSelectedForOneTurn(0); CT_InResultModelGroup* res_counter = createNewInResultModel(DEF_inResultCounter, tr("Compteur (optionnel - nom adaptatif)"), "", true); res_counter->setZeroOrMoreRootGroup(); res_counter->addItemModel("", DEF_inCounter, CT_LoopCounter::staticGetType(), tr("Compteur")); res_counter->setMinimumNumberOfPossibilityThatMustBeSelectedForOneTurn(0); } void ONF_StepExportRastersInTable::createPostConfigurationDialog() { CT_StepConfigurableDialog *configDialog = newStandardPostConfigurationDialog(); configDialog->addFileChoice(tr("Choix du fichier d'export"), CT_FileChoiceButton::OneNewFile, tr("Fichier texte (*.txt)"), _fileName); configDialog->addBool("", "", tr("Pas de préfixe (si export adaptatif)"), _noprefix); } void ONF_StepExportRastersInTable::createOutResultModelListProtected() { createNewOutResultModelToCopy(DEF_SearchInResult); } void ONF_StepExportRastersInTable::compute() { QList fooprintResults = getInputResultsForModel(DEFin_resFootprint); Eigen::Vector2d minFootprint, maxFootprint; minFootprint(0) = std::numeric_limits::max(); minFootprint(1) = std::numeric_limits::max(); maxFootprint(0) = -std::numeric_limits::max(); maxFootprint(1) = -std::numeric_limits::max(); QList emprises; if (fooprintResults.size() > 0) { CT_ResultGroupIterator itFootprint(fooprintResults.first(), this, DEFin_grpFootprint); while (!isStopped() && itFootprint.hasNext()) { CT_StandardItemGroup* group = (CT_StandardItemGroup*) itFootprint.next(); if (group != NULL) { CT_AbstractAreaShape2D *emprise = (CT_AbstractAreaShape2D*)group->firstItemByINModelName(this, DEFin_footprint); emprises.append(emprise); Eigen::Vector3d min, max; emprise->getBoundingBox(min, max); if (min(0) < minFootprint(0)) {minFootprint(0) = min(0);} if (min(1) < minFootprint(1)) {minFootprint(1) = min(1);} if (max(0) > maxFootprint(0)) {maxFootprint(0) = max(0);} if (max(1) > maxFootprint(1)) {maxFootprint(1) = max(1);} } } } QString adaptativeName = ""; QList rcounters = getInputResultsForModel(DEF_inResultCounter); if (rcounters.size() > 0) { CT_ResultItemIterator itCounter(rcounters.first(), this, DEF_inCounter); if (itCounter.hasNext()) { const CT_LoopCounter* counter = (const CT_LoopCounter*) itCounter.next(); if (counter != NULL) { adaptativeName = counter->getTurnName(); QFileInfo finf(adaptativeName); adaptativeName = finf.baseName(); } } } // recupere les resultats de sortie const QList &outResList = getOutResultList(); // récupération des modéles out CT_ResultGroup *outResult = outResList.at(0); double xmin, xmax, ymin, ymax, resolution; bool first = true; bool empriseDiff = false; bool resDiff = false; QList rasters; CT_ResultItemIterator it(outResult, this, DEF_SearchInRaster); while (!isStopped() && it.hasNext()) { CT_AbstractImage2D* raster = (CT_AbstractImage2D*) it.next(); if (raster != NULL) { rasters.append(raster); if (first) { xmin = raster->minX(); xmax = raster->maxX(); ymin = raster->minY(); ymax = raster->maxY(); resolution = raster->resolution(); first = false; } else { if (xmin != raster->minX() || xmax != raster->maxX() || ymin != raster->minY() || ymax != raster->maxY()) { empriseDiff = true; if (raster->minX() < xmin) {xmin = raster->minX();} if (raster->maxX() > xmax) {xmax = raster->maxX();} if (raster->minY() < ymin) {ymin = raster->minY();} if (raster->maxY() > ymax) {ymax = raster->maxY();} } if (resolution != raster->resolution()) { resDiff = true; if (raster->resolution() < resolution) {resolution = raster->resolution();} } } } } double halfRes = resolution / 2.0; if (empriseDiff) {PS_LOG->addMessage(LogInterface::warning, LogInterface::step, tr("Tous les rasters n'ont pas la même emprise"));} if (resDiff) {PS_LOG->addMessage(LogInterface::warning, LogInterface::step, tr("Tous les rasters n'ont pas la même résolution"));} if (!rasters.isEmpty()) { QString exportFileName = _fileName.first(); if (!adaptativeName.isEmpty()) { QFileInfo fileInfo(_fileName.first()); if (_noprefix) { exportFileName = QString("%1/%2.txt").arg(fileInfo.absolutePath()).arg(adaptativeName); } else { exportFileName = QString("%1/%2_%3.txt").arg(fileInfo.absolutePath()).arg(fileInfo.baseName()).arg(adaptativeName); } } QFile f(exportFileName); if (f.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream stream(&f); for (int i = 0 ; i < rasters.size() ; i++) { CT_AbstractImage2D* raster = (CT_AbstractImage2D*) rasters.at(i); stream << raster->displayableName(); if (i < (rasters.size() - 1)) { stream << "\t"; } else { stream << "\n"; } } int nbcells = ((xmax - xmin) / resolution) * ((ymax - ymin) / resolution); int index = 0; for (double xx = xmin + halfRes ; xx < xmax ; xx += resolution) { for (double yy = ymin + halfRes ; yy < ymax ; yy += resolution) { ++index; bool keep = true; if (!emprises.isEmpty()) { keep= false; if (xx >= minFootprint(0) && xx <= maxFootprint(0) && yy >= minFootprint(1) && yy <= maxFootprint(1)) { for (int ff = 0 ; ff < emprises.size() && !keep ; ff++) { if (emprises.at(ff)->contains(xx, yy)) { keep = true; } } } } if (keep) { for (int i = 0 ; i < rasters.size() ; i++) { CT_AbstractImage2D* raster = (CT_AbstractImage2D*) rasters.at(i); size_t indexRast; raster->indexAtCoords(xx, yy, indexRast); stream << raster->valueAtIndexAsDouble(indexRast); if (i < (rasters.size() - 1)) { stream << "\t"; } else { stream << "\n"; } } } setProgress(90.0*(double)index/(double)nbcells); } } f.close(); } } setProgress(100); }