Branch data Line data Source code
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"
29 : :
30 : 0 : IndexedPointCloudNode::IndexedPointCloudNode():
31 : 0 : mD( -1 ),
32 : 0 : mX( 0 ),
33 : 0 : mY( 0 ),
34 : 0 : mZ( 0 )
35 : 0 : {}
36 : :
37 : 0 : IndexedPointCloudNode::IndexedPointCloudNode( int _d, int _x, int _y, int _z ):
38 : 0 : mD( _d ),
39 : 0 : mX( _x ),
40 : 0 : mY( _y ),
41 : 0 : mZ( _z )
42 : 0 : {}
43 : :
44 : 0 : IndexedPointCloudNode IndexedPointCloudNode::parentNode() const
45 : : {
46 : 0 : return IndexedPointCloudNode( mD - 1, mX / 2, mY / 2, mZ / 2 );
47 : : }
48 : :
49 : 0 : IndexedPointCloudNode IndexedPointCloudNode::fromString( const QString &str )
50 : : {
51 : 0 : QStringList lst = str.split( '-' );
52 : 0 : if ( lst.count() != 4 )
53 : 0 : return IndexedPointCloudNode();
54 : 0 : return IndexedPointCloudNode( lst[0].toInt(), lst[1].toInt(), lst[2].toInt(), lst[3].toInt() );
55 : 0 : }
56 : :
57 : 0 : QString IndexedPointCloudNode::toString() const
58 : : {
59 : 0 : return QStringLiteral( "%1-%2-%3-%4" ).arg( mD ).arg( mX ).arg( mY ).arg( mZ );
60 : 0 : }
61 : :
62 : 0 : int IndexedPointCloudNode::d() const
63 : : {
64 : 0 : return mD;
65 : : }
66 : :
67 : 0 : int IndexedPointCloudNode::x() const
68 : : {
69 : 0 : return mX;
70 : : }
71 : :
72 : 0 : int IndexedPointCloudNode::y() const
73 : : {
74 : 0 : return mY;
75 : : }
76 : :
77 : 0 : int IndexedPointCloudNode::z() const
78 : : {
79 : 0 : return mZ;
80 : : }
81 : :
82 : 0 : uint qHash( IndexedPointCloudNode id )
83 : : {
84 : 0 : return id.d() + id.x() + id.y() + id.z();
85 : : }
86 : :
87 : : ///@cond PRIVATE
88 : :
89 : : //
90 : : // QgsPointCloudDataBounds
91 : : //
92 : :
93 : 0 : QgsPointCloudDataBounds::QgsPointCloudDataBounds() = default;
94 : :
95 : 0 : QgsPointCloudDataBounds::QgsPointCloudDataBounds( qint32 xmin, qint32 ymin, qint32 zmin, qint32 xmax, qint32 ymax, qint32 zmax )
96 : 0 : : mXMin( xmin )
97 : 0 : , mYMin( ymin )
98 : 0 : , mZMin( zmin )
99 : 0 : , mXMax( xmax )
100 : 0 : , mYMax( ymax )
101 : 0 : , mZMax( zmax )
102 : : {
103 : :
104 : 0 : }
105 : :
106 : 0 : qint32 QgsPointCloudDataBounds::xMin() const
107 : : {
108 : 0 : return mXMin;
109 : : }
110 : :
111 : 0 : qint32 QgsPointCloudDataBounds::yMin() const
112 : : {
113 : 0 : return mYMin;
114 : : }
115 : :
116 : 0 : qint32 QgsPointCloudDataBounds::xMax() const
117 : : {
118 : 0 : return mXMax;
119 : : }
120 : :
121 : 0 : qint32 QgsPointCloudDataBounds::yMax() const
122 : : {
123 : 0 : return mYMax;
124 : : }
125 : :
126 : 0 : qint32 QgsPointCloudDataBounds::zMin() const
127 : : {
128 : 0 : return mZMin;
129 : : }
130 : :
131 : 0 : qint32 QgsPointCloudDataBounds::zMax() const
132 : : {
133 : 0 : return mZMax;
134 : : }
135 : :
136 : 0 : QgsRectangle QgsPointCloudDataBounds::mapExtent( const QgsVector3D &offset, const QgsVector3D &scale ) const
137 : : {
138 : 0 : return QgsRectangle(
139 : 0 : mXMin * scale.x() + offset.x(), mYMin * scale.y() + offset.y(),
140 : 0 : mXMax * scale.x() + offset.x(), mYMax * scale.y() + offset.y()
141 : : );
142 : : }
143 : :
144 : 0 : QgsDoubleRange QgsPointCloudDataBounds::zRange( const QgsVector3D &offset, const QgsVector3D &scale ) const
145 : : {
146 : 0 : return QgsDoubleRange( mZMin * scale.z() + offset.z(), mZMax * scale.z() + offset.z() );
147 : : }
148 : :
149 : : ///@endcond
150 : :
151 : : //
152 : : // QgsPointCloudIndex
153 : : //
154 : :
155 : 0 : QgsPointCloudIndex::QgsPointCloudIndex() = default;
156 : :
157 : 0 : QgsPointCloudIndex::~QgsPointCloudIndex() = default;
158 : :
159 : 0 : QList<IndexedPointCloudNode> QgsPointCloudIndex::nodeChildren( const IndexedPointCloudNode &n ) const
160 : : {
161 : : Q_ASSERT( mHierarchy.contains( n ) );
162 : 0 : QList<IndexedPointCloudNode> lst;
163 : 0 : int d = n.d() + 1;
164 : 0 : int x = n.x() * 2;
165 : 0 : int y = n.y() * 2;
166 : 0 : int z = n.z() * 2;
167 : :
168 : 0 : for ( int i = 0; i < 8; ++i )
169 : : {
170 : 0 : int dx = i & 1, dy = !!( i & 2 ), dz = !!( i & 4 );
171 : 0 : IndexedPointCloudNode n2( d, x + dx, y + dy, z + dz );
172 : 0 : if ( mHierarchy.contains( n2 ) )
173 : 0 : lst.append( n2 );
174 : 0 : }
175 : 0 : return lst;
176 : 0 : }
177 : :
178 : 0 : QgsPointCloudAttributeCollection QgsPointCloudIndex::attributes() const
179 : : {
180 : 0 : return mAttributes;
181 : : }
182 : :
183 : 0 : QgsPointCloudDataBounds QgsPointCloudIndex::nodeBounds( const IndexedPointCloudNode &n ) const
184 : : {
185 : 0 : qint32 xMin = -999999999, yMin = -999999999, zMin = -999999999;
186 : 0 : qint32 xMax = 999999999, yMax = 999999999, zMax = 999999999;
187 : :
188 : 0 : int d = mRootBounds.xMax() - mRootBounds.xMin();
189 : 0 : double dLevel = ( double )d / pow( 2, n.d() );
190 : :
191 : 0 : xMin = round( mRootBounds.xMin() + dLevel * n.x() );
192 : 0 : xMax = round( mRootBounds.xMin() + dLevel * ( n.x() + 1 ) );
193 : 0 : yMin = round( mRootBounds.yMin() + dLevel * n.y() );
194 : 0 : yMax = round( mRootBounds.yMin() + dLevel * ( n.y() + 1 ) );
195 : 0 : zMin = round( mRootBounds.zMin() + dLevel * n.z() );
196 : 0 : zMax = round( mRootBounds.zMin() + dLevel * ( n.z() + 1 ) );
197 : :
198 : 0 : QgsPointCloudDataBounds db( xMin, yMin, zMin, xMax, yMax, zMax );
199 : 0 : return db;
200 : : }
201 : :
202 : 0 : QgsRectangle QgsPointCloudIndex::nodeMapExtent( const IndexedPointCloudNode &node ) const
203 : : {
204 : 0 : return nodeBounds( node ).mapExtent( mOffset, mScale );
205 : : }
206 : :
207 : 0 : QgsDoubleRange QgsPointCloudIndex::nodeZRange( const IndexedPointCloudNode &node ) const
208 : : {
209 : 0 : return nodeBounds( node ).zRange( mOffset, mScale );
210 : : }
211 : :
212 : 0 : float QgsPointCloudIndex::nodeError( const IndexedPointCloudNode &n ) const
213 : : {
214 : 0 : double w = nodeMapExtent( n ).width();
215 : 0 : return w / mSpan;
216 : : }
217 : :
218 : 0 : QgsVector3D QgsPointCloudIndex::scale() const
219 : : {
220 : 0 : return mScale;
221 : : }
222 : :
223 : 0 : QgsVector3D QgsPointCloudIndex::offset() const
224 : : {
225 : 0 : return mOffset;
226 : : }
227 : :
228 : 0 : void QgsPointCloudIndex::setAttributes( const QgsPointCloudAttributeCollection &attributes )
229 : : {
230 : 0 : mAttributes = attributes;
231 : 0 : }
232 : :
233 : 0 : int QgsPointCloudIndex::span() const
234 : : {
235 : 0 : return mSpan;
236 : : }
237 : :
238 : 0 : int QgsPointCloudIndex::nodePointCount( const IndexedPointCloudNode &n )
239 : : {
240 : 0 : if ( !mHierarchy.contains( n ) )
241 : 0 : return -1;
242 : 0 : return mHierarchy[n];
243 : 0 : }
|