/**************************************************************************** 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_metricladbouvieretal2015.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_MetricLADBouvierEtAl2015::ONF_MetricLADBouvierEtAl2015(QString pluginName) : CT_AbstractMetric_XYZ(pluginName) { _hmax = 60.0; _dz = 1.0; _k = 0.5; } ONF_MetricLADBouvierEtAl2015::ONF_MetricLADBouvierEtAl2015(const ONF_MetricLADBouvierEtAl2015 &other) : CT_AbstractMetric_XYZ(other) { _hmax = other._hmax; _dz = other._dz; _k = other._k; } QString ONF_MetricLADBouvierEtAl2015::getShortDisplayableName() const { return tr("Calcul du LAD par tranche (Ht), paramétrable"); } QString ONF_MetricLADBouvierEtAl2015::getShortDescription() const { return tr("Calcul du LAD par tranche de hauteurs." "Les indicateurs suivants peuvent être calculés :" ""); } QString ONF_MetricLADBouvierEtAl2015::getDetailledDescription() const { return tr("Fournit des résultats identiques à la fonction LAD du package LidR de R (metrics_stdmetrics.R).
" "

Référence : Bouvier, M., Durrieu, S., Fournier, R. a, & Renaud, J. (2015). Generalizing predictive " "models of forest inventory attributes using an area-based approach with airborne las data. Remote " "Sensing of Environment, 156, 322-334. http://doi.org/10.1016/j.rse.2014.10.004

"); } void ONF_MetricLADBouvierEtAl2015::saveSettings(SettingsWriterInterface& writer) const { writer.addParameter(this, "hmax", _hmax); writer.addParameter(this, "dz", _dz); writer.addParameter(this, "k", _k); SuperClass::saveSettings(writer); } bool ONF_MetricLADBouvierEtAl2015::restoreSettings(SettingsReaderInterface& reader) { QVariant value; if(reader.parameter(this, "hmax", value, 0)) _hmax = value.toDouble(); if(reader.parameter(this, "dz", value, 0)) _dz = value.toDouble(); if(reader.parameter(this, "k", value, 0)) _k = value.toDouble(); return SuperClass::restoreSettings(reader); } CT_AbstractConfigurableWidget* ONF_MetricLADBouvierEtAl2015::createConfigurationWidget() { CT_GenericConfigurableWidget* configDialog = new CT_GenericConfigurableWidget(); configDialog->addTitle(tr("Paramétrage :")); configDialog->addDouble(tr("Hauteur de fin"), "m", 0, 999, 2, _hmax); configDialog->addDouble(tr("Epaisseur des tranches"), "m", 0.01, 9999, 2, _dz); configDialog->addDouble(tr("Coefficient d'extinction"), "", 0.01, 1, 2, _k); return configDialog; } void ONF_MetricLADBouvierEtAl2015::createAttributes() { int nb = _hmax / _dz; if ((double(nb)*_dz) < _hmax) {nb++;} _lad.resize(nb+1); std::fill(_lad.begin(), _lad.end(), 0); for (int i = 0 ; i < nb - 1 ; i++) { addAttribute(_lad[i+2], CT_AbstractCategory::DATA_NUMBER, getSliceString(double(i+1)*_dz)); } CT_AbstractMetric_XYZ::createAttributes(); } void ONF_MetricLADBouvierEtAl2015::computeMetric() { QList values; 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)); } } if(values.size() > 0) { std::sort(values.begin(), values.end()); std::fill(_lad.begin(), _lad.end(), 0); for (int i = 0 ; i < values.size() ; i++) { int j = int(std::ceil(values.at(i) / _dz)); if (j < 0) {j = 0;} _lad[j]++; } double nFromBase = 0; for (int i = 0 ; i < _lad.size() ; i++) { double nz = _lad[i]; if ((nFromBase + nz) > 0) { double gf = nFromBase / (nFromBase + nz); if (gf > 0 && nz > 0) { _lad[i] = -log(gf) / (_k*_dz); } else { _lad[i] = 0; } } if (i > 1) { setAttributeValue(_lad[i]); } nFromBase += nz; } } else { std::fill(_lad.begin(), _lad.end(), 0); for (int i = 0 ; i < _lad.size(); i++) { if (i > 1) { setAttributeValue(_lad[i]); } } } } CT_AbstractConfigurableElement* ONF_MetricLADBouvierEtAl2015::copy() const { return new ONF_MetricLADBouvierEtAl2015(*this); } QString ONF_MetricLADBouvierEtAl2015::getSliceString(double h) { QString number = QString::number(100*(h+_dz/2.0), 'f', 0); if (_hmax >= 0.1 && number.size() < 2) {number.prepend("0");} if (_hmax >= 1.0 && number.size() < 3) {number.prepend("0");} if (_hmax >= 10.0 && number.size() < 4) {number.prepend("0");} if (_hmax >= 100.0 && number.size() < 5) {number.prepend("0");} return QString("LAD_%2").arg(number); }