#include "onf_stepstandardizeintensity.h"
#include "ct_log/ct_logmanager.h"
ONF_StepStandardizeIntensity::ONF_StepStandardizeIntensity() : SuperClass()
{
_meanHeight = 500.0;
}
QString ONF_StepStandardizeIntensity::description() const
{
return tr("Standardiser l'intensité (ALS)");
}
QString ONF_StepStandardizeIntensity::detailledDescription() const
{
return tr("");
}
QString ONF_StepStandardizeIntensity::inputDescription() const
{
return SuperClass::inputDescription() + tr("
");
}
QString ONF_StepStandardizeIntensity::outputDescription() const
{
return SuperClass::outputDescription() + tr("
");
}
QString ONF_StepStandardizeIntensity::detailsDescription() const
{
return tr("");
}
CT_VirtualAbstractStep* ONF_StepStandardizeIntensity::createNewInstance() const
{
return new ONF_StepStandardizeIntensity();
}
//////////////////// PROTECTED METHODS //////////////////
void ONF_StepStandardizeIntensity::declareInputModels(CT_StepInModelStructureManager& manager)
{
manager.addResult(_inResult, tr("Scene(s)"), "", true);
manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup);
manager.addGroup(_inZeroOrMoreRootGroup, _inGroup);
manager.addItem(_inGroup, _inScene, tr("Scene(s)"));
manager.addItem(_inGroup, _inAttLAS, tr("Attributs LAS"));
manager.addResult(_inResultTraj, tr("Trajectory"), "", true);
manager.setZeroOrMoreRootGroup(_inResultTraj, _inZeroOrMoreRootGroupTraj);
manager.addGroup(_inZeroOrMoreRootGroupTraj, _inGroupTraj);
manager.addItem(_inGroupTraj, _inTraj, tr("Trajectory"));
}
void ONF_StepStandardizeIntensity::declareOutputModels(CT_StepOutModelStructureManager& manager)
{
manager.addResultCopy(_inResult);
manager.addItem(_inGroup, _lasAttributesOut, tr("Attributs LAS (Icorr)"));
manager.addItem(_inGroup, _outIntensityAttribute, tr("Corrected intensity"));
}
void ONF_StepStandardizeIntensity::fillPostInputConfigurationDialog(CT_StepConfigurableDialog* postInputConfigDialog)
{
postInputConfigDialog->addDouble(tr("Altitude moyenne du vol"), "m", 1, std::numeric_limits::max(), 2, _meanHeight);
}
void ONF_StepStandardizeIntensity::compute()
{
QList trajectories;
for (const CT_ScanPath* scanPath : _inTraj.iterateInputs(_inResultTraj))
{
trajectories.append(scanPath);
}
if (trajectories.size() == 0)
return;
auto iterator = _inScene.iterateOutputs(_inResult);
auto it = iterator.begin();
auto end = iterator.end();
while(it != end)
{
const CT_AbstractItemDrawableWithPointCloud* scene = *it;
CT_StandardItemGroup* grp = it.currentParent();
const CT_StdLASPointsAttributesContainer* attributeLAS = nullptr;
CT_AbstractPointAttributesScalar* attributeGPS = nullptr;
CT_AbstractPointAttributesScalar* attributeIntensity = nullptr;
for(const CT_StdLASPointsAttributesContainer* attLAS : grp->singularItems(_inAttLAS))
{
attributeGPS = dynamic_cast(attLAS->pointsAttributesAt(CT_LasDefine::GPS_Time));
attributeIntensity = dynamic_cast(attLAS->pointsAttributesAt(CT_LasDefine::Intensity));
if (attributeIntensity != nullptr && attributeGPS != nullptr)
{
attributeLAS = attLAS;
break;
}
}
if (isStopped())
return;
if (attributeIntensity != nullptr && attributeGPS != nullptr)
{
// Put old not modified data in new container
// CT_LasDefine::Intensity : Modified after
CT_StdLASPointsAttributesContainer* container = new CT_StdLASPointsAttributesContainer(*attributeLAS);
auto intensityCorrectedSetter = _outIntensityAttribute.createAttributesSetter(scene->pointCloudIndexRegistered().dynamicCast());
double minAttribute = std::numeric_limits::max();
double maxAttribute = -std::numeric_limits::max();
size_t localIndex = 0;
size_t errorCount = 0;
const size_t n_points = scene->pointCloudIndexSize();
CT_PointIterator itP(scene->pointCloudIndexRegistered());
while(itP.hasNext())
{
if (isStopped())
return;
CT_Point point = itP.next().currentPoint();
const auto gi = itP.currentGlobalIndex();
if(attributeGPS->hasBeenSet(gi) && attributeIntensity->hasBeenSet(gi))
{
double gpsTime = attributeGPS->scalarAsDoubleAt(gi);
double intensity = attributeIntensity->scalarAsDoubleAt(gi);
bool found = false;
Eigen::Vector3d trajCoord;
for (int tra = 0 ; tra < trajectories.size() && !found ; tra++)
{
const CT_ScanPath* sp = trajectories.at(tra);
if (sp->isInScanPath(gpsTime))
{
trajCoord = const_cast(sp)->getPathPointForGPSTime(gpsTime);
found = true;
}
}
double length = -1;
double corItensity = intensity;
if (found)
{
length = sqrt(pow(point(0) - trajCoord(0), 2) + pow(point(1) - trajCoord(1), 2) + pow(point(2) - trajCoord(2), 2));
double ratio = length/_meanHeight;
ratio = ratio*ratio;
corItensity = corItensity * ratio;
if (corItensity < minAttribute) {minAttribute = corItensity;}
if (corItensity > maxAttribute) {maxAttribute = corItensity;}
} else {
errorCount++;
if (errorCount < 5)
{
PS_LOG->addMessage(LogInterface::warning, LogInterface::step, QString(tr("Pas d'information de trajectoire pour le point (%1 ; %2 ; %3)")).arg(point(0)).arg(point(1)).arg(point(2)));
}
}
intensityCorrectedSetter.setValueWithGlobalIndex(gi, corItensity);
}
setProgress( 95.0f*float(localIndex++) / float(n_points));
}
if (errorCount > 0) {PS_LOG->addMessage(LogInterface::warning, LogInterface::step, QString(tr("Pas d'information de trajectoire pour au total %1 points sur %2")).arg(errorCount).arg(localIndex));}
CT_PointsAttributesScalarTemplated* attOut_Intensity = _outIntensityAttribute.createAttributeInstance(scene->pointCloudIndexRegistered(), minAttribute, maxAttribute);
container->insertPointsAttributesAt(CT_LasDefine::Intensity, attOut_Intensity);
grp->addSingularItem(_outIntensityAttribute, attOut_Intensity);
grp->addSingularItem(_lasAttributesOut, container);
}
++it;
}
}