#include "lvox3_stepgridnormalisation.h" //In/Out dependencies #include "ct_result/model/inModel/ct_inresultmodelgrouptocopy.h" #include "ct_result/model/outModel/tools/ct_outresultmodelgrouptocopypossibilities.h" #include "ct_result/ct_resultgroup.h" //Tools dependencies #include "ct_view/ct_stepconfigurabledialog.h" #include "tools/lvox3_gridtype.h" //Source models(result where the grid will go) #define DEF_SearchInSourceResult "rs" #define DEF_SearchInSourceGroup "gs" #define DEF_SearchInSourceItem "its" //Target models(result of the grid) #define DEF_SearchInTargetResult "rt" #define DEF_SearchInTargetGroup "gt" #define DEF_SearchInGrid "grid" #define DEF_SearchInRoster "ros" #define DEF_SearchInDTMGridResult "dr" #define DEF_SearchInDTMGridGroup "dg" #define DEF_SearchInDTMGrid "gdt" LVOX3_StepGridNormalisation::LVOX3_StepGridNormalisation(CT_StepInitializeData &dataInit) : CT_AbstractStep(dataInit) { } QString LVOX3_StepGridNormalisation::getStepDescription() const { return tr("Normalisation des hauteur d'une grille (en developpement)"); } // Step detailed description QString LVOX3_StepGridNormalisation::getStepDetailledDescription() const { return tr("Cette étape permet diminuer la hauteur des voxel d'une grille selon un roster de hauteur. " "À noter que les paramètres devraient être les mêmes pour la grille 3D importée et les grilles 3D calculées présentement pour empêcher des résultats incohérents. (résolution de grille et dimension)"); } CT_VirtualAbstractStep* LVOX3_StepGridNormalisation::createNewInstance(CT_StepInitializeData &dataInit) { // Creates an instance of this step return new LVOX3_StepGridNormalisation(dataInit); } void LVOX3_StepGridNormalisation::createPreConfigurationDialog() { } void LVOX3_StepGridNormalisation::createInResultModelListProtected() { CT_InResultModelGroupToCopy *resultModel = createNewInResultModelForCopy(DEF_SearchInTargetResult, tr("Grids"), "", true); resultModel->setZeroOrMoreRootGroup(); resultModel->addGroupModel("", DEF_SearchInTargetGroup, CT_AbstractItemGroup::staticGetType(), tr("Group")); resultModel->addItemModel(DEF_SearchInTargetGroup, DEF_SearchInGrid, LVOX3_AbstractGrid3D::staticGetType(), tr("Grid to Reduce")); //resultModel->addItemModel(DEF_SearchInTargetGroup,DEF_SearchInRoster, CT_Image2D(),tr("Roster des hauteurs")); //TODO Ajuster le CT_image2D comme itemAttendu, un cas trouble de groupe devrait apparaitre //DTM CT_InResultModelGroupToCopy *resultRefGrid = createNewInResultModelForCopy(DEF_SearchInDTMGridResult, tr("Grille de modèle numérique de terrain (.GRD3DLVOX)"), "", true); resultRefGrid->setZeroOrMoreRootGroup(); resultRefGrid->addGroupModel("", DEF_SearchInDTMGridGroup, CT_AbstractItemGroup::staticGetType(), tr("Groupe de dtm"), ""); resultRefGrid->addItemModel(DEF_SearchInDTMGridGroup, DEF_SearchInDTMGrid, LVOX3_AbstractGrid3D::staticGetType(), tr("Grille de modèle numérique de terrain"), ""); } void LVOX3_StepGridNormalisation::createPostConfigurationDialog() { } void LVOX3_StepGridNormalisation::createOutResultModelListProtected() { CT_OutResultModelGroupToCopyPossibilities *resultModel = createNewOutResultModelToCopy(DEF_SearchInTargetResult); if(resultModel != NULL) { resultModel->addItemModel(DEF_SearchInTargetGroup, _NORM_ModelName, new lvox::Grid3Df(), tr("Flatted Grid")); //debug resultModel->addItemModel(DEF_SearchInTargetGroup, _ELevation_ModelName, new lvox::Grid3Df(), tr("Elevation Grid")); } } void LVOX3_StepGridNormalisation::compute() { //QList outResult = CT_ResultGroup* resultOutGrids = getOutResultList().first(); CT_ResultGroupIterator itGrp(resultOutGrids, this, DEF_SearchInTargetGroup); CT_ResultGroup* dtmResult = getInputResults().at(1); CT_ResultGroupIterator itDtmGrp(dtmResult, this, DEF_SearchInDTMGridGroup); while(itGrp.hasNext() && itDtmGrp.hasNext() && !isStopped()) { /* * Two casts are required, the group iterator returns const objects and * because addItemDrawable() is called, it has to be non const. */ CT_StandardItemGroup *group = dynamic_cast((CT_AbstractItemGroup*)itGrp.next()); lvox::Grid3Df* inGrid = dynamic_cast (group->firstItemByINModelName(this, DEF_SearchInGrid)); CT_StandardItemGroup *dtmGroup = dynamic_cast((CT_AbstractItemGroup*)itDtmGrp.next()); LVOX3_AbstractGrid3D* dtmGrid = (LVOX3_AbstractGrid3D*) dtmGroup->firstItemByINModelName(this, DEF_SearchInDTMGrid); //CT_Image2D* MNT = (CT_Image2D*) group->firstItemByINModelName(this, DEF_SearchInRoster); float xres = inGrid->xresolution(); float yres = inGrid->yresolution(); float zres = inGrid->zresolution(); float NAd = 0; size_t xdim = inGrid->xdim(); size_t ydim = inGrid->ydim(); size_t zdim = inGrid->zdim(); lvox::Grid3Df* itemoutiConteur = (lvox::Grid3Df*) inGrid->copy(_NORM_ModelName.completeName(), resultOutGrids, CT_ResultCopyModeList()); lvox::Grid3Df* elevationGrid = new lvox::Grid3Df(_ELevation_ModelName.completeName(), resultOutGrids, inGrid->minX(), inGrid->minY(), inGrid->minZ(), xdim, ydim, zdim, xres, yres, zres, NAd, NAd); group->addItemDrawable(itemoutiConteur); group->addItemDrawable(elevationGrid); //all voxel in dtm have the same z coordinate !!! double coordZ = dtmGrid->valueAtIndexAsDouble(0); 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); size_t dtmIndex; dtmGrid->indexAtXYZ(coordX, coordY, coordZ, dtmIndex); double dtmZ = dtmGrid->valueAtIndexAsDouble(dtmIndex); // 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; //isNotEmptyColumns[xx*ydim + yy] = 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); size_t dtmIndex; dtmGrid->indexAtXYZ(coordX, coordY, coordZ, dtmIndex); double dtmZ = dtmGrid->valueAtIndexAsDouble(dtmIndex); 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 = 0; zz < diff; zz++) { if( zz + beginZlevel < zdim){ elevationGrid->setValue(xx, yy, zz + beginZlevel, 1); } } 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( zdim - zz >= diff){ itemoutiConteur->setValue(xx, yy, zz, -1); } } } } } itemoutiConteur->computeMinMax(); elevationGrid->computeMinMax(); } }