/**************************************************************************** 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_stepcreatetiling.h" #include "ct_log/ct_logmanager.h" ONF_StepCreateTiling::ONF_StepCreateTiling() : SuperClass() { _tileSize = 500.0; _keepEmptyTiles = false; _useRefCoord = true; _xRefCoord = 0.0; _yRefCoord = 0.0; _nameByCoordinates = true; } QString ONF_StepCreateTiling::description() const { return tr("Créer un dallage"); } QString ONF_StepCreateTiling::detailledDescription() const { return tr("Créer un dallage couvrant l'emprise des items d'entrée."); } QString ONF_StepCreateTiling::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepCreateTiling::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepCreateTiling::createNewInstance() const { // cree une copie de cette etape return new ONF_StepCreateTiling(); } //////////////////// PROTECTED ////////////////// void ONF_StepCreateTiling::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Item (avec BoundingBox)")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inItem, tr("Item (avec BoundingBox)")); } void ONF_StepCreateTiling::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog) { postInputConfigDialog->addDouble(tr("Taille de la dalle unitaire"), "m", -std::numeric_limits::max(), std::numeric_limits::max(), 4, _tileSize); postInputConfigDialog->addBool(tr("Conserver les emprises vides"), "", "", _keepEmptyTiles); postInputConfigDialog->addEmpty(); postInputConfigDialog->addBool(tr("Recaler sur une coordonnée de référence"), "", "", _useRefCoord); 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->addEmpty(); postInputConfigDialog->addBool(tr("Nommer selon les coordonnées : Xmin_Ymin"), QString(), QString(), _nameByCoordinates); } void ONF_StepCreateTiling::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResult(_outResult, tr("Emprise Créée")); manager.setRootGroup(_outResult, _outGroup, tr("Groupe")); manager.addItem(_outGroup, _outTile, tr("Emprise Créée")); manager.addResultCopy(_inResult); } void ONF_StepCreateTiling::compute() { Eigen::Vector2d minBB, maxBB; minBB(0) = std::numeric_limits::max(); minBB(1) = std::numeric_limits::max(); maxBB(0) = -std::numeric_limits::max(); maxBB(1) = -std::numeric_limits::max(); QList mins; QList maxs; setProgress(5); for (const CT_StandardItemGroup* group : _inGroup.iterateInputs(_inResult)) { for (const CT_AbstractSingularItemDrawable* item : group->singularItems(_inItem)) { if (item->hasBoundingBox()) // the header has to be geographical { Eigen::Vector3d min, max; item->boundingBox(min, max); if (!_keepEmptyTiles) { mins.append(min); maxs.append(max); } if (min(0) < minBB(0)) {minBB(0) = min(0);} if (min(1) < minBB(1)) {minBB(1) = min(1);} if (max(0) > maxBB(0)) {maxBB(0) = max(0);} if (max(1) > maxBB(1)) {maxBB(1) = max(1);} } else { PS_LOG->addMessage(LogInterface::warning, LogInterface::step, tr("Item (id= %1) sans BoundingBox (impossible de déterminer l'emprise)").arg(item->id())); } } } setProgress(50); if (_useRefCoord) { minBB(0) = std::floor((minBB(0) - _xRefCoord) / _tileSize) * _tileSize + _xRefCoord; minBB(1) = std::floor((minBB(1) - _yRefCoord) / _tileSize) * _tileSize + _yRefCoord; double maxx = maxBB(0); double maxy = maxBB(1); maxBB(0) = minBB(0); maxBB(1) = minBB(1); while (maxBB(0) < maxx) {maxBB(0) += _tileSize;} while (maxBB(1) < maxy) {maxBB(1) += _tileSize;} } for (CT_ResultGroup* outRes : _outResult.iterateOutputs()) { for (double x = minBB(0) ; x < maxBB(0) ; x += _tileSize) { for (double y = maxBB(1) ; y > minBB(1) ; y -= _tileSize) { Eigen::Vector2d min(x, y - _tileSize); Eigen::Vector2d max(x + _tileSize, y); bool found = false; if (!_keepEmptyTiles) { for (int i = 0 ; !found && i < mins.size() ; i++) { const Eigen::Vector3d& mini = mins.at(i); const Eigen::Vector3d& maxi = maxs.at(i); found = mini(0) < max(0) && maxi(0) > min(0) && mini(1) < max(1) && maxi(1) > min(1); } } if (found || _keepEmptyTiles) { CT_StandardItemGroup* group = new CT_StandardItemGroup(); outRes->addRootGroup(_outGroup, group); CT_Box2DData* boxData = new CT_Box2DData(min, max); CT_Box2D* box2D = new CT_Box2D( boxData); if (_nameByCoordinates) { Eigen::Vector3d min, max; box2D->boundingBox(min, max); box2D->setDisplayableName(QString("%1_%2").arg(QString::number(min(0), 'f', 0)).arg(QString::number(min(1), 'f', 0))); } group->addSingularItem(_outTile, box2D); } } } } setProgress(100); }