/**************************************************************************** Copyright (C) 2010-2012 the Office National des Forêts (ONF), France All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Alexandre PIBOULE (ONF) This file is part of PluginONF library. PluginONF is free library: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PluginONF is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PluginONF. If not, see . *****************************************************************************/ #include "onf_metricnapexmean.h" #include "ct_pointcloudindex/ct_pointcloudindexvector.h" #include "ct_iterator/ct_pointiterator.h" #include "ct_math/ct_mathstatistics.h" #include "ct_view/ct_genericconfigurablewidget.h" #define checkAndSetValue(ATT, NAME, TYPE) if((value = group->firstValueByTagName(NAME)) == nullptr) { return false; } else { ATT = value->value().value(); } ONF_MetricNApexMean::ONF_MetricNApexMean(QString pluginName) : CT_AbstractMetric_XYZ(pluginName) { _nApex = 6; _percHmax = 0.70; declareAttributesVaB(); } ONF_MetricNApexMean::ONF_MetricNApexMean(const ONF_MetricNApexMean &other) : CT_AbstractMetric_XYZ(other) { declareAttributesVaB(); _nApex = other._nApex; _percHmax = other._percHmax; } QString ONF_MetricNApexMean::getShortDisplayableName() const { return tr("Moyenne des N plus hauts points (Ht)"); } QString ONF_MetricNApexMean::getShortDescription() const { return tr("Calcul de la moyenne des n plus hauts points. Parmi les points disponibles, dont la hauteur est supérieure au seuil spécifié (en pourcentage de la hauteur maximale), les n plus gros sont utilisés." "S'il y a assez de points de hauteur supérieure au seuil, n = N (paramètre Nombre de points à moyenner). Sinon n est égal au nombre de points de hauteur supérieure au seuil.

" "Une utilisation de cette métrique est de l'appliquer à un nuage de points correspondant à des apex d'arbres détéctés, pour calculer par exemple une hauteur dominante (hauteur moyenne des n plus gros arbres à l'hectare)"); } QString ONF_MetricNApexMean::getDetailledDescription() const { return tr("Les indicateurs suivants peuvent être calculés :" ""); } void ONF_MetricNApexMean::saveSettings(SettingsWriterInterface& writer) const { writer.addParameter(this, "nApex", _nApex); writer.addParameter(this, "percHmax", _percHmax); SuperClass::saveSettings(writer); } bool ONF_MetricNApexMean::restoreSettings(SettingsReaderInterface& reader) { QVariant value; if(reader.parameter(this, "nApex", value, 0)) _nApex = value.toInt(); if(reader.parameter(this, "percHmax", value, 0)) _percHmax = value.toDouble(); return SuperClass::restoreSettings(reader); } CT_AbstractConfigurableWidget* ONF_MetricNApexMean::createConfigurationWidget() { CT_GenericConfigurableWidget* configDialog = new CT_GenericConfigurableWidget(); configDialog->addInt(tr("Nombre de points à moyenner (N)"), "", 0, 10000, _nApex); configDialog->addDouble(tr("%Hmax en dessous duquel les apex ne sont plus pris en compte"), "%", 0, 100, 1, _percHmax, 100); return configDialog; } void ONF_MetricNApexMean::createAttributes() { CT_AbstractMetric_XYZ::createAttributes(); } void ONF_MetricNApexMean::computeMetric() { _nApexUsed.value = 0; _hmean.value = 0; _hmax.value = 0; _hThreshold.value = 0; QList values; size_t i = 0; CT_PointIterator itP(pointCloud()); while(itP.hasNext()) { const CT_Point& point = itP.next().currentPoint(); if ((plotArea() == nullptr) || plotArea()->contains(point(0), point(1))) { values.append(point(2)); ++i; } } if (i > 0) { std::sort(values.begin(), values.end()); double limit = values.last() * _percHmax; _hmax.value = values.last(); _hThreshold.value = limit; for (int a = 0 ; a < _nApex && a < values.size(); a++) { double val = values.at(values.size() - a - 1); if (val >= limit) { _nApexUsed.value++; _hmean.value += val; } } if (_nApexUsed.value > 0) { _hmean.value /= _nApexUsed.value; } setAttributeValueVaB(_hmean); setAttributeValueVaB(_nApexUsed); setAttributeValueVaB(_hmax); setAttributeValueVaB(_hThreshold); } } CT_AbstractConfigurableElement* ONF_MetricNApexMean::copy() const { return new ONF_MetricNApexMean(*this); } void ONF_MetricNApexMean::declareAttributesVaB() { registerAttributeVaB(_hmean, CT_AbstractCategory::DATA_NUMBER, "Apex_Hmean"); registerAttributeVaB(_nApexUsed, CT_AbstractCategory::DATA_NUMBER, "Apex_n"); registerAttributeVaB(_hmax, CT_AbstractCategory::DATA_NUMBER, "Apex_Hmax"); registerAttributeVaB(_hThreshold, CT_AbstractCategory::DATA_NUMBER, "Apex_Hthr"); }