12 m_osmTileEdgeLengthPixel( 256 ),
13 m_emptyPixel( qRgba( 0, 0, 0, 255 )),
16 m_osmMapEdgeLengthPixel(),
17 m_clusterEdgeLengthTiles(),
18 m_mapSourceDefinitions(),
26 m_clusterEdgeLengthTiles = clusterEdgeLengthTiles;
31 m_mapSourceDefinitions = mapSourceDefinitions;
36 m_osmBaseDirectory = osmBaseDirectory;
41 m_osmTileLevel = level;
42 int const osmMapEdgeLengthTiles = pow( 2, m_osmTileLevel );
43 m_osmMapEdgeLengthPixel = osmMapEdgeLengthTiles * m_osmTileEdgeLengthPixel;
44 qDebug() <<
"osmTileLevel:" << m_osmTileLevel
45 <<
"\nosmMapEdgeLengthTiles:" << osmMapEdgeLengthTiles
46 <<
"\nosmMapEdgeLengthPixel:" << m_osmMapEdgeLengthPixel;
49 QDir OsmTileClusterRenderer::checkAndCreateDirectory(
int const tileX )
const
51 QDir
const tileDirectory( m_osmBaseDirectory.path() + QString(
"/%1/%2").arg( m_osmTileLevel ).arg( tileX ));
52 if ( !tileDirectory.exists() ) {
53 bool const created = tileDirectory.mkpath( tileDirectory.path() );
56 if ( !tileDirectory.exists() )
57 qFatal(
"Unable to create directory '%s'.", tileDirectory.path().toStdString().c_str() );
65 QVector<ReadOnlyMapDefinition>::const_iterator pos = m_mapSourceDefinitions.begin();
66 QVector<ReadOnlyMapDefinition>::const_iterator
const end = m_mapSourceDefinitions.end();
67 for (; pos != end; ++pos )
71 qFatal(
"Invalid map source definition.");
72 m_mapSources.push_back( mapImage );
74 m_mapSourceCount = m_mapSources.count();
79 qDebug() << objectName() <<
"rendering clusterX:" << clusterX <<
", clusterY:" << clusterY;
80 int tilesRenderedCount = 0;
83 int const tileX1 = clusterX * m_clusterEdgeLengthTiles;
84 int const tileX2 = tileX1 + m_clusterEdgeLengthTiles;
85 int const tileY1 = clusterY * m_clusterEdgeLengthTiles;
86 int const tileY2 = tileY1 + m_clusterEdgeLengthTiles;
88 for (
int tileX = tileX1; tileX < tileX2; ++tileX ) {
89 QDir
const tileDirectory = checkAndCreateDirectory( tileX );
90 for (
int tileY = tileY1; tileY < tileY2; ++tileY ) {
91 QImage
const osmTile = renderOsmTile( tileX, tileY );
94 if ( osmTile.isNull() )
97 QString
const filename = tileDirectory.path() + QString(
"/%1.png" ).arg( tileY );
98 bool const saved = osmTile.save( filename );
100 ++tilesRenderedCount;
102 qFatal(
"Unable to save tile '%s'.", filename.toStdString().c_str() );
105 int const durationMs = t.elapsed();
106 qDebug() << objectName() <<
"clusterX:" <<clusterX <<
", clusterY:" << clusterY
107 <<
"rendered:" << tilesRenderedCount <<
"tiles in" << durationMs <<
"ms =>"
108 <<
static_cast<double>( tilesRenderedCount ) * 1000.0 / static_cast<double>( durationMs ) <<
"tiles/s";
112 QImage OsmTileClusterRenderer::renderOsmTile(
int const tileX,
int const tileY )
115 int const basePixelX = tileX * m_osmTileEdgeLengthPixel;
116 int const basePixelY = tileY * m_osmTileEdgeLengthPixel;
118 QSize
const tileSize( m_osmTileEdgeLengthPixel, m_osmTileEdgeLengthPixel );
119 QImage tile( tileSize, QImage::Format_ARGB32 );
120 bool tileEmpty =
true;
122 for (
int y = 0; y < m_osmTileEdgeLengthPixel; ++y ) {
123 int const pixelY = basePixelY + y;
124 double const latRad = osmPixelYtoLatRad( pixelY );
126 for (
int x = 0; x < m_osmTileEdgeLengthPixel; ++x ) {
127 int const pixelX = basePixelX + x;
128 double const lonRad = osmPixelXtoLonRad( pixelX );
130 QRgb color = m_emptyPixel;
131 for (
int i = 0; i < m_mapSourceCount; ++i)
133 color = m_mapSources[i]->pixel( lonRad, latRad );
134 if ( color != m_emptyPixel ) {
140 tile.setPixel( x, y, color );
143 return tileEmpty ? QImage() : tile;
146 inline double OsmTileClusterRenderer::osmPixelXtoLonRad(
int const pixelX )
const
148 double const pixelXd =
static_cast<double>( pixelX );
149 double const osmMapEdgeLengthPixeld =
static_cast<double>( m_osmMapEdgeLengthPixel );
150 return pixelXd * 2.0 *
M_PI / osmMapEdgeLengthPixeld -
M_PI;
153 inline double OsmTileClusterRenderer::osmPixelYtoLatRad(
int const pixelY )
const
155 double const pixelYd =
static_cast<double>( pixelY );
156 double const osmMapEdgeLengthPixeld =
static_cast<double>( m_osmMapEdgeLengthPixel );
157 return -atan( sinh(( pixelYd - 0.5 * osmMapEdgeLengthPixeld ) * 2.0 *
M_PI / osmMapEdgeLengthPixeld ));
160 #include "OsmTileClusterRenderer.moc"
void setOsmTileLevel(int const level)
void clusterRendered(OsmTileClusterRenderer *)
void setOsmBaseDirectory(QDir const &osmBaseDirectory)
OsmTileClusterRenderer(QObject *const parent=NULL)
void setMapSources(QVector< ReadOnlyMapDefinition > const &mapSources)
void renderOsmTileCluster(int const clusterX, int const clusterY)
void setClusterEdgeLengthTiles(int const clusterEdgeLengthTiles)