25 #define GZIP_WINDOWS_BIT 15 + 16
26 #define GZIP_CHUNK_SIZE 32 * 1024
40 if ( input.isEmpty() )
49 strm.next_in = Z_NULL;
58 const char *input_data = input.constData();
59 int input_data_left = input.length();
68 if ( chunk_size <= 0 )
72 strm.next_in = (
unsigned char * )input_data;
73 strm.avail_in = chunk_size;
76 input_data += chunk_size;
77 input_data_left -= chunk_size;
87 strm.next_out = (
unsigned char * )out;
91 ret = inflate( &strm, Z_NO_FLUSH );
112 output.append( (
char * )out, have );
115 while ( strm.avail_out == 0 );
118 while ( ret != Z_STREAM_END );
124 return ( ret == Z_STREAM_END );
130 for (
int i = 0; i < count; ++i )
132 quint16 encoded = *( quint16 * ) dataPtr;
134 qint16 decoded = ( encoded >> 1 ) ^ ( -( encoded & 1 ) );
141 static QString _tileFilename(
int tx,
int ty,
int tz )
143 return QString(
"/tmp/terrain-%1-%2-%3" ).arg( tz ).arg( tx ).arg( ty );
148 QString filename = _tileFilename( tx, ty, tz );
150 if ( !f.open( QIODevice::ReadOnly ) )
157 if ( data.isEmpty() )
163 const char *dataPtr = data.constData();
178 quint32 vertexCount = *( quint32 * ) dataPtr;
180 t->
uvh.resize( 3 * vertexCount );
181 qint16 *vptr = t->
uvh.data();
184 qint16 u = 0, v = 0, h = 0;
185 for ( uint i = 0; i < vertexCount; ++i )
187 qint16 du = vptr[i], dv = vptr[vertexCount + i], dh = vptr[vertexCount * 2 + i];
192 vptr[vertexCount + i] = v;
193 vptr[vertexCount * 2 + i] = h;
196 Q_ASSERT( vertexCount < 65537 );
207 quint32 triangleCount = *( quint32 * ) dataPtr;
209 t->
indices.resize( 3 * triangleCount );
210 quint16 *indicesPtr = t->
indices.data();
211 quint16 *srcIdxPtr = ( quint16 * )dataPtr;
213 for ( uint i = 0; i < triangleCount * 3; ++i )
215 quint16 code = *srcIdxPtr++;
216 *indicesPtr++ = highest - code;
233 #include <QGuiApplication>
234 #include <QNetworkRequest>
235 #include <QNetworkReply>
242 QString tileFilename = _tileFilename( tx, ty, tz );
243 if ( !QFile::exists( tileFilename ) )
245 qDebug() <<
"downloading tile " << tx <<
" " << ty <<
" " << tz;
246 bool downloaded =
false;
247 QString url = QString(
"http://assets.agi.com/stk-terrain/tilesets/world/tiles/%1/%2/%3.terrain" ).arg( tz ).arg( tx ).arg( ty );
248 QNetworkRequest request( url );
249 request.setRawHeader( QByteArray(
"Accept-Encoding" ), QByteArray(
"gzip" ) );
250 request.setRawHeader( QByteArray(
"Accept" ), QByteArray(
"application/vnd.quantized-mesh,application/octet-stream;q=0.9" ) );
251 request.setRawHeader( QByteArray(
"User-Agent" ), QByteArray(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/58.0.3029.110 Chrome/58.0.3029.110 Safari/537.36" ) );
253 connect( reply, &QNetworkReply::finished, [reply, tileFilename, &downloaded]
255 QFile fOut( tileFilename );
256 fOut.open( QIODevice::WriteOnly );
257 fOut.write( reply->readAll() );
259 reply->deleteLater();
263 while ( !downloaded )
265 qApp->processEvents();
277 : QGeometry( parent )
279 int vertexCount = t->
uvh.count() / 3;
280 int indexCount = t->
indices.count();
282 int vertexEntrySize =
sizeof( float ) * ( 3 + 2 );
291 const qint16 *uvh = t->
uvh.constData();
292 vb.resize( vertexCount * vertexEntrySize );
293 float *vbptr = (
float * ) vb.data();
294 for (
int i = 0; i < vertexCount; ++i )
296 qint16 u = uvh[i], v = uvh[vertexCount + i], h = uvh[vertexCount * 2 + i];
297 float uNorm = u / 32767.f;
298 float vNorm = v / 32767.f;
299 float hNorm = h / 32767.f;
300 float xWgs = xMinWgs + widthWgs * uNorm;
301 float yWgs = yMinWgs + heightWgs * vNorm;
305 QgsPointXY ptFinal( ptProjected.x() - ptMinProjected.
x(), ptProjected.y() - ptMinProjected.
y() );
308 *vbptr++ = ptFinal.
x();
310 *vbptr++ = -ptFinal.
y();
319 ib.resize( indexCount * 2 );
320 memcpy( ib.data(), t->
indices.constData(), ib.count() );
332 m_vertexBuffer =
new Qt3DRender::QBuffer(
this );
333 m_indexBuffer =
new Qt3DRender::QBuffer(
this );
335 m_vertexBuffer->setData( vb );
336 m_indexBuffer->setData( ib );
338 m_positionAttribute =
new Qt3DRender::QAttribute(
this );
339 m_positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );
340 m_positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
341 m_positionAttribute->setVertexSize( 3 );
342 m_positionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
343 m_positionAttribute->setBuffer( m_vertexBuffer );
344 m_positionAttribute->setByteStride( vertexEntrySize );
345 m_positionAttribute->setCount( vertexCount );
347 m_texCoordAttribute =
new Qt3DRender::QAttribute(
this );
348 m_texCoordAttribute->setName( Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName() );
349 m_texCoordAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
350 m_texCoordAttribute->setVertexSize( 2 );
351 m_texCoordAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
352 m_texCoordAttribute->setBuffer( m_vertexBuffer );
353 m_texCoordAttribute->setByteStride( vertexEntrySize );
354 m_texCoordAttribute->setByteOffset( 3 *
sizeof(
float ) );
355 m_texCoordAttribute->setCount( vertexCount );
357 m_indexAttribute =
new Qt3DRender::QAttribute(
this );
358 m_indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute );
359 m_indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedShort );
360 m_indexAttribute->setBuffer( m_indexBuffer );
361 m_indexAttribute->setCount( indexCount );
363 addAttribute( m_positionAttribute );
364 addAttribute( m_texCoordAttribute );
365 addAttribute( m_indexAttribute );