#include "onf_stepcomputedominanceindicators.h" #include "ct_itemdrawable/tools/iterator/ct_groupiterator.h" #include "ct_result/ct_resultgroup.h" #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" #include "ct_view/ct_stepconfigurabledialog.h" #include "ct_itemdrawable/ct_referencepoint.h" #include "ct_itemdrawable/ct_attributeslist.h" #include "ct_itemdrawable/ct_scene.h" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" // Alias for indexing models #define DEFin_res "res" #define DEFin_grp "grp" #define DEFin_apexItem "apex" #define DEFin_attXApex "XApex" #define DEFin_attYApex "YApex" #define DEFin_attZApex "ZApex" #define DEFin_attDiameter "Diameter" #define DEFin_outputItem "outitem" #define DEFin_resDTM "resdtm" #define DEFin_DTMGrp "dtmgrp" #define DEFin_DTM "dtm" // Constructor : initialization of parameters ONF_StepComputeDominanceIndicators::ONF_StepComputeDominanceIndicators(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { _outItem = false; } // Step description (tooltip of contextual menu) QString ONF_StepComputeDominanceIndicators::getStepDescription() const { return tr("Calcul de l'indice de compétition de Schutz 1989"); } // Step detailled description QString ONF_StepComputeDominanceIndicators::getStepDetailledDescription() const { return tr("No detailled description for this step"); } // Step URL QString ONF_StepComputeDominanceIndicators::getStepURL() const { //return tr("STEP URL HERE"); return CT_AbstractStep::getStepURL(); //by default URL of the plugin } // Step copy method CT_VirtualAbstractStep* ONF_StepComputeDominanceIndicators::createNewInstance(CT_StepInitializeData &dataInit) { return new ONF_StepComputeDominanceIndicators(dataInit); } //////////////////// PROTECTED METHODS ////////////////// // Creation and affiliation of IN models void ONF_StepComputeDominanceIndicators::createInResultModelListProtected() { CT_InResultModelGroupToCopy *resIn_res = createNewInResultModelForCopy(DEFin_res, tr("Apex")); resIn_res->setZeroOrMoreRootGroup(); resIn_res->addGroupModel("", DEFin_grp, CT_AbstractItemGroup::staticGetType(), tr("Groupe")); resIn_res->addItemModel(DEFin_grp, DEFin_apexItem, CT_AbstractSingularItemDrawable::staticGetType(), tr("Apex")); resIn_res->addItemAttributeModel(DEFin_apexItem, DEFin_attXApex, QList() << CT_AbstractCategory::DATA_VALUE, CT_AbstractCategory::NUMBER, tr("X_Apex")); resIn_res->addItemAttributeModel(DEFin_apexItem, DEFin_attYApex, QList() << CT_AbstractCategory::DATA_VALUE, CT_AbstractCategory::NUMBER, tr("Y_Apex")); resIn_res->addItemAttributeModel(DEFin_apexItem, DEFin_attZApex, QList() << CT_AbstractCategory::DATA_VALUE, CT_AbstractCategory::NUMBER, tr("Z_Apex")); resIn_res->addItemAttributeModel(DEFin_apexItem, DEFin_attDiameter, QList() << CT_AbstractCategory::DATA_VALUE, CT_AbstractCategory::NUMBER, tr("Diametre_Houppier")); if (_outItem) { resIn_res->addItemModel(DEFin_grp, DEFin_outputItem, CT_AbstractSingularItemDrawable::staticGetType(), tr("Item de sortie")); } CT_InResultModelGroup *resultDTM = createNewInResultModel(DEFin_resDTM, tr("MNT"), "", true); resultDTM->setZeroOrMoreRootGroup(); resultDTM->addGroupModel("", DEFin_DTMGrp, CT_AbstractItemGroup::staticGetType(), tr("Group")); resultDTM->addItemModel(DEFin_DTMGrp, DEFin_DTM, CT_Image2D::staticGetType(), tr("MNT")); resultDTM->setMinimumNumberOfPossibilityThatMustBeSelectedForOneTurn(0); } // Creation and affiliation of OUT models void ONF_StepComputeDominanceIndicators::createOutResultModelListProtected() { CT_OutResultModelGroupToCopyPossibilities *resCpy_res = createNewOutResultModelToCopy(DEFin_res); if (resCpy_res != NULL) { resCpy_res->addItemModel(DEFin_grp, _itemAtt_ModelName, new CT_AttributesList(), tr("indiceSchutz")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzTotal_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzTotal")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzHorTotal_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorTotal")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzVerTotal_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerTotal")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzMax_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzMax")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzHorMax_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorMax")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _indiceSchutzVerMax_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerMax")); resCpy_res->addItemAttributeModel(_itemAtt_ModelName, _angleNeighbMax_ModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("angleNeighbMax")); if (_outItem) { resCpy_res->addItemModel(DEFin_grp, _outScene_ModelName, new CT_Scene(), tr("Scene")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzTotal_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzTotal")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzHorTotal_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorTotal")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzVerTotal_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerTotal")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzVerTotalINT_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerTotalINT")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzMax_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzMax")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzHorMax_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorMax")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _indiceSchutzVerMax_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerMax")); resCpy_res->addItemAttributeModel(_outScene_ModelName, _angleNeighbMax_OutModelName, new CT_StdItemAttributeT(CT_AbstractCategory::DATA_VALUE), tr("angleNeighbMax")); } } } // Semi-automatic creation of step parameters DialogBox void ONF_StepComputeDominanceIndicators::createPreConfigurationDialog() { CT_StepConfigurableDialog *configDialog = newStandardPreConfigurationDialog(); configDialog->addBool(tr("Ajouter les attributs à un autre item en copie"), "", "", _outItem); } // Semi-automatic creation of step parameters DialogBox void ONF_StepComputeDominanceIndicators::createPostConfigurationDialog() { // CT_StepConfigurableDialog *configDialog = newStandardPostConfigurationDialog(); } void ONF_StepComputeDominanceIndicators::compute() { QList outResultList = getOutResultList(); CT_ResultGroup* res = outResultList.at(0); CT_Image2D* mnt = NULL; if (getInputResults().size() > 1) { CT_ResultGroup* resin_DTM = getInputResults().at(1); CT_ResultItemIterator it(resin_DTM, this, DEFin_DTM); if (it.hasNext()) { mnt = (CT_Image2D*) it.next(); } } double minx = std::numeric_limits::max(); double miny = std::numeric_limits::max(); double maxx = -std::numeric_limits::max(); double maxy = -std::numeric_limits::max(); QList apexList; // COPIED results browsing CT_ResultGroupIterator itCpy_grp(res, this, DEFin_grp); while (itCpy_grp.hasNext() && !isStopped()) { CT_StandardItemGroup* grp = (CT_StandardItemGroup*) itCpy_grp.next(); CT_AbstractSingularItemDrawable* apexItem = (CT_AbstractSingularItemDrawable*)grp->firstItemByINModelName(this, DEFin_apexItem); CT_AbstractSingularItemDrawable* outItem = NULL; if (_outItem) {outItem = (CT_AbstractSingularItemDrawable*)grp->firstItemByINModelName(this, DEFin_outputItem);} if (apexItem != NULL) { CT_AbstractItemAttribute *attXApex = apexItem->firstItemAttributeByINModelName(res, this, DEFin_attXApex); CT_AbstractItemAttribute *attYApex = apexItem->firstItemAttributeByINModelName(res, this, DEFin_attYApex); CT_AbstractItemAttribute *attZApex = apexItem->firstItemAttributeByINModelName(res, this, DEFin_attZApex); CT_AbstractItemAttribute *attDiameter = apexItem->firstItemAttributeByINModelName(res, this, DEFin_attDiameter); if (attXApex != NULL && attYApex != NULL && attZApex != NULL && attDiameter != NULL) { bool okX, okY, okZ, okDiameter; double valX = attXApex->toDouble(apexItem, &okX); double valY = attYApex->toDouble(apexItem, &okY); double valZ = attZApex->toDouble(apexItem, &okZ); double valDiameter = attDiameter->toDouble(apexItem, &okDiameter); if (okX && okY && okZ && okDiameter) { if (valX < minx) {minx = valX;} if (valY < miny) {miny = valY;} if (valX > maxx) {maxx = valX;} if (valY > maxy) {maxy = valY;} size_t index; double valH = valZ; if (mnt != NULL && mnt->indexAtCoords(valX, valY, index)) { double zval = mnt->valueAtIndex(index); if (zval != mnt->NA()) { valH -= zval; } } apexList.append(new Apex(valX, valY, valZ, valH, valDiameter, grp, outItem)); } } } } setProgress(50); QMap apexMap; // Compute triangulation CT_DelaunayTriangulation *delaunay = new CT_DelaunayTriangulation(); delaunay->init(minx - 1.0, miny - 1.0, maxx + 1.0, maxy + 1.0); for (int i = 0 ; i < apexList.size() ; i++) { Apex* apex = apexList.at(i); Eigen::Vector3d *coord = new Eigen::Vector3d(apex->_x, apex->_y, apex->_h); CT_DelaunayVertex* delaunayVertex = delaunay->addVertex(coord, true); apexMap.insert(delaunayVertex, apex); } delaunay->doInsertion(); delaunay->computeVerticesNeighbors(); QMapIterator itM(apexMap); while (itM.hasNext()) { double indiceSchutzTotal = 0; double indiceSchutzHorTotal = 0; double indiceSchutzVerTotal = 0; double indiceSchutzMax = 0; double indiceSchutzHorMax = 0; double indiceSchutzVerMax = 0; double angleNeighbMax = 0; itM.next(); CT_DelaunayVertex* baseVertex = itM.key(); Apex* baseApex = itM.value(); QList &neighbours = baseVertex->getNeighbors(); for (int j = 0 ; j < neighbours.size() ; j++) { CT_DelaunayVertex* neighbour = neighbours.at(j); Apex* neighbApex = apexMap.value(neighbour); if (neighbApex != NULL) { double dist2D = std::sqrt(pow(baseApex->_x - neighbApex->_x, 2) + pow(baseApex->_y - neighbApex->_y, 2)); double deltaH = neighbApex->_h - baseApex->_h; double sommeRadius = baseApex->_diameter / 2.0 + neighbApex->_diameter / 2.0; double indiceSchutzHor = 0.5 - (dist2D - sommeRadius) / sommeRadius; if (dist2D < sommeRadius) {indiceSchutzHor = 0.5;} double indiceSchutzVer = 0.65 * deltaH / dist2D; double indiceSchutz = indiceSchutzHor + indiceSchutzVer; if (indiceSchutz < 0) {indiceSchutz = 0;} if (indiceSchutzHor < 0) {indiceSchutzHor = 0;} if (indiceSchutzVer < 0) {indiceSchutzVer = 0;} indiceSchutzTotal += indiceSchutz; indiceSchutzHorTotal += indiceSchutzHor; indiceSchutzVerTotal += indiceSchutzVer; if (indiceSchutz > indiceSchutzMax) {indiceSchutzMax = indiceSchutz;} if (indiceSchutzHor > indiceSchutzHorMax) {indiceSchutzHorMax = indiceSchutzHor;} if (indiceSchutzVer > indiceSchutzVerMax) {indiceSchutzVerMax = indiceSchutzVer;} double angleNeighb = 0; if (neighbApex->_h > baseApex->_diameter) {angleNeighb = (180.0 / M_PI) * std::atan(deltaH / dist2D);} if (angleNeighb > angleNeighbMax && dist2D < 1.2*sommeRadius) {angleNeighbMax = angleNeighb;} } } CT_AttributesList* attList = new CT_AttributesList(_itemAtt_ModelName.completeName(), res); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzTotal_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzTotal)); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzHorTotal_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzHorTotal)); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzVerTotal_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzVerTotal)); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzMax_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzMax)); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzHorMax_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzHorMax)); attList->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzVerMax_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzVerMax)); attList->addItemAttribute(new CT_StdItemAttributeT(_angleNeighbMax_ModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, angleNeighbMax)); baseApex->_group->addItemDrawable(attList); if (_outItem && baseApex->_outItem != NULL) { CT_Scene* sc = dynamic_cast(baseApex->_outItem); if (sc != NULL) { CT_PointCloudIndexVector *resPointCloudIndex = new CT_PointCloudIndexVector(); resPointCloudIndex->setSortType(CT_PointCloudIndexVector::NotSorted); const CT_AbstractPointCloudIndex* incloud = sc->getPointCloudIndex(); for (int i = 0 ; i < incloud->size() ; i++) { resPointCloudIndex->addIndex(incloud->indexAt(i)); } resPointCloudIndex->setSortType(CT_PointCloudIndexVector::SortedInAscendingOrder); CT_Scene *outScene = new CT_Scene(_outScene_ModelName.completeName(), res, PS_REPOSITORY->registerPointCloudIndex(resPointCloudIndex)); outScene->updateBoundingBox(); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzTotal_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzTotal)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzHorTotal_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzHorTotal)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzVerTotal_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzVerTotal)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzVerTotalINT_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, 100*indiceSchutzVerTotal)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzMax_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzMax)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzHorMax_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzHorMax)); outScene->addItemAttribute(new CT_StdItemAttributeT(_indiceSchutzVerMax_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, indiceSchutzVerMax)); outScene->addItemAttribute(new CT_StdItemAttributeT(_angleNeighbMax_OutModelName.completeName(), CT_AbstractCategory::DATA_VALUE, res, angleNeighbMax)); baseApex->_group->addItemDrawable(outScene); } } } delete delaunay; setProgress(100); }