#include "onf_stepcreatemaximacloud.h"
#include "ct_log/ct_logmanager.h"
ONF_StepCreateMaximaCloud::ONF_StepCreateMaximaCloud() : SuperClass()
{
_createRefPoints = false;
}
QString ONF_StepCreateMaximaCloud::description() const
{
return tr("Créer un nuage de points de maxima");
}
QString ONF_StepCreateMaximaCloud::detailledDescription() const
{
return tr("Créer un nuage de points à partir d'un raster de maxima (un numéro d'ID par maximum).");
}
QString ONF_StepCreateMaximaCloud::inputDescription() const
{
return SuperClass::inputDescription() + tr("
");
}
QString ONF_StepCreateMaximaCloud::outputDescription() const
{
return SuperClass::outputDescription() + tr("
");
}
QString ONF_StepCreateMaximaCloud::detailsDescription() const
{
return tr("");
}
QString ONF_StepCreateMaximaCloud::URL() const
{
//return tr("STEP URL HERE");
return SuperClass::URL(); //by default URL of the plugin
}
CT_VirtualAbstractStep* ONF_StepCreateMaximaCloud::createNewInstance() const
{
return new ONF_StepCreateMaximaCloud();
}
//////////////////// PROTECTED METHODS //////////////////
void ONF_StepCreateMaximaCloud::declareInputModels(CT_StepInModelStructureManager& manager)
{
manager.addResult(_inResult, tr("Scene(s)"));
manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup);
manager.addGroup(_inZeroOrMoreRootGroup, _inGroup);
manager.addItem(_inGroup, _inHeights, tr("Raster (hauteurs)"));
manager.addItem(_inGroup, _inMaxima, tr("Raster Maxima"));
manager.addItem(_inGroup, _inDTM, tr("MNT"));
manager.addItem(_inGroup, _inArea, tr("Emprise"));
}
void ONF_StepCreateMaximaCloud::declareOutputModels(CT_StepOutModelStructureManager& manager)
{
manager.addResultCopy(_inResult);
if (_createRefPoints == 0)
{
manager.addItem(_inGroup, _outScene, tr("Maxima (points)"));
} else {
manager.addGroup(_inGroup, _outGroup, tr("Groupe"));
manager.addItem(_outGroup, _outRefPt, tr("Maximum (point)"));
}
}
void ONF_StepCreateMaximaCloud::fillPreInputConfigurationDialog(CT_StepConfigurableDialog* preInputConfigDialog)
{
CT_ButtonGroup &bg_mode = preInputConfigDialog->addButtonGroup(_createRefPoints);
preInputConfigDialog->addExcludeValue("", "", tr("Créer un nuage de points"), bg_mode, 0);
preInputConfigDialog->addExcludeValue("", "", tr("Créer des points de référence"), bg_mode, 1);
}
void ONF_StepCreateMaximaCloud::compute()
{
for (CT_StandardItemGroup* grp : _inGroup.iterateOutputs(_inResult))
{
for (const CT_Image2D* maximaIn : grp->singularItems(_inMaxima))
{
if (isStopped()) {return;}
const CT_Image2D* imageIn = grp->singularItem(_inHeights);
const CT_Image2D* dtm = grp->singularItem(_inDTM);
const CT_AbstractAreaShape2D* emprise = grp->singularItem(_inArea);
if (dtm != nullptr)
{
PS_LOG->addMessage(LogInterface::info, LogInterface::step, QString(tr("Un MNT a été founit, les valeurs Z des maxima seront corrigées")));
} else {
PS_LOG->addMessage(LogInterface::info, LogInterface::step, QString(tr("Aucun MNT n'a été founit, les valeurs Z des maxima NE seront PAS corrigées")));
}
// Get maxima coordinates list
QMultiMap maximaCoords;
for (int xx = 0 ; xx < maximaIn->xdim() ; xx++)
{
for (int yy = 0 ; yy < maximaIn->ydim() ; yy++)
{
qint32 maximaID = maximaIn->value(xx, yy);
if (maximaID > 0 && maximaID != maximaIn->NA())
{
Eigen::Vector3d* coords = new Eigen::Vector3d();
if (maximaIn->getCellCenterCoordinates(xx, yy, *coords))
{
if (emprise == nullptr || emprise->contains((*coords)(0), (*coords)(1)))
{
(*coords)(2) = imageIn->value(xx, yy);
maximaCoords.insert(maximaID, coords);
}
}
}
}
}
setProgress(25);
QList maximaList = maximaCoords.uniqueKeys();
int mxSize = maximaList.size();
CT_NMPCIR pcir;
CT_MutablePointIterator *it = nullptr;
CT_Point pReaded;
if (_createRefPoints == 0)
{
pcir = PS_REPOSITORY->createNewPointCloud(mxSize);
it = new CT_MutablePointIterator(pcir);
}
// Create maxima coords vector
for (int i = 0 ; i < mxSize ; i++)
{
qint32 id = maximaList.at(i);
QList coordinates = maximaCoords.values(id);
double x = 0;
double y = 0;
double z = -std::numeric_limits::max();
// Compute position of the current maxima if more than one pixel
int size = coordinates.size();
if (size > 0)
{
for (int j = 0 ; j < size ; j++)
{
Eigen::Vector3d* pos = coordinates.at(j);
x += (*pos)(0);
y += (*pos)(1);
if ((*pos)(2) > z) {z = (*pos)(2);}
}
x /= size;
y /= size;
if (dtm != nullptr)
{
float dtmVal = dtm->valueAtCoords(x, y);
if (dtmVal != dtm->NA())
{
z -= dtmVal;
}else
{
PS_LOG->addMessage(LogInterface::error, LogInterface::step, QString(tr("Valeur manquante dans le MNT pour un l'apex : x=%1 ; y=%2").arg(x).arg(y)));
}
}
}
if (_createRefPoints == 0)
{
pReaded(CT_Point::X) = x;
pReaded(CT_Point::Y) = y;
pReaded(CT_Point::Z) = z;
it->next();
it->replaceCurrentPoint(pReaded);
} else {
CT_StandardItemGroup* grpPt = new CT_StandardItemGroup();
grp->addGroup(_outGroup, grpPt);
CT_ReferencePoint* refPoint = new CT_ReferencePoint(x, y, z, 0);
grpPt->addSingularItem(_outRefPt, refPoint);
}
}
setProgress(60);
if (_createRefPoints == 0)
{
CT_Scene* sceneMaxima = new CT_Scene(pcir);
sceneMaxima->updateBoundingBox();
grp->addSingularItem(_outScene, sceneMaxima);
}
setProgress(80);
}
}
setProgress(100);
}