#include "onf_stepcomputedominanceindicators.h" #include "ct_math/delaunay2d/ct_delaunaytriangulation.h" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" ONF_StepComputeDominanceIndicators::ONF_StepComputeDominanceIndicators() : SuperClass() { } QString ONF_StepComputeDominanceIndicators::description() const { return tr("Calcul de l'indice de compétition de Schutz 1989"); } QString ONF_StepComputeDominanceIndicators::detailledDescription() const { return tr("Nécessite en entrée des items représentant des apex, avec les attributs (X, Y, Z, DiamètreHouppier)."); } QString ONF_StepComputeDominanceIndicators::inputDescription() const { return SuperClass::inputDescription() + tr("

"); } QString ONF_StepComputeDominanceIndicators::outputDescription() const { return SuperClass::outputDescription() + tr("

"); } QString ONF_StepComputeDominanceIndicators::detailsDescription() const { return tr(""); } QString ONF_StepComputeDominanceIndicators::URL() const { //return tr("STEP URL HERE"); return SuperClass::URL(); //by default URL of the plugin } CT_VirtualAbstractStep* ONF_StepComputeDominanceIndicators::createNewInstance() const { return new ONF_StepComputeDominanceIndicators(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepComputeDominanceIndicators::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Items (apex)")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inApexItem, tr("Item (apex)")); manager.addItemAttribute(_inApexItem, _inAttXApex, CT_AbstractCategory::DATA_VALUE, tr("X_Apex")); manager.addItemAttribute(_inApexItem, _inAttYApex, CT_AbstractCategory::DATA_VALUE, tr("Y_Apex")); manager.addItemAttribute(_inApexItem, _inAttZApex, CT_AbstractCategory::DATA_VALUE, tr("Z_Apex")); manager.addItemAttribute(_inApexItem, _inAttDiameter, CT_AbstractCategory::DATA_VALUE, tr("Diametre_Houppier")); manager.addResult(_inResultDTM, tr("MNT"), "", true); manager.setZeroOrMoreRootGroup(_inResultDTM, _inZeroOrMoreRootGroupDTM); manager.addGroup(_inZeroOrMoreRootGroupDTM, _inGroupDTM); manager.addItem(_inGroupDTM, _inDTM, tr("MNT")); } void ONF_StepComputeDominanceIndicators::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _outitemAtt, tr("indiceSchutz")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzTotal, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzTotal")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzHorTotal, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorTotal")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzVerTotal, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerTotal")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzMax, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzMax")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzHorMax, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzHorMax")); manager.addItemAttribute(_outitemAtt, _outIndiceSchutzVerMax, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("indiceSchutzVerMax")); manager.addItemAttribute(_outitemAtt, _outAngleNeighbMax, PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), tr("angleNeighbMax")); } void ONF_StepComputeDominanceIndicators::compute() { const CT_Image2D* mnt = nullptr; for (const CT_Image2D* imageIn : _inDTM.iterateInputs(_inResultDTM)) { mnt = imageIn; } 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; for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { for (const CT_AbstractSingularItemDrawable* apexItem : group->singularItems(_inApexItem)) { if (isStopped()) {return;} const CT_AbstractItemAttribute *attXApex = apexItem->itemAttribute(_inAttXApex); const CT_AbstractItemAttribute *attYApex = apexItem->itemAttribute(_inAttYApex); const CT_AbstractItemAttribute *attZApex = apexItem->itemAttribute(_inAttZApex); const CT_AbstractItemAttribute *attDiameter = apexItem->itemAttribute(_inAttDiameter); if (attXApex != nullptr && attYApex != nullptr && attZApex != nullptr && attDiameter != nullptr) { 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 != nullptr && mnt->indexAtCoords(valX, valY, index)) { float zval = mnt->valueAtIndex(index); if (!qFuzzyCompare(zval, mnt->NA())) { valH -= double(zval); } } apexList.append(new Apex(valX, valY, valZ, valH, valDiameter, group)); } } } } 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 != nullptr) { 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_ItemAttributeList* attList = new CT_ItemAttributeList(); baseApex->_group->addSingularItem(_outitemAtt, attList); attList->addItemAttribute(_outIndiceSchutzTotal, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzTotal)); attList->addItemAttribute(_outIndiceSchutzHorTotal, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzHorTotal)); attList->addItemAttribute(_outIndiceSchutzVerTotal, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzVerTotal)); attList->addItemAttribute(_outIndiceSchutzMax, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzMax)); attList->addItemAttribute(_outIndiceSchutzHorMax, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzHorMax)); attList->addItemAttribute(_outIndiceSchutzVerMax, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), indiceSchutzVerMax)); attList->addItemAttribute(_outAngleNeighbMax, new CT_StdItemAttributeT(PS_CATEGORY_MANAGER->findByUniqueName(CT_AbstractCategory::DATA_VALUE), angleNeighbMax)); } delete delaunay; setProgress(100.0f); }