• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • tools
  • mapreproject
OsmTileClusterRenderer.cpp
Go to the documentation of this file.
1 #include "OsmTileClusterRenderer.h"
2 
3 #include "ReadOnlyMapImage.h"
4 
5 #include <QDebug>
6 #include <QTime>
7 
8 #include <cmath>
9 
10 OsmTileClusterRenderer::OsmTileClusterRenderer( QObject * const parent )
11  : QObject( parent ),
12  m_osmTileEdgeLengthPixel( 256 ),
13  m_emptyPixel( qRgba( 0, 0, 0, 255 )),
14  m_osmBaseDirectory(),
15  m_osmTileLevel(),
16  m_osmMapEdgeLengthPixel(),
17  m_clusterEdgeLengthTiles(),
18  m_mapSourceDefinitions(),
19  m_mapSources(),
20  m_mapSourceCount()
21 {
22 }
23 
24 void OsmTileClusterRenderer::setClusterEdgeLengthTiles( int const clusterEdgeLengthTiles )
25 {
26  m_clusterEdgeLengthTiles = clusterEdgeLengthTiles;
27 }
28 
29 void OsmTileClusterRenderer::setMapSources( QVector<ReadOnlyMapDefinition> const & mapSourceDefinitions )
30 {
31  m_mapSourceDefinitions = mapSourceDefinitions;
32 }
33 
34 void OsmTileClusterRenderer::setOsmBaseDirectory( QDir const & osmBaseDirectory )
35 {
36  m_osmBaseDirectory = osmBaseDirectory;
37 }
38 
39 void OsmTileClusterRenderer::setOsmTileLevel( int const level )
40 {
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;
47 }
48 
49 QDir OsmTileClusterRenderer::checkAndCreateDirectory( int const tileX ) const
50 {
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() );
54  if ( !created ) {
55  // maybe it was created in the meantime by a different thread, then it should be there now
56  if ( !tileDirectory.exists() )
57  qFatal("Unable to create directory '%s'.", tileDirectory.path().toStdString().c_str() );
58  }
59  }
60  return tileDirectory;
61 }
62 
63 void OsmTileClusterRenderer::initMapSources()
64 {
65  QVector<ReadOnlyMapDefinition>::const_iterator pos = m_mapSourceDefinitions.begin();
66  QVector<ReadOnlyMapDefinition>::const_iterator const end = m_mapSourceDefinitions.end();
67  for (; pos != end; ++pos )
68  {
69  ReadOnlyMapImage * const mapImage = (*pos).createReadOnlyMap();
70  if ( !mapImage )
71  qFatal("Invalid map source definition.");
72  m_mapSources.push_back( mapImage );
73  }
74  m_mapSourceCount = m_mapSources.count();
75 }
76 
77 void OsmTileClusterRenderer::renderOsmTileCluster( int const clusterX, int const clusterY )
78 {
79  qDebug() << objectName() << "rendering clusterX:" << clusterX << ", clusterY:" << clusterY;
80  int tilesRenderedCount = 0;
81  QTime t;
82  t.start();
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;
87 
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 );
92 
93  // hack
94  if ( osmTile.isNull() )
95  continue;
96 
97  QString const filename = tileDirectory.path() + QString( "/%1.png" ).arg( tileY );
98  bool const saved = osmTile.save( filename );
99  if ( saved )
100  ++tilesRenderedCount;
101  else
102  qFatal("Unable to save tile '%s'.", filename.toStdString().c_str() );
103  }
104  }
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";
109  emit clusterRendered( this );
110 }
111 
112 QImage OsmTileClusterRenderer::renderOsmTile( int const tileX, int const tileY )
113 {
114  //qDebug() << objectName() << "renderOsmTile tileX:" << tileX << ", tileY:" << tileY;
115  int const basePixelX = tileX * m_osmTileEdgeLengthPixel;
116  int const basePixelY = tileY * m_osmTileEdgeLengthPixel;
117 
118  QSize const tileSize( m_osmTileEdgeLengthPixel, m_osmTileEdgeLengthPixel );
119  QImage tile( tileSize, QImage::Format_ARGB32 );
120  bool tileEmpty = true;
121 
122  for ( int y = 0; y < m_osmTileEdgeLengthPixel; ++y ) {
123  int const pixelY = basePixelY + y;
124  double const latRad = osmPixelYtoLatRad( pixelY );
125 
126  for ( int x = 0; x < m_osmTileEdgeLengthPixel; ++x ) {
127  int const pixelX = basePixelX + x;
128  double const lonRad = osmPixelXtoLonRad( pixelX );
129 
130  QRgb color = m_emptyPixel;
131  for (int i = 0; i < m_mapSourceCount; ++i)
132  {
133  color = m_mapSources[i]->pixel( lonRad, latRad );
134  if ( color != m_emptyPixel ) {
135  tileEmpty = false;
136  break;
137  }
138  }
139 
140  tile.setPixel( x, y, color );
141  }
142  }
143  return tileEmpty ? QImage() : tile;
144 }
145 
146 inline double OsmTileClusterRenderer::osmPixelXtoLonRad( int const pixelX ) const
147 {
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;
151 }
152 
153 inline double OsmTileClusterRenderer::osmPixelYtoLatRad( int const pixelY ) const
154 {
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 ));
158 }
159 
160 #include "OsmTileClusterRenderer.moc"
OsmTileClusterRenderer::setOsmTileLevel
void setOsmTileLevel(int const level)
Definition: OsmTileClusterRenderer.cpp:39
ReadOnlyMapImage.h
OsmTileClusterRenderer::clusterRendered
void clusterRendered(OsmTileClusterRenderer *)
OsmTileClusterRenderer.h
OsmTileClusterRenderer::setOsmBaseDirectory
void setOsmBaseDirectory(QDir const &osmBaseDirectory)
Definition: OsmTileClusterRenderer.cpp:34
QObject
ReadOnlyMapImage
Definition: ReadOnlyMapImage.h:8
OsmTileClusterRenderer::OsmTileClusterRenderer
OsmTileClusterRenderer(QObject *const parent=NULL)
Definition: OsmTileClusterRenderer.cpp:10
OsmTileClusterRenderer::setMapSources
void setMapSources(QVector< ReadOnlyMapDefinition > const &mapSources)
Definition: OsmTileClusterRenderer.cpp:29
OsmTileClusterRenderer::renderOsmTileCluster
void renderOsmTileCluster(int const clusterX, int const clusterY)
Definition: OsmTileClusterRenderer.cpp:77
OsmTileClusterRenderer::initMapSources
void initMapSources()
Definition: OsmTileClusterRenderer.cpp:63
OsmTileClusterRenderer::setClusterEdgeLengthTiles
void setClusterEdgeLengthTiles(int const clusterEdgeLengthTiles)
Definition: OsmTileClusterRenderer.cpp:24
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal