25#include <QJsonDocument>
36 const double delta1 = newMean -
mean;
38 const double delta2 = newMean - stats.
mean;
39 const double variance2 = stats.
stDev * stats.
stDev * ( stats.
count - 1 ) + stats.
count * delta2 * delta2;
40 const double variance = ( variance1 + variance2 ) / (
count + stats.
count );
41 stDev = std::sqrt( variance );
72 mStatisticsMap.clear();
79 mStatisticsMap.remove( attribute.name() );
86 defaultVal.
minimum = std::numeric_limits<double>::max();
87 defaultVal.
maximum = std::numeric_limits<double>::lowest();
89 return mStatisticsMap.value( attribute, defaultVal );
94 if ( !mStatisticsMap.contains( attribute ) )
102 if ( !mStatisticsMap.contains( attribute ) )
103 return QMap<int, int>();
104 return mStatisticsMap[ attribute ].classCount;
109 if ( !mStatisticsMap.contains( attribute ) )
110 return std::numeric_limits<double>::quiet_NaN();
111 return mStatisticsMap[ attribute ].minimum;
116 if ( !mStatisticsMap.contains( attribute ) )
117 return std::numeric_limits<double>::quiet_NaN();
118 return mStatisticsMap[ attribute ].maximum;
123 if ( !mStatisticsMap.contains( attribute ) )
124 return std::numeric_limits<double>::quiet_NaN();
125 return mStatisticsMap[ attribute ].mean;
130 if ( !mStatisticsMap.contains( attribute ) )
131 return std::numeric_limits<double>::quiet_NaN();
132 return mStatisticsMap[ attribute ].stDev;
138 for (
auto it = stats.mStatisticsMap.constBegin(); it != stats.mStatisticsMap.constEnd(); it++ )
140 const QString attribute = it.key();
142 if ( mStatisticsMap.contains( attribute ) )
146 mStatisticsMap[ attribute ] = s;
148 mSampledPointsCount += stats.mSampledPointsCount;
154 obj.insert( QStringLiteral(
"sampled-points" ), QJsonValue::fromVariant(
sampledPointsCount() ) );
156 for (
auto it = mStatisticsMap.constBegin(); it != mStatisticsMap.constEnd(); it++ )
159 stats.insert( it.key(), attributeStatisticsToJson( stat ) );
161 obj.insert( QStringLiteral(
"stats" ), stats );
163 QJsonDocument statsDoc( obj );
164 return statsDoc.toJson( QJsonDocument::Compact );
169 QJsonParseError error;
170 QJsonDocument document = QJsonDocument::fromJson( statsByteArray, &error );
171 if ( error.error != QJsonParseError::NoError )
173 QgsMessageLog::logMessage( QObject::tr(
"Failed to load statistics JSON from COPC file, reason: %1" ).arg( error.errorString() ) );
177 QJsonObject statsJson = document.object();
180 stats.mSampledPointsCount = statsJson.value( QStringLiteral(
"sampled-points" ) ).toInt();
181 if ( statsJson.contains( QStringLiteral(
"stats" ) ) )
183 QJsonObject statsObj = statsJson.value( QStringLiteral(
"stats" ) ).toObject();
184 for (
const QString &attr : statsObj.keys() )
186 QJsonObject obj = statsObj.value( attr ).toObject();
188 attrStats.
count = stats.mSampledPointsCount;
189 stats.mStatisticsMap.insert( attr, attrStats );
198 obj.insert( QStringLiteral(
"minimum" ), stats.
minimum );
199 obj.insert( QStringLiteral(
"maximum" ), stats.
maximum );
200 obj.insert( QStringLiteral(
"mean" ), stats.
mean );
201 if ( !std::isnan( stats.
stDev ) )
203 obj.insert( QStringLiteral(
"standard-deviation" ), stats.
stDev );
205 QJsonObject classCount;
208 classCount.insert( QString::number( it.key() ), it.value() );
210 obj.insert( QStringLiteral(
"class-count" ), classCount );
216 QgsPointCloudAttributeStatistics statsObj;
217 QVariantMap m = statsJson.toVariantMap();
218 statsObj.
minimum = m.value( QStringLiteral(
"minimum" ), std::numeric_limits<double>::max() ).toDouble();
219 statsObj.
maximum = m.value( QStringLiteral(
"maximum" ), std::numeric_limits<double>::lowest() ).toDouble();
220 statsObj.
mean = m.value( QStringLiteral(
"mean" ), 0 ).toDouble();
221 statsObj.
stDev = m.value( QStringLiteral(
"standard-deviation" ), std::numeric_limits<double>::quiet_NaN() ).toDouble();
222 QJsonObject classCountJson = statsJson.value( QStringLiteral(
"class-count" ) ).toObject();
223 for (
const QString &key : classCountJson.keys() )
225 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.
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