19#include "moc_qgspointcloudstatscalculator.cpp"
34#include <QtConcurrent/QtConcurrentMap>
42 : mIndex( index->clone().release() ), mRequest( request ), mFeedback( feedback ), mProgressValue( progressValue )
47 : mIndex( processor.mIndex->clone().release() ), mRequest( processor.mRequest ), mFeedback( processor.mFeedback ), mProgressValue( processor.mProgressValue )
53 mIndex.reset( rhs.mIndex->clone().release() );
54 mRequest = rhs.mRequest;
55 mFeedback = rhs.mFeedback;
56 mProgressValue = rhs.mProgressValue;
66 std::unique_ptr<QgsPointCloudBlock> block =
nullptr;
69 block = mIndex->nodeData( nodeId, mRequest );
74 if ( request ==
nullptr )
76 QgsDebugError( QStringLiteral(
"Unable to calculate statistics for node %1: Got nullptr async request" ).arg( nodeId.
toString() ) );
100 const QVector<QgsPointCloudAttribute> attributes = attributesCollection.
attributes();
101 const char *ptr = block->data();
102 int count = block->pointCount();
105 QMap<QString, QgsPointCloudAttributeStatistics> statsMap;
109 summary.
minimum = std::numeric_limits<double>::max();
110 summary.
maximum = std::numeric_limits<double>::lowest();
113 summary.
stDev = std::numeric_limits<double>::quiet_NaN();
115 statsMap[ attribute.name() ] = std::move( summary );
118 QVector<int> attributeOffsetVector;
119 QSet<int> classifiableAttributesOffsetSet;
122 int attributeOffset = 0;
123 attributesCollection.
find( attribute.name(), attributeOffset );
124 attributeOffsetVector.push_back( attributeOffset );
125 if ( attribute.name() == QLatin1String(
"ScannerChannel" ) ||
126 attribute.name() == QLatin1String(
"ReturnNumber" ) ||
127 attribute.name() == QLatin1String(
"NumberOfReturns" ) ||
128 attribute.name() == QLatin1String(
"ScanDirectionFlag" ) ||
129 attribute.name() == QLatin1String(
"Classification" ) ||
130 attribute.name() == QLatin1String(
"EdgeOfFlightLine" ) ||
131 attribute.name() == QLatin1String(
"PointSourceId" ) ||
132 attribute.name() == QLatin1String(
"Synthetic" ) ||
133 attribute.name() == QLatin1String(
"KeyPoint" ) ||
134 attribute.name() == QLatin1String(
"Withheld" ) ||
135 attribute.name() == QLatin1String(
"Overlap" ) )
137 classifiableAttributesOffsetSet.insert( attributeOffset );
141 for (
int i = 0; i < count; ++i )
143 for (
int j = 0; j < attributes.size(); ++j )
149 QString attributeName = attributes.at( j ).name();
152 double attributeValue = 0;
153 int attributeOffset = attributeOffsetVector[ j ];
159 stats.
mean += attributeValue / count;
162 if ( classifiableAttributesOffsetSet.contains( attributeOffset ) )
172 std::unique_ptr<QgsPointCloudIndex> mIndex =
nullptr;
175 double mProgressValue = 0.0;
177 void updateFeedback()
187 : mIndex( index->clone() )
194 if ( !mIndex->isValid() )
201 qint64 pointCount = 0;
202 QVector<QgsPointCloudNodeId> nodes;
203 QQueue<QgsPointCloudNodeId> queue;
204 queue.push_back( mIndex->root() );
205 while ( !queue.empty() )
209 if ( !mProcessedNodes.contains( node.
id() ) )
211 if ( pointsLimit != -1 && pointCount > pointsLimit )
213 if ( !mProcessedNodes.contains( node.
id() ) )
215 nodes.push_back( node.
id() );
216 mProcessedNodes.insert( node.
id() );
220 queue.push_back( child );
226 QVector<QgsPointCloudStatistics> list = QtConcurrent::blockingMapped( nodes,
StatsProcessor( mIndex.get(), mRequest, feedback, 100.0 / (
double )nodes.size() ) );
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
void canceled()
Internal routines can connect to this signal if they use event loop.
void setProgress(double progress)
Sets the current progress for the feedback object.
double progress() const
Returns the current progress reported by the feedback object.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Collection of point cloud attributes.
int pointRecordSize() const
Returns total size of record.
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
QVector< QgsPointCloudAttribute > attributes() const
Returns all attributes.
Attribute for point cloud data pair of name and size in bytes.
DataType
Systems of unit measurement.
Base class for handling loading QgsPointCloudBlock asynchronously.
QString errorStr()
Returns the error message string of the request.
void finished()
Emitted when the request processing has finished.
std::unique_ptr< QgsPointCloudBlock > takeBlock()
Returns the requested block.
Represents a indexed point clouds data in octree.
@ Local
Local means the source is a local file on the machine.
Represents a indexed point cloud node's position in octree.
QString toString() const
Encode node to string.
Keeps metadata for indexed point cloud node.
QList< QgsPointCloudNodeId > children() const
Returns IDs of child nodes.
qint64 pointCount() const
Returns number of points contained in node data.
QgsPointCloudNodeId id() const
Returns node's ID (unique in index)
static void getAttribute(const char *data, std::size_t offset, QgsPointCloudAttribute::DataType type, T &value)
Retrieves the attribute value from data at the specified offset, where type indicates the original da...
Point cloud data request.
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Set attributes filter in the request.
Class used to store statistics of a point cloud dataset.
void combineWith(const QgsPointCloudStatistics &stats)
Merges the current statistics with the statistics from stats.
int sampledPointsCount() const
Returns the number of points used to calculate the statistics.
QgsPointCloudStatsCalculator(QgsPointCloudIndex *index)
Constructor.
bool calculateStats(QgsFeedback *feedback, const QVector< QgsPointCloudAttribute > &attributes, qint64 pointsLimit=-1)
Calculates the statistics of given attributes attributes up to new pointsLimit points Note: the alrea...
#define QgsDebugError(str)
Class used to store statistics of one attribute of a point cloud dataset.
QMap< int, int > classCount
StatsProcessor(QgsPointCloudIndex *index, QgsPointCloudRequest request, QgsFeedback *feedback, double progressValue)
static QMutex sStatsProcessorFeedbackMutex
StatsProcessor(const StatsProcessor &processor)
QgsPointCloudStatistics result_type
QgsPointCloudStatistics operator()(QgsPointCloudNodeId nodeId)
StatsProcessor & operator=(const StatsProcessor &rhs)