#include "onf_stepstandardizeintensity.h" // Utilise le depot #include "ct_global/ct_context.h" // Utilise les attributs optionnels #include "ct_itemdrawable/ct_pointsattributesscalartemplated.h" #include "ct_view/ct_stepconfigurabledialog.h" #include "ct_result/model/inModel/ct_inresultmodelgroup.h" #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/ct_outresultmodelgroupcopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" #include "ct_view/ct_stepconfigurabledialog.h" // Inclusion of standard result class #include "ct_result/ct_resultgroup.h" // Inclusion of used ItemDrawable classes #include "ct_itemdrawable/ct_scene.h" #include "ct_itemdrawable/ct_scanpath.h" #include "ct_iterator/ct_pointiterator.h" #include "ct_iterator/ct_groupiterator.h" #include "ct_iterator/ct_mutablepointiterator.h" #include "ctliblas/itemdrawable/las/ct_stdlaspointsattributescontainer.h" #include // Alias for indexing in models #define DEFin_resSc "resSc" #define DEFin_scGrp "scGrp" #define DEFin_attLAS "attLAS" #define DEFin_resTraj "resTraj" #define DEFin_TrajGrp "TrajGrp" #define DEFin_Traj "Traj" // Constructor : initialization of parameters ONF_StepStandardizeIntensity::ONF_StepStandardizeIntensity(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { _meanHeight = 500.0; } // Step description (tooltip of contextual menu) QString ONF_StepStandardizeIntensity::getStepDescription() const { return tr("Standardiser l'intensité (ALS)"); } // Step copy method CT_VirtualAbstractStep* ONF_StepStandardizeIntensity::createNewInstance(CT_StepInitializeData &dataInit) { return new ONF_StepStandardizeIntensity(dataInit); } //////////////////// PROTECTED METHODS ////////////////// // Creation and affiliation of IN models void ONF_StepStandardizeIntensity::createInResultModelListProtected() { CT_InResultModelGroupToCopy * resultSc = createNewInResultModelForCopy(DEFin_resSc, tr("Scene(s)"), "", true); resultSc->setZeroOrMoreRootGroup(); resultSc->addGroupModel("", DEFin_scGrp, CT_AbstractItemGroup::staticGetType(), tr("Group")); resultSc->addItemModel(DEFin_scGrp, DEFin_attLAS, CT_StdLASPointsAttributesContainer::staticGetType(), tr("Attributs LAS"), tr("Attribut LAS")); CT_InResultModelGroup *resultDTM = createNewInResultModel(DEFin_resTraj, tr("Trajectory"), "", true); resultDTM->setZeroOrMoreRootGroup(); resultDTM->addGroupModel("", DEFin_TrajGrp, CT_AbstractItemGroup::staticGetType(), tr("Group")); resultDTM->addItemModel(DEFin_TrajGrp, DEFin_Traj, CT_ScanPath::staticGetType(), tr("Trajectory")); } // Creation and affiliation of OUT models void ONF_StepStandardizeIntensity::createOutResultModelListProtected() { CT_OutResultModelGroupToCopyPossibilities *res = createNewOutResultModelToCopy(DEFin_resSc); if(res != NULL) { res->addItemModel(DEFin_scGrp, _lasAttributesOut_AutoRenameModel, new CT_StdLASPointsAttributesContainer(), tr("All Attributs (Icorr)")); res->addItemModel(DEFin_scGrp, _outIntensityAttributeModelName, new CT_PointsAttributesScalarTemplated(), tr("Corrected intensity")); } } // Semi-automatic creation of step parameters DialogBox void ONF_StepStandardizeIntensity::createPostConfigurationDialog() { CT_StepConfigurableDialog *configDialog = newStandardPostConfigurationDialog(); configDialog->addDouble(tr("Altitude moyenne du vol"), "m", 1, 1e+10, 2, _meanHeight); } void ONF_StepStandardizeIntensity::compute() { CT_ResultGroup* resin_Traj = getInputResults().at(1); QList trajectories; CT_ResultItemIterator it(resin_Traj, this, DEFin_Traj); while (it.hasNext()) { trajectories.append((CT_ScanPath*) it.next()); } if (trajectories.size() > 0) { CT_ResultGroup* resOut = getOutResultList().first(); CT_ResultGroupIterator itSc(resOut, this, DEFin_scGrp); while (itSc.hasNext()) { CT_StandardItemGroup* grp = (CT_StandardItemGroup*) itSc.next(); if (grp != NULL) { const CT_StdLASPointsAttributesContainer* attributeLAS = (CT_StdLASPointsAttributesContainer*)grp->firstItemByINModelName(this, DEFin_attLAS); if (attributeLAS != NULL && !isStopped()) { // Retrieve attributes QHashIterator itLAS(attributeLAS->lasPointsAttributes()); if (!itLAS.hasNext()) {return;} CT_AbstractPointAttributesScalar *firstAttribute = itLAS.next().value(); if (firstAttribute == NULL) {return;} const CT_AbstractPointCloudIndex* pointCloudIndexLAS = firstAttribute->getPointCloudIndex(); size_t n_points = pointCloudIndexLAS->size(); if (pointCloudIndexLAS == NULL) {return;} CT_AbstractPointAttributesScalar* att_Intensity = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Intensity); CT_AbstractPointAttributesScalar* att_Return_Number = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Return_Number); CT_AbstractPointAttributesScalar* att_Number_of_Returns = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Number_of_Returns); CT_AbstractPointAttributesScalar* att_Classification_Flags = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Classification_Flags); CT_AbstractPointAttributesScalar* att_Scanner_Channel = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Scanner_Channel); CT_AbstractPointAttributesScalar* att_Scan_Direction_Flag = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Scan_Direction_Flag); CT_AbstractPointAttributesScalar* att_Edge_of_Flight_Line = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Edge_of_Flight_Line); CT_AbstractPointAttributesScalar* att_Classification = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Classification); CT_AbstractPointAttributesScalar* att_Scan_Angle_Rank = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Scan_Angle_Rank); CT_AbstractPointAttributesScalar* att_User_Data = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::User_Data); CT_AbstractPointAttributesScalar* att_Point_Source_ID = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Point_Source_ID); CT_AbstractPointAttributesScalar* att_GPS_Time = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::GPS_Time); CT_AbstractPointAttributesScalar* att_Red = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Red); CT_AbstractPointAttributesScalar* att_Green = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Green); CT_AbstractPointAttributesScalar* att_Blue = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Blue); CT_AbstractPointAttributesScalar* att_NIR = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::NIR); CT_AbstractPointAttributesScalar* att_Wave_Packet_Descriptor_Index = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Wave_Packet_Descriptor_Index); CT_AbstractPointAttributesScalar* att_Byte_offset_to_waveform_data = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Byte_offset_to_waveform_data); CT_AbstractPointAttributesScalar* att_Waveform_packet_size_in_bytes = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Waveform_packet_size_in_bytes); CT_AbstractPointAttributesScalar* att_Return_Point_Waveform_Location = (CT_AbstractPointAttributesScalar*)attributeLAS->pointsAttributesAt(CT_LasDefine::Return_Point_Waveform_Location); if (att_Intensity == NULL || att_GPS_Time == NULL) {return;} CT_StdLASPointsAttributesContainer *container = new CT_StdLASPointsAttributesContainer(_lasAttributesOut_AutoRenameModel.completeName(), resOut); // Put old not modified data in new container //CT_LasDefine::Intensity : Modified after container->insertPointsAttributesAt(CT_LasDefine::Return_Number, att_Return_Number); container->insertPointsAttributesAt(CT_LasDefine::Number_of_Returns, att_Number_of_Returns); container->insertPointsAttributesAt(CT_LasDefine::Classification_Flags, att_Classification_Flags); container->insertPointsAttributesAt(CT_LasDefine::Scanner_Channel, att_Scanner_Channel); container->insertPointsAttributesAt(CT_LasDefine::Scan_Direction_Flag, att_Scan_Direction_Flag); container->insertPointsAttributesAt(CT_LasDefine::Edge_of_Flight_Line, att_Edge_of_Flight_Line); container->insertPointsAttributesAt(CT_LasDefine::Classification, att_Classification); container->insertPointsAttributesAt(CT_LasDefine::Scan_Angle_Rank, att_Scan_Angle_Rank); container->insertPointsAttributesAt(CT_LasDefine::User_Data, att_User_Data); container->insertPointsAttributesAt(CT_LasDefine::Point_Source_ID, att_Point_Source_ID); container->insertPointsAttributesAt(CT_LasDefine::GPS_Time, att_GPS_Time); container->insertPointsAttributesAt(CT_LasDefine::Red, att_Red); container->insertPointsAttributesAt(CT_LasDefine::Green, att_Green); container->insertPointsAttributesAt(CT_LasDefine::Blue, att_Blue); container->insertPointsAttributesAt(CT_LasDefine::NIR, att_NIR); container->insertPointsAttributesAt(CT_LasDefine::Wave_Packet_Descriptor_Index, att_Wave_Packet_Descriptor_Index); container->insertPointsAttributesAt(CT_LasDefine::Byte_offset_to_waveform_data, att_Byte_offset_to_waveform_data); container->insertPointsAttributesAt(CT_LasDefine::Waveform_packet_size_in_bytes, att_Waveform_packet_size_in_bytes); container->insertPointsAttributesAt(CT_LasDefine::Return_Point_Waveform_Location, att_Return_Point_Waveform_Location); CT_PointIterator itP(pointCloudIndexLAS); CT_StandardCloudStdVectorT *intensityAttribute = new CT_StandardCloudStdVectorT(); double minAttribute = std::numeric_limits::max(); double maxAttribute = -std::numeric_limits::max(); size_t localIndex = 0; size_t errorCount = 0; while (itP.hasNext() && !isStopped()) { CT_Point point = itP.next().currentPoint(); double gpsTime = 0; // Récupération du temps GPS pour le point double intensity = 0; // Récupération de l'intensité pour le point if (localIndex < pointCloudIndexLAS->size()) { gpsTime = att_GPS_Time->dValueAt(localIndex); intensity = att_Intensity->dValueAt(localIndex); } bool found = false; Eigen::Vector3d trajCoord; for (int tra = 0 ; tra < trajectories.size() && !found ; tra++) { CT_ScanPath* sp = trajectories.at(tra); if (sp->isInScanPath(gpsTime)) { trajCoord = 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))); } } intensityAttribute->addT(corItensity); setProgress( 95.0*localIndex++ / 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 = new CT_PointsAttributesScalarTemplated(_outIntensityAttributeModelName.completeName(), resOut, firstAttribute->getPointCloudIndexRegistered(), intensityAttribute, minAttribute, maxAttribute); container->insertPointsAttributesAt(CT_LasDefine::Intensity, attOut_Intensity); grp->addItemDrawable(attOut_Intensity); grp->addItemDrawable(container); } } } } }