#include "onf_stepcomputepointheightfromdtm.h"
ONF_StepComputePointHeightFromDTM::ONF_StepComputePointHeightFromDTM() : SuperClass()
{
_ptsAttribute = false;
_ptsCloud = true;
_addLAS = false;
}
QString ONF_StepComputePointHeightFromDTM::description() const
{
return tr("Calculer la hauteur des points à l'aide d'un MNT");
}
QString ONF_StepComputePointHeightFromDTM::detailledDescription() const
{
return tr("Cette étape soustrait à l'altitude des points la coordonnée du MNT."
"En sortie, elle peut (options) générer :
"
"- Un attribut de hauteur sur le nuage d'altitudes
"
"- Un nuage de point
"
"- Recopier les attributs LAS (dans le cas de la création d'un nouveau nuage)");
}
QString ONF_StepComputePointHeightFromDTM::inputDescription() const
{
return SuperClass::inputDescription() + tr("
");
}
QString ONF_StepComputePointHeightFromDTM::outputDescription() const
{
return SuperClass::outputDescription() + tr("
");
}
QString ONF_StepComputePointHeightFromDTM::detailsDescription() const
{
return tr("");
}
CT_VirtualAbstractStep* ONF_StepComputePointHeightFromDTM::createNewInstance() const
{
return new ONF_StepComputePointHeightFromDTM();
}
//////////////////// PROTECTED METHODS //////////////////
void ONF_StepComputePointHeightFromDTM::declareInputModels(CT_StepInModelStructureManager& manager)
{
manager.addResult(_inResult, tr("Scene(s)"));
manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup);
manager.addGroup(_inZeroOrMoreRootGroup, _inGroup);
manager.addItem(_inGroup, _inScene, tr("Scene(s)"));
if (_addLAS)
manager.addItem(_inGroup, _inLAS, tr("Attributs LAS"));
manager.addResult(_inResultDTM, tr("MNT"), "", true);
manager.setZeroOrMoreRootGroup(_inResultDTM, _inZeroOrMoreRootGroupDTM);
manager.addGroup(_inZeroOrMoreRootGroupDTM, _inGroupDTM);
manager.addItem(_inGroupDTM, _inDTM, tr("MNT"));
}
void ONF_StepComputePointHeightFromDTM::declareOutputModels(CT_StepOutModelStructureManager& manager)
{
manager.addResultCopy(_inResult);
if (_ptsAttribute)
manager.addPointAttribute(_inGroup, _outHeightAtt, tr("Attribut Hauteur"));
if (_ptsCloud)
manager.addItem(_inGroup, _outScene, tr("Scene H"));
}
void ONF_StepComputePointHeightFromDTM::fillPreInputConfigurationDialog(CT_StepConfigurableDialog* preInputConfigDialog)
{
preInputConfigDialog->addBool(tr("Créer des attributs de points hauteur"), "", "", _ptsAttribute);
preInputConfigDialog->addEmpty();
preInputConfigDialog->addBool(tr("Créer un nuage de points hauteur"), "", "", _ptsCloud);
preInputConfigDialog->addBool(tr("Transférer les attributs las au nuage de points hauteur"), "", "", _addLAS);
}
void ONF_StepComputePointHeightFromDTM::compute()
{
const CT_Image2D* dtm = _inDTM.firstInput(_inResultDTM);
if ((dtm == nullptr) || (!_ptsAttribute && !_ptsCloud))
return;
auto iterator = _inScene.iterateOutputs(_inResult);
auto it = iterator.begin();
auto end = iterator.end();
while(it != end)
{
const CT_AbstractItemDrawableWithPointCloud* inputScene = *it;
CT_StandardItemGroup* grp = it.currentParent();
if (isStopped())
return;
const CT_AbstractPointCloudIndex *pointCloudIndex = inputScene->pointCloudIndex();
size_t n_points = pointCloudIndex->size();
CT_PointIterator itP(pointCloudIndex);
CT_NMPCIR heightCloud;
if (_ptsCloud) {heightCloud = PS_REPOSITORY->createNewPointCloud(n_points);}
CT_MutablePointIterator itPM(heightCloud);
// On declare un tableau d'attributs double que l'on va remplir avec les coordonnées correspondant a l'axe demandé
HeightAttManager::SetterPtr attributeSetter = nullptr;
if (_ptsAttribute) {attributeSetter = _outHeightAtt.createAttributesSetterPtr(heightCloud);}
float minAttribute = std::numeric_limits::max();
float maxAttribute = -std::numeric_limits::max();
size_t i = 0;
// On applique la translation a tous les points du nuage
while (itP.hasNext() && !isStopped())
{
CT_Point point = itP.next().currentPoint();
const float h = float(point(2)) - dtm->valueAtCoords(point(0), point(1));
if (_ptsAttribute)
{
attributeSetter->setValueWithGlobalIndex(itP.currentGlobalIndex(), h);
if (h < minAttribute) {minAttribute = h;}
if (h > maxAttribute) {maxAttribute = h;}
}
if (_ptsCloud)
{
point.setZ(double(h));
itPM.next().replaceCurrentPoint(point);
}
setProgress(float(100.0*i++ / n_points));
}
if (i > 0)
{
if (_ptsAttribute)
{
CT_PointsAttributesScalarTemplated* outAttribute = _outHeightAtt.createAttributeInstance(inputScene->pointCloudIndexRegistered(), minAttribute, maxAttribute);
grp->addSingularItem(_outHeightAtt, outAttribute);
}
if (_ptsCloud)
{
CT_Scene* outputHeightScene = new CT_Scene(heightCloud);
outputHeightScene->updateBoundingBox();
grp->addSingularItem(_outScene, outputHeightScene);
// Ajout des données LAS
if (_addLAS)
{
const CT_StdLASPointsAttributesContainer* attributeLAS = grp->singularItem(_inLAS);
if (attributeLAS != nullptr)
{
// Retrieve attributes
QHashIterator itLAS(attributeLAS->lasPointsAttributes());
while(itLAS.hasNext())
{
CT_AbstractPointAttributesScalar* v = itLAS.next().value();
if(v != nullptr)
v->copyAttributesOfSForD(inputScene->pointCloudIndexRegistered(), outputHeightScene->pointCloudIndexRegistered());
}
}
}
}
}
++it;
}
}