QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgspointcloudindex.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointcloudindex.cpp
3  --------------------
4  begin : October 2020
5  copyright : (C) 2020 by Peter Petrik
6  email : zilolv at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgspointcloudindex.h"
19 #include <QFile>
20 #include <QFileInfo>
21 #include <QDir>
22 #include <QJsonArray>
23 #include <QJsonDocument>
24 #include <QJsonObject>
25 #include <QTime>
26 #include <QtDebug>
27 
28 #include "qgstiledownloadmanager.h"
30 
32  mD( -1 ),
33  mX( 0 ),
34  mY( 0 ),
35  mZ( 0 )
36 {}
37 
38 IndexedPointCloudNode::IndexedPointCloudNode( int _d, int _x, int _y, int _z ):
39  mD( _d ),
40  mX( _x ),
41  mY( _y ),
42  mZ( _z )
43 {}
44 
46 {
47  return IndexedPointCloudNode( mD - 1, mX / 2, mY / 2, mZ / 2 );
48 }
49 
51 {
52  QStringList lst = str.split( '-' );
53  if ( lst.count() != 4 )
54  return IndexedPointCloudNode();
55  return IndexedPointCloudNode( lst[0].toInt(), lst[1].toInt(), lst[2].toInt(), lst[3].toInt() );
56 }
57 
59 {
60  return QStringLiteral( "%1-%2-%3-%4" ).arg( mD ).arg( mX ).arg( mY ).arg( mZ );
61 }
62 
64 {
65  return mD;
66 }
67 
69 {
70  return mX;
71 }
72 
74 {
75  return mY;
76 }
77 
79 {
80  return mZ;
81 }
82 
84 {
85  return id.d() + id.x() + id.y() + id.z();
86 }
87 
89 
90 //
91 // QgsPointCloudDataBounds
92 //
93 
95 
96 QgsPointCloudDataBounds::QgsPointCloudDataBounds( qint32 xmin, qint32 ymin, qint32 zmin, qint32 xmax, qint32 ymax, qint32 zmax )
97  : mXMin( xmin )
98  , mYMin( ymin )
99  , mZMin( zmin )
100  , mXMax( xmax )
101  , mYMax( ymax )
102  , mZMax( zmax )
103 {
104 
105 }
106 
107 qint32 QgsPointCloudDataBounds::xMin() const
108 {
109  return mXMin;
110 }
111 
112 qint32 QgsPointCloudDataBounds::yMin() const
113 {
114  return mYMin;
115 }
116 
117 qint32 QgsPointCloudDataBounds::xMax() const
118 {
119  return mXMax;
120 }
121 
122 qint32 QgsPointCloudDataBounds::yMax() const
123 {
124  return mYMax;
125 }
126 
127 qint32 QgsPointCloudDataBounds::zMin() const
128 {
129  return mZMin;
130 }
131 
132 qint32 QgsPointCloudDataBounds::zMax() const
133 {
134  return mZMax;
135 }
136 
137 QgsRectangle QgsPointCloudDataBounds::mapExtent( const QgsVector3D &offset, const QgsVector3D &scale ) const
138 {
139  return QgsRectangle(
140  mXMin * scale.x() + offset.x(), mYMin * scale.y() + offset.y(),
141  mXMax * scale.x() + offset.x(), mYMax * scale.y() + offset.y()
142  );
143 }
144 
145 QgsDoubleRange QgsPointCloudDataBounds::zRange( const QgsVector3D &offset, const QgsVector3D &scale ) const
146 {
147  return QgsDoubleRange( mZMin * scale.z() + offset.z(), mZMax * scale.z() + offset.z() );
148 }
149 
151 
152 //
153 // QgsPointCloudIndex
154 //
155 
157 
159 
161 {
162  QMutexLocker locker( &mHierarchyMutex );
163  return mHierarchy.contains( n );
164 }
165 
167 {
168  QMutexLocker locker( &mHierarchyMutex );
169  return mHierarchy.value( n, -1 );
170 }
171 
172 QList<IndexedPointCloudNode> QgsPointCloudIndex::nodeChildren( const IndexedPointCloudNode &n ) const
173 {
174  QMutexLocker locker( &mHierarchyMutex );
175  Q_ASSERT( mHierarchy.contains( n ) );
176  QList<IndexedPointCloudNode> lst;
177  const int d = n.d() + 1;
178  const int x = n.x() * 2;
179  const int y = n.y() * 2;
180  const int z = n.z() * 2;
181 
182  for ( int i = 0; i < 8; ++i )
183  {
184  int dx = i & 1, dy = !!( i & 2 ), dz = !!( i & 4 );
185  const IndexedPointCloudNode n2( d, x + dx, y + dy, z + dz );
186  if ( mHierarchy.contains( n2 ) )
187  lst.append( n2 );
188  }
189  return lst;
190 }
191 
193 {
194  return mAttributes;
195 }
196 
198 {
199  qint32 xMin = -999999999, yMin = -999999999, zMin = -999999999;
200  qint32 xMax = 999999999, yMax = 999999999, zMax = 999999999;
201 
202  const int d = mRootBounds.xMax() - mRootBounds.xMin();
203  const double dLevel = ( double )d / pow( 2, n.d() );
204 
205  xMin = round( mRootBounds.xMin() + dLevel * n.x() );
206  xMax = round( mRootBounds.xMin() + dLevel * ( n.x() + 1 ) );
207  yMin = round( mRootBounds.yMin() + dLevel * n.y() );
208  yMax = round( mRootBounds.yMin() + dLevel * ( n.y() + 1 ) );
209  zMin = round( mRootBounds.zMin() + dLevel * n.z() );
210  zMax = round( mRootBounds.zMin() + dLevel * ( n.z() + 1 ) );
211 
212  QgsPointCloudDataBounds db( xMin, yMin, zMin, xMax, yMax, zMax );
213  return db;
214 }
215 
217 {
218  return nodeBounds( node ).mapExtent( mOffset, mScale );
219 }
220 
222 {
223  return nodeBounds( node ).zRange( mOffset, mScale );
224 }
225 
227 {
228  const double w = nodeMapExtent( n ).width();
229  return w / mSpan;
230 }
231 
233 {
234  return mScale;
235 }
236 
238 {
239  return mOffset;
240 }
241 
243 {
245 }
246 
248 {
249  return mSpan;
250 }
251 
253 {
254  mHierarchyMutex.lock();
255  const int count = mHierarchy.value( n, -1 );
256  mHierarchyMutex.unlock();
257  return count;
258 }
259 
260 bool QgsPointCloudIndex::setSubsetString( const QString &subset )
261 {
262  const QString lastExpression = mFilterExpression;
263  mFilterExpression.setExpression( subset );
264  if ( mFilterExpression.hasParserError() && !subset.isEmpty() )
265  {
266  mFilterExpression.setExpression( lastExpression );
267  return false;
268  }
269 
270  // fail if expression references unknown attributes
271  int offset;
272  const QSet<QString> attributes = mFilterExpression.referencedAttributes();
273  for ( const QString &attribute : attributes )
274  {
275  if ( !mAttributes.find( attribute, offset ) )
276  {
277  mFilterExpression.setExpression( lastExpression );
278  return false;
279  }
280  }
281  return true;
282 }
283 
285 {
286  return mFilterExpression;
287 }
288 
289 QVariant QgsPointCloudIndex::metadataStatistic( const QString &attribute, QgsStatisticalSummary::Statistic statistic ) const
290 {
291  if ( attribute == QLatin1String( "X" ) && statistic == QgsStatisticalSummary::Min )
292  return mExtent.xMinimum();
293  if ( attribute == QLatin1String( "X" ) && statistic == QgsStatisticalSummary::Max )
294  return mExtent.xMaximum();
295 
296  if ( attribute == QLatin1String( "Y" ) && statistic == QgsStatisticalSummary::Min )
297  return mExtent.yMinimum();
298  if ( attribute == QLatin1String( "Y" ) && statistic == QgsStatisticalSummary::Max )
299  return mExtent.yMaximum();
300 
301  if ( attribute == QLatin1String( "Z" ) && statistic == QgsStatisticalSummary::Min )
302  return mZMin;
303  if ( attribute == QLatin1String( "Z" ) && statistic == QgsStatisticalSummary::Max )
304  return mZMax;
305 
306  return QVariant();
307 }
308 
309 QVariantList QgsPointCloudIndex::metadataClasses( const QString &attribute ) const
310 {
311  Q_UNUSED( attribute );
312  return QVariantList();
313 }
314 
315 QVariant QgsPointCloudIndex::metadataClassStatistic( const QString &attribute, const QVariant &value, QgsStatisticalSummary::Statistic statistic ) const
316 {
317  Q_UNUSED( attribute );
318  Q_UNUSED( value );
319  Q_UNUSED( statistic );
320  return QVariant();
321 }
322 
324 {
325  QMap<QString, QgsPointCloudAttributeStatistics> statsMap;
326  for ( QgsPointCloudAttribute attribute : attributes().attributes() )
327  {
328  QString name = attribute.name();
330  QVariant min = metadataStatistic( name, QgsStatisticalSummary::Min );
331  QVariant max = metadataStatistic( name, QgsStatisticalSummary::Max );
332  QVariant mean = metadataStatistic( name, QgsStatisticalSummary::Mean );
333  QVariant stDev = metadataStatistic( name, QgsStatisticalSummary::StDev );
334  if ( !min.isValid() )
335  continue;
336 
337  s.minimum = min.toDouble();
338  s.maximum = max.toDouble();
339  s.mean = mean.toDouble();
340  s.stDev = stDev.toDouble();
342  QVariantList classes = metadataClasses( name );
343  for ( QVariant c : classes )
344  {
345  s.classCount[ c.toInt() ] = metadataClassStatistic( name, c, QgsStatisticalSummary::Count ).toInt();
346  }
347  statsMap[ name ] = s;
348  }
349  return QgsPointCloudStatistics( pointCount(), statsMap );
350 }
351 
353 {
354  // Base QgsPointCloudIndex fields
355  destination->mExtent = mExtent;
356  destination->mZMin = mZMin;
357  destination->mZMax = mZMax;
358  destination->mHierarchy = mHierarchy;
359  destination->mScale = mScale;
360  destination->mOffset = mOffset;
361  destination->mRootBounds = mRootBounds;
362  destination->mAttributes = mAttributes;
363  destination->mSpan = mSpan;
364  destination->mFilterExpression = mFilterExpression;
365 }
QgsPointCloudIndex::nodeMapExtent
QgsRectangle nodeMapExtent(const IndexedPointCloudNode &node) const
Returns the extent of a node in map coordinates.
Definition: qgspointcloudindex.cpp:216
QgsPointCloudIndex::QgsPointCloudIndex
QgsPointCloudIndex()
Constructs index.
qHash
uint qHash(IndexedPointCloudNode id)
Hash function for indexed nodes.
Definition: qgspointcloudindex.cpp:83
QgsPointCloudIndex::offset
QgsVector3D offset() const
Returns offset.
Definition: qgspointcloudindex.cpp:237
QgsPointCloudAttributeStatistics::classCount
QMap< int, int > classCount
Definition: qgspointcloudstatistics.h:47
QgsPointCloudDataBounds::zMax
qint32 zMax() const
Returns z max.
QgsPointCloudIndex::mOffset
QgsVector3D mOffset
Offset of our int32 coordinates compared to CRS coords.
Definition: qgspointcloudindex.h:341
QgsPointCloudIndex::mAttributes
QgsPointCloudAttributeCollection mAttributes
Definition: qgspointcloudindex.h:343
QgsPointCloudAttributeCollection::find
const QgsPointCloudAttribute * find(const QString &attributeName, int &offset) const
Finds the attribute with the name.
Definition: qgspointcloudattribute.cpp:168
QgsPointCloudDataBounds::yMin
qint32 yMin() const
Returns y min.
QgsStatisticalSummary::StDev
@ StDev
Standard deviation of values.
Definition: qgsstatisticalsummary.h:55
QgsPointCloudDataBounds::mapExtent
QgsRectangle mapExtent(const QgsVector3D &offset, const QgsVector3D &scale) const
Returns 2D rectangle in map coordinates.
qgstiledownloadmanager.h
QgsVector3D::y
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:64
QgsVector3D
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
Definition: qgsvector3d.h:31
QgsPointCloudAttributeStatistics::minimum
double minimum
Definition: qgspointcloudstatistics.h:41
QgsPointCloudIndex::nodeChildren
virtual QList< IndexedPointCloudNode > nodeChildren(const IndexedPointCloudNode &n) const
Returns all children of node.
Definition: qgspointcloudindex.cpp:172
IndexedPointCloudNode::y
int y() const
Returns y.
Definition: qgspointcloudindex.cpp:73
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsPointCloudIndex::nodeError
float nodeError(const IndexedPointCloudNode &n) const
Returns node's error in map units (used to determine in whether the node has enough detail for the cu...
Definition: qgspointcloudindex.cpp:226
IndexedPointCloudNode::x
int x() const
Returns x.
Definition: qgspointcloudindex.cpp:68
QgsPointCloudIndex::copyCommonProperties
void copyCommonProperties(QgsPointCloudIndex *destination) const
Copies common properties to the destination index.
Definition: qgspointcloudindex.cpp:352
QgsPointCloudStatistics
Class used to store statistics of a point cloud dataset.
Definition: qgspointcloudstatistics.h:61
QgsPointCloudDataBounds::xMax
qint32 xMax() const
Returns x max.
QgsPointCloudIndex::attributes
QgsPointCloudAttributeCollection attributes() const
Returns all attributes that are stored in the file.
Definition: qgspointcloudindex.cpp:192
QgsPointCloudIndex::mZMin
double mZMin
Definition: qgspointcloudindex.h:336
QgsPointCloudIndex::~QgsPointCloudIndex
~QgsPointCloudIndex()
QgsPointCloudIndex::subsetString
QString subsetString() const
Returns the string used to define a subset of the point cloud.
Definition: qgspointcloudindex.cpp:284
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
IndexedPointCloudNode::d
int d() const
Returns d.
Definition: qgspointcloudindex.cpp:63
QgsPointCloudIndex::mHierarchy
QHash< IndexedPointCloudNode, int > mHierarchy
Data hierarchy.
Definition: qgspointcloudindex.h:339
QgsPointCloudIndex::mScale
QgsVector3D mScale
Scale of our int32 coordinates compared to CRS coords.
Definition: qgspointcloudindex.h:340
QgsPointCloudDataBounds::yMax
qint32 yMax() const
Returns y max.
QgsPointCloudIndex::mSpan
int mSpan
All native attributes stored in the file.
Definition: qgspointcloudindex.h:344
IndexedPointCloudNode::parentNode
IndexedPointCloudNode parentNode() const
Returns the parent of the node.
Definition: qgspointcloudindex.cpp:45
QgsPointCloudDataBounds::zRange
QgsDoubleRange zRange(const QgsVector3D &offset, const QgsVector3D &scale) const
Returns the z range, applying the specified offset and scale.
qgspointcloudstatistics.h
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
IndexedPointCloudNode
Represents a indexed point cloud node in octree.
Definition: qgspointcloudindex.h:57
QgsPointCloudDataBounds::xMin
qint32 xMin() const
Returns x min.
QgsPointCloudAttributeStatistics
Class used to store statistics of one attribute of a point cloud dataset.
Definition: qgspointcloudstatistics.h:39
QgsPointCloudIndex::metadataStatistics
virtual QgsPointCloudStatistics metadataStatistics() const
Returns the object containings the statistics metadata extracted from the dataset.
Definition: qgspointcloudindex.cpp:323
QgsPointCloudIndex::zMin
double zMin() const
Returns z min.
Definition: qgspointcloudindex.h:269
QgsPointCloudIndex::zMax
double zMax() const
Returns z max.
Definition: qgspointcloudindex.h:271
QgsVector3D::z
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:66
QgsPointCloudIndex::hasNode
virtual bool hasNode(const IndexedPointCloudNode &n) const
Returns whether the octree contain given node.
Definition: qgspointcloudindex.cpp:160
QgsPointCloudAttributeCollection
Collection of point cloud attributes.
Definition: qgspointcloudattribute.h:141
QgsPointCloudIndex::mExtent
QgsRectangle mExtent
2D extent of data
Definition: qgspointcloudindex.h:335
QgsPointCloudAttributeStatistics::count
int count
Definition: qgspointcloudstatistics.h:45
QgsPointCloudIndex::mZMax
double mZMax
Vertical extent of data.
Definition: qgspointcloudindex.h:336
QgsPointCloudDataBounds::zMin
qint32 zMin() const
Returns z min.
QgsPointCloudIndex::scale
QgsVector3D scale() const
Returns scale.
Definition: qgspointcloudindex.cpp:232
QgsPointCloudAttribute
Attribute for point cloud data pair of name and size in bytes.
Definition: qgspointcloudattribute.h:40
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsPointCloudIndex::mRootBounds
QgsPointCloudDataBounds mRootBounds
Bounds of the root node's cube (in int32 coordinates)
Definition: qgspointcloudindex.h:342
qgspointcloudindex.h
QgsPointCloudIndex::metadataClasses
virtual QVariantList metadataClasses(const QString &attribute) const
Returns the classes of attribute.
Definition: qgspointcloudindex.cpp:309
QgsStatisticalSummary::Statistic
Statistic
Enumeration of flags that specify statistics to be calculated.
Definition: qgsstatisticalsummary.h:48
QgsDoubleRange
QgsRange which stores a range of double values.
Definition: qgsrange.h:202
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsPointCloudIndex::mHierarchyMutex
QMutex mHierarchyMutex
Definition: qgspointcloudindex.h:338
str
#define str(x)
Definition: qgis.cpp:37
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsStatisticalSummary::Min
@ Min
Min of values.
Definition: qgsstatisticalsummary.h:57
QgsPointCloudAttributeStatistics::maximum
double maximum
Definition: qgspointcloudstatistics.h:42
QgsPointCloudDataBounds::QgsPointCloudDataBounds
QgsPointCloudDataBounds()
Constructs invalid bounds.
QgsPointCloudAttributeStatistics::stDev
double stDev
Definition: qgspointcloudstatistics.h:44
QgsPointCloudIndex::metadataStatistic
virtual QVariant metadataStatistic(const QString &attribute, QgsStatisticalSummary::Statistic statistic) const
Returns the statistic statistic of attribute.
Definition: qgspointcloudindex.cpp:289
IndexedPointCloudNode::fromString
static IndexedPointCloudNode fromString(const QString &str)
Creates node from string.
Definition: qgspointcloudindex.cpp:50
QgsPointCloudDataBounds
Represents packaged data bounds.
Definition: qgspointcloudindex.h:118
QgsPointCloudIndex::span
int span() const
Returns the number of points in one direction in a single node.
Definition: qgspointcloudindex.cpp:247
IndexedPointCloudNode::IndexedPointCloudNode
IndexedPointCloudNode()
Constructs invalid node.
Definition: qgspointcloudindex.cpp:31
QgsStatisticalSummary::Mean
@ Mean
Mean of values.
Definition: qgsstatisticalsummary.h:53
QgsPointCloudIndex::setAttributes
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Sets native attributes of the data.
Definition: qgspointcloudindex.cpp:242
QgsStatisticalSummary::Max
@ Max
Max of values.
Definition: qgsstatisticalsummary.h:58
IndexedPointCloudNode::z
int z() const
Returns z.
Definition: qgspointcloudindex.cpp:78
QgsPointCloudIndex
Represents a indexed point clouds data in octree.
Definition: qgspointcloudindex.h:163
QgsStatisticalSummary::Count
@ Count
Count.
Definition: qgsstatisticalsummary.h:50
QgsPointCloudIndex::nodeBounds
QgsPointCloudDataBounds nodeBounds(const IndexedPointCloudNode &node) const
Returns bounds of particular node.
Definition: qgspointcloudindex.cpp:197
IndexedPointCloudNode::toString
QString toString() const
Encode node to string.
Definition: qgspointcloudindex.cpp:58
QgsPointCloudAttributeStatistics::mean
double mean
Definition: qgspointcloudstatistics.h:43
QgsVector3D::x
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:62
QgsPointCloudIndex::nodeZRange
QgsDoubleRange nodeZRange(const IndexedPointCloudNode &node) const
Returns the z range of a node.
Definition: qgspointcloudindex.cpp:221
QgsPointCloudIndex::setSubsetString
bool setSubsetString(const QString &subset)
Sets the string used to define a subset of the point cloud.
Definition: qgspointcloudindex.cpp:260
QgsPointCloudIndex::mFilterExpression
QgsPointCloudExpression mFilterExpression
The filter expression to be evaluated when fetching node data.
Definition: qgspointcloudindex.h:345
QgsPointCloudIndex::metadataClassStatistic
virtual QVariant metadataClassStatistic(const QString &attribute, const QVariant &value, QgsStatisticalSummary::Statistic statistic) const
Returns the statistic statistic of the class value of the attribute attribute.
Definition: qgspointcloudindex.cpp:315
QgsPointCloudIndex::nodePointCount
virtual qint64 nodePointCount(const IndexedPointCloudNode &n) const
Returns the number of points of a given node n.
Definition: qgspointcloudindex.cpp:166
QgsPointCloudIndex::pointCount
virtual qint64 pointCount() const =0
Returns the number of points in the point cloud.