/**************************************************************************** Copyright (C) 2010-2019 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_stepcomputedtm.h" #include "ct_log/ct_logmanager.h" #include #define EPSILON 0.000001 ONF_StepComputeDTM::ONF_StepComputeDTM() : SuperClass() { _gridsize = 0.5; _gridMode = 1; _xBase = 0; _yBase = 0; _name = tr("MNT"); } QString ONF_StepComputeDTM::description() const { return tr("Créer MNT (Zmin)"); } QString ONF_StepComputeDTM::detailledDescription() const { return tr("Cette étape permet de générer un Modèle Numérique de Terrain (MNT).
" "Le MNT est calculé comme un raster Zmin à la résolution spécifiée."); } QString ONF_StepComputeDTM::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepComputeDTM::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepComputeDTM::createNewInstance() const { // cree une copie de cette etape return new ONF_StepComputeDTM(); } /////////////////////// PROTECTED /////////////////////// void ONF_StepComputeDTM::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Points sol")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inScene, tr("Points sol")); manager.addItem(_inGroup, _inArea, tr("Emprise")); } void ONF_StepComputeDTM::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Résolution du raster :"), "cm", 1, 1000, 0, _gridsize, 100); postInputConfigDialog->addString(tr("Nom à donner au raster"), "", _name, tr("Attention : ce paramètre ne peut être pris en compte qu'à l'ajout de l'étape ou au chargement d'un script.
Une modification de ce paramètre lors d'une reconfiguration des paramètres se répercutera dans les scripts exportés ultérieurement, mais pas dans la session en cours. ")); postInputConfigDialog->addSeparationLine(); postInputConfigDialog->addText(tr("Quelle emprise utiliser ?"),"", "", tr("La section suivante définit comment l'extension selon les axes X et Y du raster est déterminée.")); CT_ButtonGroup &bg_gridMode = postInputConfigDialog->addButtonGroup(_gridMode); postInputConfigDialog->addExcludeValue("", "", tr("La boite englobante de la scène"), bg_gridMode, 0); postInputConfigDialog->addExcludeValue("", "", tr("L'emprise précédement sélectionnée "), bg_gridMode, 2); postInputConfigDialog->addExcludeValue("", "", tr("Recaler par rapport aux coordonnées suivantes :"), bg_gridMode, 1); postInputConfigDialog->addDouble(tr("Coordonnée X :"), "", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _xBase); postInputConfigDialog->addDouble(tr("Coordonnée Y :"), "", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _yBase); } void ONF_StepComputeDTM::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outDTM, _name); } void ONF_StepComputeDTM::compute() { for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { for (const CT_AbstractItemDrawableWithPointCloud* inScene : group->singularItems(_inScene)) { if (isStopped()) {return;} const CT_AbstractPointCloudIndex *pointCloudIndex = inScene->pointCloudIndex(); if (pointCloudIndex->size() > 0) { const CT_AbstractGeometricalItem *emprise = group->singularItem(_inArea); // Creation du raster double minX = std::floor(inScene->minX()*100.0) / 100.0; double minY = std::floor(inScene->minY()*100.0) / 100.0; double maxX = std::ceil(inScene->maxX()*100.0) / 100.0; double maxY = std::ceil(inScene->maxY()*100.0) / 100.0; if (_gridMode == 2 && emprise != nullptr && emprise->hasBoundingBox()) { Eigen::Vector3d min, max; emprise->boundingBox(min, max); minX = min(0); minY = min(1); maxX = max(0) - EPSILON; maxY = max(1) - EPSILON; } else if (_gridMode == 1) { minX = std::floor((inScene->minX() - _xBase - 1) / _gridsize) * _gridsize + _xBase; minY = std::floor((inScene->minY() - _yBase - 1) / _gridsize) * _gridsize + _yBase; while (minX < inScene->minX()) {minX += _gridsize;} while (minY < inScene->minY()) {minY += _gridsize;} while (minX > inScene->minX()) {minX -= _gridsize;} while (minY > inScene->minY()) {minY -= _gridsize;} } CT_Image2D* mnt = CT_Image2D::createImage2DFromXYCoords(minX, minY, maxX, maxY, _gridsize, inScene->minZ(), -9999, -9999); // Création MNT (version Zmin) CT_PointIterator itP(pointCloudIndex); while(itP.hasNext() && !isStopped()) { const CT_Point &point =itP.next().currentPoint(); mnt->setMinValueAtCoords(point(0), point(1), static_cast(point(2))); } setProgress(50.0f); // ajout du raster MNS mnt->computeMinMax(); group->addSingularItem(_outDTM, mnt); } } setProgress(100.0f); } }