/
qgsmbtilesreader.cpp
124 lines (105 loc) · 3.77 KB
/
qgsmbtilesreader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/***************************************************************************
qgsmbtilesreader.cpp
--------------------------------------
Date : January 2020
Copyright : (C) 2020 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsmbtilesreader.h"
#include "qgslogger.h"
#include "qgsrectangle.h"
#include <QImage>
QgsMBTilesReader::QgsMBTilesReader( const QString &filename )
: mFilename( filename )
{
}
bool QgsMBTilesReader::open()
{
if ( mDatabase )
return true; // already opened
sqlite3_database_unique_ptr database;
int result = mDatabase.open_v2( mFilename, SQLITE_OPEN_READONLY, nullptr );
if ( result != SQLITE_OK )
{
QgsDebugMsg( QStringLiteral( "Can't open MBTiles database: %1" ).arg( database.errorMessage() ) );
return false;
}
return true;
}
bool QgsMBTilesReader::isOpen() const
{
return bool( mDatabase );
}
QString QgsMBTilesReader::metadataValue( const QString &key )
{
if ( !mDatabase )
{
QgsDebugMsg( QStringLiteral( "MBTiles database not open: " ) + mFilename );
return QString();
}
int result;
QString sql = QStringLiteral( "select value from metadata where name='%1'" ).arg( key );
sqlite3_statement_unique_ptr preparedStatement = mDatabase.prepare( sql, result );
if ( result != SQLITE_OK )
{
QgsDebugMsg( QStringLiteral( "MBTile failed to prepare statement: " ) + sql );
return QString();
}
if ( preparedStatement.step() != SQLITE_ROW )
{
QgsDebugMsg( QStringLiteral( "MBTile metadata value not found: " ) + key );
return QString();
}
return preparedStatement.columnAsText( 0 );
}
QgsRectangle QgsMBTilesReader::extent()
{
QString boundsStr = metadataValue( "bounds" );
if ( boundsStr.isEmpty() )
return QgsRectangle();
QStringList boundsArray = boundsStr.split( ',' );
if ( boundsArray.count() != 4 )
return QgsRectangle();
return QgsRectangle( boundsArray[0].toDouble(), boundsArray[1].toDouble(),
boundsArray[2].toDouble(), boundsArray[3].toDouble() );
}
QByteArray QgsMBTilesReader::tileData( int z, int x, int y )
{
if ( !mDatabase )
{
QgsDebugMsg( QStringLiteral( "MBTiles database not open: " ) + mFilename );
return QByteArray();
}
int result;
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 );
sqlite3_statement_unique_ptr preparedStatement = mDatabase.prepare( sql, result );
if ( result != SQLITE_OK )
{
QgsDebugMsg( QStringLiteral( "MBTile failed to prepare statement: " ) + sql );
return QByteArray();
}
if ( preparedStatement.step() != SQLITE_ROW )
{
QgsDebugMsg( QStringLiteral( "MBTile not found: z=%1 x=%2 y=%3" ).arg( z ).arg( x ).arg( y ) );
return QByteArray();
}
return preparedStatement.columnAsBlob( 0 );
}
QImage QgsMBTilesReader::tileDataAsImage( int z, int x, int y )
{
QImage tileImage;
QByteArray tileBlob = tileData( z, x, y );
if ( !tileImage.loadFromData( tileBlob ) )
{
QgsDebugMsg( QStringLiteral( "MBTile data failed to load: z=%1 x=%2 y=%3" ).arg( z ).arg( x ).arg( y ) );
return QImage();
}
return tileImage;
}