#include "lvox3_stepgridnormalisationraster.h" #include "ct_log/ct_logmanager.h" LVOX3_StepGridNormalisationRaster::LVOX3_StepGridNormalisationRaster() : CT_AbstractStep() { } QString LVOX3_StepGridNormalisationRaster::description() const { return tr("Height normalization with DTM (WIP)"); } // Step detailed description QString LVOX3_StepGridNormalisationRaster::detailledDescription() const { return tr("This step allows for reducing the voxels' height with respect to a DTM." "
" "Note : Both grids (imported and computed here) should have their parameters equal (namely dimension and resolution) to avoid incoherent results."); } CT_VirtualAbstractStep* LVOX3_StepGridNormalisationRaster::createNewInstance() const { // Creates an instance of this step return new LVOX3_StepGridNormalisationRaster(); } QString LVOX3_StepGridNormalisationRaster::outputDescription() const { auto indent = [](QString s) -> QString { return "
" + s+ "
"; }; return CT_AbstractStep::outputDescription() + "
Group [Group]:" + indent("...") + indent("LVOX3_Grid3D [Normalized grid]"); } void LVOX3_StepGridNormalisationRaster::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, "Grids", "", true); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inGrid, "Input grid"); manager.addResult(_inResultDTM, "DTM", "", true); manager.setZeroOrMoreRootGroup(_inResultDTM, _inZeroOrMoreRootGroupDTM); manager.addGroup(_inZeroOrMoreRootGroupDTM, _inGroupDTM); manager.addItem(_inGroupDTM, _inDTM, "DTM"); } void LVOX3_StepGridNormalisationRaster::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); manager.addItem(_inGroup, _NORM, "Normalized grid"); } void LVOX3_StepGridNormalisationRaster::compute() { QList*> dtms; for (const CT_StandardItemGroup* groupDTM : _inGroupDTM.iterateInputs(_inResultDTM)) { dtms.append(groupDTM->singularItem(_inDTM)); } int counter = 0; for (CT_StandardItemGroup* group : _inGroup.iterateOutputs(_inResult)) { if (isStopped()) {return;} const LVOX3_AbstractGrid3D* inGrid = group->singularItem(_inGrid); if (inGrid != nullptr) { const CT_Image2D* dtm = dtms.at(counter++); float xres = inGrid->xresolution(); float yres = inGrid->yresolution(); float zres = inGrid->zresolution(); size_t xdim = inGrid->xdim(); size_t ydim = inGrid->ydim(); size_t zdim = inGrid->zdim(); float NAin = inGrid->NAAsString().toFloat(); lvox::Grid3Df* itemoutiConteur = new lvox::Grid3Df(inGrid->minX(), inGrid->minY(), inGrid->minZ(), xdim, ydim, zdim, xres, yres, zres, NAin, NAin); group->addSingularItem(_NORM, itemoutiConteur); //all voxel in dtm have the same z coordinate !!! double minZ = inGrid->minZ(); double minDtmZ = std::numeric_limits::max(); //std::vector isNotEmptyColumns(xdim*ydim, false); for(size_t xx = 0; xx < xdim; xx++) { for(size_t yy = 0; yy < ydim; yy++) { //nombre de voxels //int nbValeur = div(MNT->valueAtCoords(xx,yy),zres).quot; //find first non null double coordX = inGrid->getCellCenterX(xx); double coordY = inGrid->getCellCenterY(yy); float dtmZ = dtm->valueAtCoords(coordX, coordY); // size_t minZIndex = 0; // inGrid->index(xx, yy, 0, minZIndex); //double minZ = inGrid->valueAtIndexAsDouble(minZIndex); //compute the number of voxel must be descended bool isNotEmptyColumn = false; for(size_t zz = 0; zz < zdim; zz++) { size_t index = 0; inGrid->index(xx, yy, zz, index); if (inGrid->valueAtIndexAsDouble(index) >= 0){ isNotEmptyColumn = true; break; } } int diff = (dtmZ - minZ)/zres; if(diff > 0 && isNotEmptyColumn){ if( dtmZ < minDtmZ ){ minDtmZ = dtmZ; } } } } //correction of height for(size_t xx = 0; xx < xdim; xx++) { for(size_t yy = 0; yy < ydim; yy++) { double coordX = inGrid->getCellCenterX(xx); double coordY = inGrid->getCellCenterY(yy); float dtmZ = dtm->valueAtCoords(coordX, coordY); size_t minZIndex = 0; inGrid->index(xx, yy, 0, minZIndex); //double minZ = inGrid->valueAtIndexAsDouble(minZIndex); //compute the number of voxel must be descended int beginZlevel = (minDtmZ - minZ)/zres; int diff = (dtmZ - minDtmZ)/zres; //qDebug()<<"###diff"<< diff<< "minZ" << minZ << "dtmZ"<< dtmZ << "minDtm" << minDtmZ; if(diff > 0){ for(size_t zz = beginZlevel + diff; zz < zdim; zz++) { size_t index = 0; inGrid->index(xx, yy, zz, index); float currentValue = inGrid->valueAtIndexAsDouble(index); itemoutiConteur->setValue(xx, yy, zz - diff, currentValue); if( static_cast(zdim - zz) >= diff){ itemoutiConteur->setValue(xx, yy, zz, -1); } } } } } itemoutiConteur->computeMinMax(); } else { PS_LOG->addWarningMessage(LogInterface::step, tr("Erreur : Grille Nulle")); } } }