24 #include <QJsonDocument>
25 #include <QJsonObject>
45 #include "qgspointcloudexpression.h"
49 QgsRemoteEptPointCloudIndex::QgsRemoteEptPointCloudIndex() : QgsEptPointCloudIndex()
54 QgsRemoteEptPointCloudIndex::~QgsRemoteEptPointCloudIndex() =
default;
56 std::unique_ptr<QgsPointCloudIndex> QgsRemoteEptPointCloudIndex::clone()
const
58 QgsRemoteEptPointCloudIndex *clone =
new QgsRemoteEptPointCloudIndex;
59 QMutexLocker locker( &mHierarchyMutex );
60 copyCommonProperties( clone );
61 return std::unique_ptr<QgsPointCloudIndex>( clone );
64 QList<IndexedPointCloudNode> QgsRemoteEptPointCloudIndex::nodeChildren(
const IndexedPointCloudNode &n )
const
66 QList<IndexedPointCloudNode> lst;
67 if ( !loadNodeHierarchy( n ) )
70 const int d = n.
d() + 1;
71 const int x = n.
x() * 2;
72 const int y = n.
y() * 2;
73 const int z = n.
z() * 2;
76 for (
int i = 0; i < 8; ++i )
78 int dx = i & 1, dy = !!( i & 2 ), dz = !!( i & 4 );
80 if ( loadNodeHierarchy( n2 ) )
86 void QgsRemoteEptPointCloudIndex::load(
const QString &url )
90 QStringList splitUrl = url.split(
'/' );
92 mUrlFileNamePart = splitUrl.back();
94 mUrlDirectoryPart = splitUrl.join(
'/' );
96 QNetworkRequest nr( url );
102 QgsDebugMsg( QStringLiteral(
"Request failed: " ) + url );
108 mIsValid = loadSchema( reply.
content() );
113 std::unique_ptr<QgsPointCloudBlockRequest> blockRequest( asyncNodeData( n, request ) );
121 if ( !blockRequest->block() )
123 QgsDebugMsg( QStringLiteral(
"Error downloading node %1 data, error : %2 " ).arg( n.
toString(), blockRequest->errorStr() ) );
126 return blockRequest->block();
131 if ( !loadNodeHierarchy( n ) )
135 if ( mDataType == QLatin1String(
"binary" ) )
137 fileUrl = QStringLiteral(
"%1/ept-data/%2.bin" ).arg( mUrlDirectoryPart, n.
toString() );
139 else if ( mDataType == QLatin1String(
"zstandard" ) )
141 fileUrl = QStringLiteral(
"%1/ept-data/%2.zst" ).arg( mUrlDirectoryPart, n.
toString() );
143 else if ( mDataType == QLatin1String(
"laszip" ) )
145 fileUrl = QStringLiteral(
"%1/ept-data/%2.laz" ).arg( mUrlDirectoryPart, n.
toString() );
155 QgsPointCloudExpression filterExpression = mFilterExpression;
157 requestAttributes.
extend( attributes(), filterExpression.referencedAttributes() );
163 return loadNodeHierarchy( n );
168 mHierarchyMutex.lock();
169 bool found = mHierarchy.contains( nodeId );
170 mHierarchyMutex.unlock();
174 QVector<IndexedPointCloudNode> nodePathToRoot;
179 nodePathToRoot.push_back( currentNode );
182 while ( currentNode.
d() >= 0 );
185 for (
int i = nodePathToRoot.size() - 1; i >= 0 && !mHierarchy.contains( nodeId ); --i )
189 mHierarchyMutex.lock();
190 const bool foundInHierarchy = mHierarchy.contains( node );
191 const bool foundInHierarchyNodes = mHierarchyNodes.contains( node );
192 mHierarchyMutex.unlock();
193 if ( foundInHierarchy )
196 if ( !foundInHierarchyNodes )
199 const QString fileUrl = QStringLiteral(
"%1/ept-hierarchy/%2.json" ).arg( mUrlDirectoryPart, node.
toString() );
200 QNetworkRequest nr( fileUrl );
202 nr.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
203 nr.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
209 QgsDebugMsgLevel( QStringLiteral(
"unable to read hierarchy from file %1" ).arg( fileUrl ), 2 );
215 const QByteArray dataJsonH = reply.
content();
216 QJsonParseError errH;
217 const QJsonDocument docH = QJsonDocument::fromJson( dataJsonH, &errH );
218 if ( errH.error != QJsonParseError::NoError )
220 QgsDebugMsgLevel( QStringLiteral(
"QJsonParseError when reading hierarchy from file %1" ).arg( fileUrl ), 2 );
224 const QJsonObject rootHObj = docH.object();
225 for (
auto it = rootHObj.constBegin(); it != rootHObj.constEnd(); ++it )
227 const QString nodeIdStr = it.key();
228 const int nodePointCount = it.value().toInt();
230 mHierarchyMutex.lock();
231 if ( nodePointCount > 0 )
232 mHierarchy[nodeId] = nodePointCount;
233 else if ( nodePointCount == -1 )
234 mHierarchyNodes.insert( nodeId );
235 mHierarchyMutex.unlock();
239 mHierarchyMutex.lock();
240 found = mHierarchy.contains( nodeId );
241 mHierarchyMutex.unlock();
246 bool QgsRemoteEptPointCloudIndex::isValid()
const
251 void QgsRemoteEptPointCloudIndex::copyCommonProperties( QgsRemoteEptPointCloudIndex *destination )
const
253 QgsEptPointCloudIndex::copyCommonProperties( destination );
256 destination->mUrlDirectoryPart = mUrlDirectoryPart;
257 destination->mUrlFileNamePart = mUrlFileNamePart;
258 destination->mUrl = mUrl;
259 destination->mHierarchyNodes = mHierarchyNodes;