22#include <QJsonDocument>
35 const double delta1 = newMean -
mean;
37 const double delta2 = newMean - stats.
mean;
38 const double variance2 = stats.
stDev * stats.
stDev * ( stats.
count - 1 ) + stats.
count * delta2 * delta2;
39 const double variance = ( variance1 + variance2 ) / (
count + stats.
count );
40 stDev = std::sqrt( variance );
64 : mSampledPointsCount( sampledPointsCount ), mStatisticsMap( stats )
71 mStatisticsMap.clear();
78 mStatisticsMap.remove( attribute.name() );
85 defaultVal.
minimum = std::numeric_limits<double>::max();
86 defaultVal.
maximum = std::numeric_limits<double>::lowest();
88 return mStatisticsMap.value( attribute, defaultVal );
93 if ( !mStatisticsMap.contains( attribute ) )
101 if ( !mStatisticsMap.contains( attribute ) )
102 return QMap<int, int>();
103 return mStatisticsMap[ attribute ].classCount;
108 if ( !mStatisticsMap.contains( attribute ) )
109 return std::numeric_limits<double>::quiet_NaN();
110 return mStatisticsMap[ attribute ].minimum;
115 if ( !mStatisticsMap.contains( attribute ) )
116 return std::numeric_limits<double>::quiet_NaN();
117 return mStatisticsMap[ attribute ].maximum;
122 if ( !mStatisticsMap.contains( attribute ) )
123 return std::numeric_limits<double>::quiet_NaN();
124 return mStatisticsMap[ attribute ].mean;
129 if ( !mStatisticsMap.contains( attribute ) )
130 return std::numeric_limits<double>::quiet_NaN();
131 return mStatisticsMap[ attribute ].stDev;
137 for (
auto it = stats.mStatisticsMap.constBegin(); it != stats.mStatisticsMap.constEnd(); it++ )
139 const QString attribute = it.key();
141 if ( mStatisticsMap.contains( attribute ) )
145 mStatisticsMap[ attribute ] = s;
147 mSampledPointsCount += stats.mSampledPointsCount;
153 obj.insert( QStringLiteral(
"sampled-points" ), QJsonValue::fromVariant(
sampledPointsCount() ) );
155 for (
auto it = mStatisticsMap.constBegin(); it != mStatisticsMap.constEnd(); it++ )
158 stats.insert( it.key(), attributeStatisticsToJson( stat ) );
160 obj.insert( QStringLiteral(
"stats" ), stats );
162 QJsonDocument statsDoc( obj );
163 return statsDoc.toJson( QJsonDocument::Compact );
168 QJsonParseError error;
169 QJsonDocument document = QJsonDocument::fromJson( statsByteArray, &error );
170 if ( error.error != QJsonParseError::NoError )
172 QgsMessageLog::logMessage( QObject::tr(
"Failed to load statistics JSON from COPC file, reason: %1" ).arg( error.errorString() ) );
176 QJsonObject statsJson = document.object();
179 stats.mSampledPointsCount = statsJson.value( QStringLiteral(
"sampled-points" ) ).toInt();
180 if ( statsJson.contains( QStringLiteral(
"stats" ) ) )
182 QJsonObject statsObj = statsJson.value( QStringLiteral(
"stats" ) ).toObject();
183 for (
const QString &attr : statsObj.keys() )
185 QJsonObject obj = statsObj.value( attr ).toObject();
187 attrStats.
count = stats.mSampledPointsCount;
188 stats.mStatisticsMap.insert( attr, attrStats );
197 obj.insert( QStringLiteral(
"minimum" ), stats.
minimum );
198 obj.insert( QStringLiteral(
"maximum" ), stats.
maximum );
199 obj.insert( QStringLiteral(
"mean" ), stats.
mean );
200 if ( !std::isnan( stats.
stDev ) )
202 obj.insert( QStringLiteral(
"standard-deviation" ), stats.
stDev );
204 QJsonObject classCount;
207 classCount.insert( QString::number( it.key() ), it.value() );
209 obj.insert( QStringLiteral(
"class-count" ), classCount );
216 QVariantMap m = statsJson.toVariantMap();
217 statsObj.
minimum = m.value( QStringLiteral(
"minimum" ), std::numeric_limits<double>::max() ).toDouble();
218 statsObj.
maximum = m.value( QStringLiteral(
"maximum" ), std::numeric_limits<double>::lowest() ).toDouble();
219 statsObj.
mean = m.value( QStringLiteral(
"mean" ), 0 ).toDouble();
220 statsObj.
stDev = m.value( QStringLiteral(
"standard-deviation" ), std::numeric_limits<double>::quiet_NaN() ).toDouble();
221 QJsonObject classCountJson = statsJson.value( QStringLiteral(
"class-count" ) ).toObject();
222 for (
const QString &key : classCountJson.keys() )
224 statsObj.
classCount.insert( key.toInt(), classCountJson.value( key ).toInt() );
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Attribute for point cloud data pair of name and size in bytes.
Used to store statistics of a point cloud dataset.
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
double stDev(const QString &attribute) const
Returns the standard deviation value for the attribute attribute If no matching statistic is availabl...
void clear()
Clears the statistics of all attributes.
QMap< int, int > availableClasses(const QString &attribute) const
Returns a map containing the count of each class of the attribute attribute If no matching statistic ...
static QgsPointCloudStatistics fromStatisticsJson(const QByteArray &stats)
Creates a statistics object from the JSON object stats.
QgsPointCloudStatistics()
QList< int > classesOf(const QString &attribute) const
Returns a list of existing classes which are present for the specified attribute.
double mean(const QString &attribute) const
Returns the mean value for the attribute attribute If no matching statistic is available then NaN wil...
void combineWith(const QgsPointCloudStatistics &stats)
Merges the current statistics with the statistics from stats.
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
int sampledPointsCount() const
Returns the number of points used to calculate the statistics.
QByteArray toStatisticsJson() const
Converts the current statistics object into JSON object.
QgsPointCloudAttributeStatistics statisticsOf(const QString &attribute) const
Returns the calculated statistics of attribute attribute.
Stores statistics of one attribute of a point cloud dataset.
void cumulateStatistics(const QgsPointCloudAttributeStatistics &stats)
Updates the current point cloud statistics to hold the cumulation of the current statistics and stats...
int singleClassCount(int cls) const
Returns the count of points in given class or -1 on error.
QMap< int, int > classCount