28 : mFilename( filename )
38 int result = mDatabase.
open_v2( mFilename, SQLITE_OPEN_READONLY,
nullptr );
39 if ( result != SQLITE_OK )
49 return bool( mDatabase );
57 if ( QFile::exists( mFilename ) )
61 int result = mDatabase.
open_v2( mFilename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
nullptr );
62 if ( result != SQLITE_OK )
69 "CREATE TABLE metadata (name text, value text);" \
70 "CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob);" \
71 "CREATE UNIQUE INDEX tile_index on tiles (zoom_level, tile_column, tile_row);";
73 result = mDatabase.
exec( sql, errorMessage );
74 if ( result != SQLITE_OK )
76 QgsDebugMsg( QStringLiteral(
"Failed to initialize MBTiles database: " ) + errorMessage );
87 QgsDebugMsg( QStringLiteral(
"MBTiles database not open: " ) + mFilename );
92 QString sql = QStringLiteral(
"select value from metadata where name='%1'" ).arg( key );
94 if ( result != SQLITE_OK )
96 QgsDebugMsg( QStringLiteral(
"MBTile failed to prepare statement: " ) + sql );
100 if ( preparedStatement.
step() != SQLITE_ROW )
102 QgsDebugMsg( QStringLiteral(
"MBTile metadata value not found: " ) + key );
113 QgsDebugMsg( QStringLiteral(
"MBTiles database not open: " ) + mFilename );
120 if ( result != SQLITE_OK )
122 QgsDebugMsg( QStringLiteral(
"MBTile failed to prepare statement: " ) + sql );
126 if ( preparedStatement.
step() != SQLITE_DONE )
128 QgsDebugMsg( QStringLiteral(
"MBTile metadata value failed to be set: " ) + key );
136 if ( boundsStr.isEmpty() )
138 QStringList boundsArray = boundsStr.split(
',' );
139 if ( boundsArray.count() != 4 )
142 return QgsRectangle( boundsArray[0].toDouble(), boundsArray[1].toDouble(),
143 boundsArray[2].toDouble(), boundsArray[3].toDouble() );
150 QgsDebugMsg( QStringLiteral(
"MBTiles database not open: " ) + mFilename );
155 QString sql = QStringLiteral(
"select tile_data from tiles where zoom_level=%1 and tile_column=%2 and tile_row=%3" ).arg( z ).arg( x ).arg( y );
157 if ( result != SQLITE_OK )
159 QgsDebugMsg( QStringLiteral(
"MBTile failed to prepare statement: " ) + sql );
163 if ( preparedStatement.
step() != SQLITE_ROW )
165 QgsDebugMsg( QStringLiteral(
"MBTile not found: z=%1 x=%2 y=%3" ).arg( z ).arg( x ).arg( y ) );
175 QByteArray tileBlob =
tileData( z, x, y );
176 if ( !tileImage.loadFromData( tileBlob ) )
178 QgsDebugMsg( QStringLiteral(
"MBTile data failed to load: z=%1 x=%2 y=%3" ).arg( z ).arg( x ).arg( y ) );
188 QgsDebugMsg( QStringLiteral(
"MBTiles database not open: " ) + mFilename );
193 QString sql = QStringLiteral(
"insert into tiles values (%1, %2, %3, ?)" ).arg( z ).arg( x ).arg( y );
195 if ( result != SQLITE_OK )
197 QgsDebugMsg( QStringLiteral(
"MBTile failed to prepare statement: " ) + sql );
201 sqlite3_bind_blob( preparedStatement.get(), 1, data.constData(), data.size(), SQLITE_TRANSIENT );
203 if ( preparedStatement.
step() != SQLITE_DONE )
205 QgsDebugMsg( QStringLiteral(
"MBTile tile failed to be set: %1,%2,%3" ).arg( z ).arg( x ).arg( y ) );
212 unsigned char *bytesInPtr =
reinterpret_cast<unsigned char *
>(
const_cast<char *
>( bytesIn.constData() ) );
213 uint bytesInLeft =
static_cast<uint
>( bytesIn.count() );
215 const uint CHUNK = 16384;
216 unsigned char out[CHUNK];
217 const int DEC_MAGIC_NUM_FOR_GZIP = 16;
221 strm.zalloc = Z_NULL;
223 strm.opaque = Z_NULL;
225 strm.next_in = Z_NULL;
227 int ret = inflateInit2( &strm, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP );
231 while ( ret != Z_STREAM_END )
234 uint bytesToProcess = std::min( CHUNK, bytesInLeft );
235 strm.next_in = bytesInPtr;
236 strm.avail_in = bytesToProcess;
237 bytesInPtr += bytesToProcess;
238 bytesInLeft -= bytesToProcess;
240 if ( bytesToProcess == 0 )
246 strm.avail_out = CHUNK;
248 ret = inflate( &strm, Z_NO_FLUSH );
249 Q_ASSERT( ret != Z_STREAM_ERROR );
250 if ( ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR )
255 unsigned have = CHUNK - strm.avail_out;
256 bytesOut.append( QByteArray::fromRawData(
reinterpret_cast<const char *
>( out ),
static_cast<int>( have ) ) );
258 while ( strm.avail_out == 0 );
262 return ret == Z_STREAM_END;
268 unsigned char *bytesInPtr =
reinterpret_cast<unsigned char *
>(
const_cast<char *
>( bytesIn.constData() ) );
269 uint bytesInLeft =
static_cast<uint
>( bytesIn.count() );
271 const uint CHUNK = 16384;
272 unsigned char out[CHUNK];
273 const int DEC_MAGIC_NUM_FOR_GZIP = 16;
277 strm.zalloc = Z_NULL;
279 strm.opaque = Z_NULL;
281 int ret = deflateInit2( &strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP, 8, Z_DEFAULT_STRATEGY );
285 strm.avail_in = bytesInLeft;
286 strm.next_in = bytesInPtr;
292 strm.avail_out = CHUNK;
294 ret = deflate( &strm, Z_FINISH );
295 Q_ASSERT( ret != Z_STREAM_ERROR );
297 unsigned have = CHUNK - strm.avail_out;
298 bytesOut.append( QByteArray::fromRawData(
reinterpret_cast<const char *
>( out ),
static_cast<int>( have ) ) );
300 while ( strm.avail_out == 0 );
301 Q_ASSERT( ret == Z_STREAM_END );