/**************************************************************************** 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_stepaddtilexyareas.h" #include "ct_log/ct_logmanager.h" ONF_StepAddTileXYAreas::ONF_StepAddTileXYAreas() : SuperClass() { _xRefCoord = 0.0; _yRefCoord = 0.0; _tileSize = 500.0; _bufferSize = 20.0; _bufferIncluded = false; } QString ONF_StepAddTileXYAreas::description() const { return tr("Ajout des emprises de dalles"); } QString ONF_StepAddTileXYAreas::detailledDescription() const { return tr("Pour chaque fichier d'entrée, ajoute l'emprise de la dalle. En fait deux emprises sont ajoutée :
" "- L'emprise normale
" "- L'emprise avec buffer
" "Les emprises sont calculées à partir de coordonnées de référence et de la taille de dalle données en paramètres.
" "En cas d'incohérence, un message esst affiché dans le log."); } QString ONF_StepAddTileXYAreas::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepAddTileXYAreas::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepAddTileXYAreas::createNewInstance() const { // cree une copie de cette etape return new ONF_StepAddTileXYAreas(); } //////////////////// PROTECTED ////////////////// void ONF_StepAddTileXYAreas::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Dalles")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inFootPrintItem, tr("Item définissant l'emprise")); manager.addItemAttribute(_inFootPrintItem, _inAttFileName, CT_AbstractCategory::DATA_VALUE, tr("Nom de la dalle")); } void ONF_StepAddTileXYAreas::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Coordonnée X de référence"), "m" , -std::numeric_limits::max(), std::numeric_limits::max(), 4, _xRefCoord); postInputConfigDialog->addDouble(tr("Coordonnée Y de référence"), "m" , -std::numeric_limits::max(), std::numeric_limits::max(), 4, _yRefCoord); postInputConfigDialog->addDouble(tr("Taille de la dalle unitaire (hors zones tampons)"), "m", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _tileSize); postInputConfigDialog->addDouble(tr("Taille de la zone tampon"), "m", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _bufferSize); postInputConfigDialog->addBool(tr("Cocher si les fichiers d'entrée incluent les zones tampons"), "", "", _bufferIncluded); } void ONF_StepAddTileXYAreas::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outTileXYArea, tr("Emprise")); manager.addItem(_inGroup, _outBufferTileXYArea, tr("Emprise (zone tampon)")); } void ONF_StepAddTileXYAreas::compute() { double minXsize = std::numeric_limits::max(); double maxXsize = 0; double minYsize = std::numeric_limits::max(); double maxYsize = 0; int nbDalles = 0; for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { for (const CT_AbstractSingularItemDrawable *footprintItem : group->singularItems(_inFootPrintItem)) { if (isStopped()) {return;} const CT_AbstractItemAttribute* att = footprintItem->itemAttribute(_inAttFileName); QString fileName = footprintItem->displayableName(); if (att != nullptr) { fileName = att->toString(footprintItem, nullptr); } if (footprintItem->hasBoundingBox()) // the footprintItem has to be geographical { nbDalles++; Eigen::Vector3d min, max; footprintItem->boundingBox(min, max); // qDebug() << "BoundingBox"; // qDebug() << "minx=" << QString::number(min(0), 'f', 4); // qDebug() << "miny=" << QString::number(min(1), 'f', 4); // qDebug() << "maxx=" << QString::number(max(0), 'f', 4); // qDebug() << "maxy=" << QString::number(max(1), 'f', 4); double sizeXTMP = max(0) - min(0); double sizeYTMP = max(1) - min(1); if (sizeXTMP < minXsize) {minXsize = sizeXTMP;} if (sizeXTMP > maxXsize) {maxXsize = sizeXTMP;} if (sizeYTMP < minYsize) {minYsize = sizeYTMP;} if (sizeYTMP > maxYsize) {maxYsize = sizeYTMP;} if (_bufferIncluded) { min(0) += _bufferSize; min(1) += _bufferSize; max(0) -= _bufferSize; max(1) -= _bufferSize; } double baseX = max(0) / 2.0 + min(0) / 2.0; double baseY = max(1) / 2.0 + min(1) / 2.0; // qDebug() << "baseX=" << QString::number(baseX, 'f', 4); // qDebug() << "baseY=" << QString::number(baseY, 'f', 4); Eigen::Vector2d minBB, maxBB; minBB(0) = std::floor((baseX - _xRefCoord) / _tileSize) * _tileSize + _xRefCoord; minBB(1) = std::floor((baseY - _yRefCoord) / _tileSize) * _tileSize + _yRefCoord; // qDebug() << "minBB(0)=" << QString::number(minBB(0), 'f', 4); // qDebug() << "minBB(1)=" << QString::number(minBB(1), 'f', 4); maxBB(0) = minBB(0); maxBB(1) = minBB(1); // while (maxBB(0) < max(0)) {maxBB(0) += _tileSize;} // while (maxBB(1) < max(1)) {maxBB(1) += _tileSize;} maxBB(0) += _tileSize; maxBB(1) += _tileSize; // qDebug() << "maxBB(0)=" << QString::number(maxBB(0), 'f', 4); // qDebug() << "maxBB(1)=" << QString::number(maxBB(1), 'f', 4); CT_Box2DData* boxData = new CT_Box2DData(minBB, maxBB); CT_Box2D* box2D = new CT_Box2D(boxData); if (!fileName.isEmpty()) {box2D->setDisplayableName(fileName);} group->addSingularItem(_outTileXYArea, box2D); minBB(0) -= _bufferSize; minBB(1) -= _bufferSize; maxBB(0) += _bufferSize; maxBB(1) += _bufferSize; boxData = new CT_Box2DData(minBB, maxBB); box2D = new CT_Box2D(boxData); if (!fileName.isEmpty()) {box2D->setDisplayableName(QString("%1_Buffer").arg(fileName));} group->addSingularItem(_outBufferTileXYArea, box2D); } else { PS_LOG->addMessage(LogInterface::warning, LogInterface::step, tr("Header %1 non géographique (impossible de déterminer l'emprise)").arg(fileName)); } } PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr("Taille choisie pour les dalles :%1 m").arg(_tileSize)); PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr("Taille constatée des dalles (%1 dalles analysées) :").arg(nbDalles)); PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr(" - Taille minimale selon X :%1 m").arg(minXsize)); PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr(" - Taille minimale selon Y :%1 m").arg(minYsize)); PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr(" - Taille maximale selon X :%1 m").arg(maxXsize)); PS_LOG->addMessage(LogInterface::info, LogInterface::step, tr(" - Taille maximale selon Y :%1 m").arg(maxYsize)); if (std::abs(std::max(maxXsize,maxYsize) - _tileSize) / _tileSize > 0.1) { PS_LOG->addMessage(LogInterface::error, LogInterface::step, tr("Attention : écart supérieur à 10 % de la taille choisie")); } } }