#include "onf_stepcomputerelativeintensityattribute.h"
ONF_StepComputeRelativeIntensityAttribute::ONF_StepComputeRelativeIntensityAttribute() : SuperClass()
{
}
QString ONF_StepComputeRelativeIntensityAttribute::description() const
{
return tr("Calculer l'intensité relative");
}
QString ONF_StepComputeRelativeIntensityAttribute::detailledDescription() const
{
return tr("L'intensité relative est calculée de façon à ce que la somme des intensité d'un rayon (tous les retours) fasse 1.");
}
QString ONF_StepComputeRelativeIntensityAttribute::inputDescription() const
{
return SuperClass::inputDescription() + tr("
");
}
QString ONF_StepComputeRelativeIntensityAttribute::outputDescription() const
{
return SuperClass::outputDescription() + tr("
");
}
QString ONF_StepComputeRelativeIntensityAttribute::detailsDescription() const
{
return tr("");
}
CT_VirtualAbstractStep* ONF_StepComputeRelativeIntensityAttribute::createNewInstance() const
{
return new ONF_StepComputeRelativeIntensityAttribute();
}
//////////////////// PROTECTED METHODS //////////////////
void ONF_StepComputeRelativeIntensityAttribute::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)"));
manager.addItem(_inGroup, _inLas, tr("Attributs LAS"));
}
void ONF_StepComputeRelativeIntensityAttribute::declareOutputModels(CT_StepOutModelStructureManager& manager)
{
manager.addResultCopy(_inResult);
manager.addItem(_inGroup, _outAtt, tr("Relative intensity"));
}
void ONF_StepComputeRelativeIntensityAttribute::compute()
{
auto iterator = _inScene.iterateOutputs(_inResult);
auto it = iterator.begin();
auto end = iterator.end();
QList candidatePoints;
while(it != end)
{
const CT_AbstractItemDrawableWithPointCloud* scene = *it;
candidatePoints.reserve(int(scene->pointCloudIndexSize()));
CT_StandardItemGroup* grp = it.currentParent();
CT_AbstractPointAttributesScalar* attributeGPS = nullptr;
CT_AbstractPointAttributesScalar* attributeIntensity = nullptr;
for(const CT_StdLASPointsAttributesContainer* attributeLAS : grp->singularItems(_inLas))
{
attributeGPS = dynamic_cast(attributeLAS->pointsAttributesAt(CT_LasDefine::GPS_Time));
attributeIntensity = dynamic_cast(attributeLAS->pointsAttributesAt(CT_LasDefine::Intensity));
if (attributeIntensity != nullptr && attributeGPS != nullptr)
break;
}
if (isStopped())
return;
if (attributeIntensity != nullptr && attributeGPS != nullptr)
{
CT_PointIterator itP(scene->pointCloudIndexRegistered());
while(itP.hasNext())
{
if (isStopped())
return;
itP.next();
const auto gi = itP.currentGlobalIndex();
if(attributeGPS->hasBeenSet(gi) && attributeIntensity->hasBeenSet(gi))
{
const double gpsTime = attributeGPS->scalarAsDoubleAt(gi);
const double intensity = attributeIntensity->scalarAsDoubleAt(gi);
candidatePoints.append(new CandidatePoint(gi, gpsTime, intensity));
}
}
std::sort(candidatePoints.begin(), candidatePoints.end(), sortByGPSTime);
double intensitySum = 0;
int ibegin = 0;
if (candidatePoints.size() > 0) {intensitySum = candidatePoints.first()->_intensity;}
for (int i = 1 ; i < candidatePoints.size() ; i++)
{
if (isStopped())
return;
CandidatePoint* cp0 = candidatePoints.at(i-1);
CandidatePoint* cp1 = candidatePoints.at(i);
if (!qFuzzyCompare(cp1->_gpsTime, cp0->_gpsTime))
{
for (int j = ibegin ; j < i ; j++)
{
candidatePoints.at(j)->_sumIntensity = intensitySum;
}
intensitySum = cp1->_intensity;
ibegin = i;
} else {
intensitySum += cp1->_intensity;
}
}
CT_DenseAttributeSetter setter = _outAtt.createAttributesSetter(scene->pointCloudIndexRegistered().dynamicCast());
double minAttribute = std::numeric_limits::max();
double maxAttribute = -std::numeric_limits::max();
for (int i = 0 ; i < candidatePoints.size() ; i++)
{
if (isStopped())
return;
CandidatePoint* cp = candidatePoints.at(i);
double intensityRel = 0;
if (cp->_sumIntensity > 0) {intensityRel = cp->_intensity / cp->_sumIntensity;}
setter.setValueWithGlobalIndex(cp->_pointIndex, intensityRel);
if (intensityRel < minAttribute) {minAttribute = intensityRel;}
if (intensityRel > maxAttribute) {maxAttribute = intensityRel;}
}
if (candidatePoints.size() > 0)
{
grp->addSingularItem(_outAtt, _outAtt.createAttributeInstance(scene->pointCloudIndexRegistered(), minAttribute, maxAttribute));
}
qDeleteAll(candidatePoints);
candidatePoints.clear();
}
++it;
}
}