#include "onf_stepcomputepointheightfromtin.h" ONF_StepComputePointHeightFromTIN::ONF_StepComputePointHeightFromTIN() : SuperClass() { _ptsAttribute = false; _ptsCloud = true; _addLAS = false; } QString ONF_StepComputePointHeightFromTIN::description() const { return tr("Calculer la hauteur des points à l'aide d'un TIN"); } QString ONF_StepComputePointHeightFromTIN::detailledDescription() const { return tr("Cette étape soustrait à l'altitude des points la coordonnée du TIN." "En sortie, elle peut (options) générer :
" "- Un attribut de hauteur sur le nuage d'altitudes
" "- Un nuage de point
" "- Recopier les attributs LAS (dans le cas de la création d'un nouveau nuage)"); } QString ONF_StepComputePointHeightFromTIN::inputDescription() const { return SuperClass::inputDescription() + tr("

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

"); } QString ONF_StepComputePointHeightFromTIN::detailsDescription() const { return tr(""); } CT_VirtualAbstractStep* ONF_StepComputePointHeightFromTIN::createNewInstance() const { return new ONF_StepComputePointHeightFromTIN(); } //////////////////// PROTECTED METHODS ////////////////// void ONF_StepComputePointHeightFromTIN::declareInputModels(CT_StepInModelStructureManager& manager) { manager.addResult(_inResult, tr("Scene(s)")); manager.setZeroOrMoreRootGroup(_inResult, _inZeroOrMoreRootGroup); manager.addGroup(_inZeroOrMoreRootGroup, _inGroup); manager.addItem(_inGroup, _inScene, tr("Scene(s)")); if (_addLAS) manager.addItem(_inGroup, _inLAS, tr("Attributs LAS")); manager.addResult(_inResultTIN, tr("TIN"), "", true); manager.setZeroOrMoreRootGroup(_inResultTIN, _inZeroOrMoreRootGroupTIN); manager.addGroup(_inZeroOrMoreRootGroupTIN, _inGroupTIN); manager.addItem(_inGroupTIN, _inTIN, tr("TIN")); } void ONF_StepComputePointHeightFromTIN::declareOutputModels(CT_StepOutModelStructureManager& manager) { manager.addResultCopy(_inResult); if (_ptsAttribute) manager.addPointAttribute(_inGroup, _outHeightAtt, tr("Attribut Hauteur")); if (_ptsCloud) manager.addItem(_inGroup, _outScene, tr("Scene H")); } void ONF_StepComputePointHeightFromTIN::fillPreInputConfigurationDialog(CT_StepConfigurableDialog* preInputConfigDialog) { preInputConfigDialog->addBool(tr("Créer des attributs de points hauteur"), "", "", _ptsAttribute); preInputConfigDialog->addEmpty(); preInputConfigDialog->addBool(tr("Créer un nuage de points hauteur"), "", "", _ptsCloud); preInputConfigDialog->addBool(tr("Transférer les attributs las au nuage de points hauteur"), "", "", _addLAS); } void ONF_StepComputePointHeightFromTIN::compute() { const CT_Triangulation2D* tin = _inTIN.firstInput(_inResultTIN); if ((tin == nullptr) || (!_ptsAttribute && !_ptsCloud)) return; auto iterator = _inScene.iterateOutputs(_inResult); auto it = iterator.begin(); auto end = iterator.end(); while(it != end) { const CT_AbstractItemDrawableWithPointCloud* inputScene = *it; CT_StandardItemGroup* grp = it.currentParent(); if (isStopped()) return; const CT_AbstractPointCloudIndex *inputPointCloudIndex = inputScene->pointCloudIndex(); const size_t n_points = inputPointCloudIndex->size(); CT_PointIterator itP(inputPointCloudIndex); CT_NMPCIR outputHeightCloud; if (_ptsCloud) {outputHeightCloud = PS_REPOSITORY->createNewPointCloud(n_points);} CT_MutablePointIterator itPM(outputHeightCloud); // On declare un tableau d'attributs double que l'on va remplir avec les coordonnées correspondant a l'axe demandé HeightAttManager::SetterPtr attributeSetter = nullptr; if (_ptsAttribute) {attributeSetter = _outHeightAtt.createAttributesSetterPtr(outputHeightCloud);} float minAttribute = std::numeric_limits::max(); float maxAttribute = -std::numeric_limits::max(); size_t i = 0; CT_DelaunayTriangulation *triangulation = tin->getDelaunayT(); double zTin = 0; CT_DelaunayTriangle* refTri = nullptr; // On applique la translation a tous les points du nuage while (itP.hasNext() && !isStopped()) { CT_Point point = itP.next().currentPoint(); refTri = const_cast(triangulation->getZCoordForXY(point(0), point(1), zTin, refTri)); float h = float(point(2)); if (!std::isnan(zTin)) { h -= float(zTin); } else { h = 0; } if (_ptsAttribute) { attributeSetter->setValueWithGlobalIndex(itP.currentGlobalIndex(), h); if (h < minAttribute) {minAttribute = h;} if (h > maxAttribute) {maxAttribute = h;} } if (_ptsCloud) { point.setZ(double(h)); itPM.next().replaceCurrentPoint(point); } setProgress(float(100.0*i++ / n_points)); } if (i > 0) { if (_ptsAttribute) { CT_PointsAttributesScalarTemplated* outAttribute = _outHeightAtt.createAttributeInstance(inputScene->pointCloudIndexRegistered(), minAttribute, maxAttribute); grp->addSingularItem(_outHeightAtt, outAttribute); } if (_ptsCloud) { CT_Scene* outputHeightScene = new CT_Scene(outputHeightCloud); outputHeightScene->updateBoundingBox(); grp->addSingularItem(_outScene, outputHeightScene); // Copie des attributs LAS pour les lier au nuage de point d'hauteur if (_addLAS) { const CT_StdLASPointsAttributesContainer* attributeLAS = grp->singularItem(_inLAS); if (attributeLAS != nullptr) { // Retrieve attributes QHashIterator itLAS(attributeLAS->lasPointsAttributes()); while(itLAS.hasNext()) { CT_AbstractPointAttributesScalar* v = itLAS.next().value(); if(v != nullptr) v->copyAttributesOfSForD(inputScene->pointCloudIndexRegistered(), outputHeightScene->pointCloudIndexRegistered()); } } } } } ++it; } }