9 : m_tileEdgeLengthPixel( 512 ),
10 m_emptyPixel( qRgba( 0, 0, 0, 255 )),
11 m_baseDirectory( baseDirectory ),
12 m_tileLevel( tileLevel ),
13 m_mapWidthTiles( 10 * pow( 2, m_tileLevel )),
14 m_mapHeightTiles( 5 * pow( 2, m_tileLevel )),
15 m_mapWidthPixel( m_mapWidthTiles * m_tileEdgeLengthPixel ),
16 m_mapHeightPixel( m_mapHeightTiles * m_tileEdgeLengthPixel ),
17 m_interpolationMethod(),
18 m_tileCache( DefaultCacheSizeBytes )
20 if ( !m_baseDirectory.exists() )
21 qFatal(
"Base directory '%s' does not exist.", m_baseDirectory.path().toStdString().c_str() );
23 qDebug() <<
"tileLevel:" << m_tileLevel
24 <<
"\nmapWidthTiles:" << m_mapWidthTiles
25 <<
"\nmapHeightTiles:" << m_mapHeightTiles
26 <<
"\nmapWidthPixel:" << m_mapWidthPixel
27 <<
"\nmapHeightPixel:" << m_mapHeightPixel;
32 double const x = lonRadToPixelX( lonRad );
33 double const y = latRadToPixelY( latRad );
39 int const tileX = x / m_tileEdgeLengthPixel;
40 int const tileY = y / m_tileEdgeLengthPixel;
43 int const tileKey = tileId( tileX, tileY );
44 if ( m_tileMissing.contains( tileKey ))
47 QPair<QImage, bool> potentialTile = tile( tileX, tileY );
48 if ( !potentialTile.second )
51 return potentialTile.first.pixel( x % m_tileEdgeLengthPixel,
52 m_tileEdgeLengthPixel - y % m_tileEdgeLengthPixel - 1 );
57 m_baseDirectory = baseDirectory;
62 m_tileCache.setMaxCost( cacheSizeBytes );
67 m_interpolationMethod = method;
73 m_tileLevel = tileLevel;
74 m_mapWidthTiles = 10 * pow( 2, m_tileLevel );
75 m_mapHeightTiles = 5 * pow( 2, m_tileLevel );
76 m_mapWidthPixel = m_mapWidthTiles * m_tileEdgeLengthPixel;
77 m_mapHeightPixel = m_mapHeightTiles * m_tileEdgeLengthPixel;
80 inline int NwwMapImage::tileId(
int const tileX,
int const tileY )
82 return (tileX << 16) + tileY;
85 QPair<QImage, bool> NwwMapImage::tile(
int const tileX,
int const tileY )
87 int const tileKey = tileId( tileX, tileY );
90 QImage *
const cachedTile = m_tileCache.object( tileKey );
92 return QPair<QImage, bool>( *cachedTile, true );
94 QString
const filename = QString(
"%1/%2/%2_%3.jpg")
95 .arg( m_baseDirectory.path() )
96 .arg( tileY, 4, 10, QLatin1Char(
'0'))
97 .arg( tileX, 4, 10, QLatin1Char(
'0'));
99 bool const loaded = tile.load( filename );
101 m_tileMissing.insert( tileKey );
104 m_tileCache.insert( tileKey,
new QImage( tile ), tile.byteCount() );
107 return QPair<QImage, bool>( tile, loaded );
110 inline double NwwMapImage::lonRadToPixelX(
double const lonRad )
const
112 return static_cast<double>( m_mapWidthPixel ) / ( 2.0 *
M_PI ) * lonRad
113 + 0.5 *
static_cast<double>( m_mapWidthPixel );
116 inline double NwwMapImage::latRadToPixelY(
double const latRad )
const
118 return static_cast<double>( m_mapHeightPixel ) /
M_PI * latRad
119 + 0.5 * static_cast<double>( m_mapHeightPixel );
122 QRgb NwwMapImage::nearestNeighbor(
double const x,
double const y )
124 int const xr = round( x );
125 int const yr = round( y );
126 return pixel( xr, yr );
129 QRgb NwwMapImage::bilinearInterpolation(
double const x,
double const y )
132 int const x2 = x1 + 1;
134 int const y2 = y1 + 1;
136 QRgb
const lowerLeftPixel =
pixel( x1, y1 );
137 QRgb
const lowerRightPixel =
pixel( x2, y1 );
138 QRgb
const upperLeftPixel =
pixel( x1, y2 );
139 QRgb
const upperRightPixel =
pixel( x2, y2 );
151 double const fractionX = x - x1;
152 double const lowerMidRed = ( 1.0 - fractionX ) * qRed( lowerLeftPixel ) + fractionX * qRed( lowerRightPixel );
153 double const lowerMidGreen = ( 1.0 - fractionX ) * qGreen( lowerLeftPixel ) + fractionX * qGreen( lowerRightPixel );
154 double const lowerMidBlue = ( 1.0 - fractionX ) * qBlue( lowerLeftPixel ) + fractionX * qBlue( lowerRightPixel );
155 double const lowerMidAlpha = ( 1.0 - fractionX ) * qAlpha( lowerLeftPixel ) + fractionX * qAlpha( lowerRightPixel );
157 double const upperMidRed = ( 1.0 - fractionX ) * qRed( upperLeftPixel ) + fractionX * qRed( upperRightPixel );
158 double const upperMidGreen = ( 1.0 - fractionX ) * qGreen( upperLeftPixel ) + fractionX * qGreen( upperRightPixel );
159 double const upperMidBlue = ( 1.0 - fractionX ) * qBlue( upperLeftPixel ) + fractionX * qBlue( upperRightPixel );
160 double const upperMidAlpha = ( 1.0 - fractionX ) * qAlpha( upperLeftPixel ) + fractionX * qAlpha( upperRightPixel );
172 double const fractionY = y - y1;
173 double const red = ( 1.0 - fractionY ) * lowerMidRed + fractionY * upperMidRed;
174 double const green = ( 1.0 - fractionY ) * lowerMidGreen + fractionY * upperMidGreen;
175 double const blue = ( 1.0 - fractionY ) * lowerMidBlue + fractionY * upperMidBlue;
176 double const alpha = ( 1.0 - fractionY ) * lowerMidAlpha + fractionY * upperMidAlpha;
178 return qRgba( round( red ), round( green ), round( blue ), round( alpha ));
NwwMapImage(QDir const &baseDirectory, int const tileLevel)
void setCacheSizeBytes(int const cacheSizeBytes)
void setTileLevel(int const level)
virtual QRgb interpolate(double const x, double const y)=0
virtual QRgb pixel(double const lonRad, double const latRad)
void setBaseDirectory(QDir const &baseDirectory)
void setInterpolationMethod(InterpolationMethod *const method)
void setMapImage(ReadOnlyMapImage *const mapImage)