File indexing completed on 2024-03-24 15:23:33

0001 #include "NasaWorldWindToOpenStreetMapConverter.h"
0002 
0003 #include "OsmTileClusterRenderer.h"
0004 #include "Thread.h"
0005 
0006 #include <QDebug>
0007 #include <QMetaObject>
0008 #include <QString>
0009 #include <QThread>
0010 
0011 #include <cmath>
0012 
0013 NasaWorldWindToOpenStreetMapConverter::NasaWorldWindToOpenStreetMapConverter( QObject * const parent )
0014     : QObject( parent ),
0015       m_threadCount(),
0016       m_osmTileLevel(),
0017       m_osmTileClusterEdgeLengthTiles(),
0018       m_osmMapEdgeLengthClusters(),
0019       m_nextClusterX(),
0020       m_nextClusterY()
0021 {
0022 }
0023 
0024 void NasaWorldWindToOpenStreetMapConverter::setMapSources( QVector<ReadOnlyMapDefinition> const & mapSources )
0025 {
0026     m_mapSources = mapSources;
0027 }
0028 
0029 void NasaWorldWindToOpenStreetMapConverter::setOsmBaseDirectory( QDir const & osmBaseDirectory )
0030 {
0031     if ( !osmBaseDirectory.exists() ) {
0032         qDebug() << "Destination path " << osmBaseDirectory << "does not exist, creating.";
0033         osmBaseDirectory.mkpath( osmBaseDirectory.path() );
0034     }
0035     m_osmBaseDirectory = osmBaseDirectory;
0036 }
0037 
0038 void NasaWorldWindToOpenStreetMapConverter::setOsmTileClusterEdgeLengthTiles( int const clusterEdgeLengthTiles )
0039 {
0040     m_osmTileClusterEdgeLengthTiles = clusterEdgeLengthTiles;
0041 }
0042 
0043 void NasaWorldWindToOpenStreetMapConverter::setOsmTileLevel( int const level )
0044 {
0045     m_osmTileLevel = level;
0046 }
0047 
0048 void NasaWorldWindToOpenStreetMapConverter::setThreadCount(const int threadCount)
0049 {
0050     m_threadCount = threadCount;
0051 }
0052 
0053 QVector<QPair<Thread*, OsmTileClusterRenderer*> > NasaWorldWindToOpenStreetMapConverter::start()
0054 {
0055     // create directory for osm tile level if necessary
0056 
0057     // render Osm tiles using quadratic clusters of tiles instead of stripes
0058     // to increase Nww tile cache usage
0059     int const osmMapEdgeLengthTiles = pow( 2, m_osmTileLevel );
0060     m_osmMapEdgeLengthClusters = osmMapEdgeLengthTiles / m_osmTileClusterEdgeLengthTiles;
0061     if ( osmMapEdgeLengthTiles % m_osmTileClusterEdgeLengthTiles != 0 )
0062         qFatal("Bad tile cluster size");
0063 
0064     QVector<QPair<Thread*, OsmTileClusterRenderer*> > renderThreads;
0065 
0066     for ( int i = 0; i < m_threadCount; ++i ) {
0067         OsmTileClusterRenderer * const renderer = new OsmTileClusterRenderer;
0068         renderer->setObjectName( QString("Renderer %1").arg( i ));
0069         renderer->setClusterEdgeLengthTiles( m_osmTileClusterEdgeLengthTiles );
0070         renderer->setMapSources( m_mapSources );
0071         renderer->setOsmBaseDirectory( m_osmBaseDirectory );
0072         renderer->setOsmTileLevel( m_osmTileLevel );
0073         QObject::connect( renderer, SIGNAL(clusterRendered(OsmTileClusterRenderer*)),
0074                           this, SLOT(assignNextCluster(OsmTileClusterRenderer*)) );
0075 
0076         Thread * const thread = new Thread;
0077         thread->launchWorker( renderer );
0078         QMetaObject::invokeMethod( renderer, "initMapSources", Qt::QueuedConnection );
0079         QMetaObject::invokeMethod( renderer, "renderOsmTileCluster", Qt::QueuedConnection,
0080                                    Q_ARG( int, m_nextClusterX ), Q_ARG( int, m_nextClusterY ));
0081         incNextCluster();
0082         renderThreads.push_back( qMakePair( thread, renderer ));
0083     }
0084     return renderThreads;
0085 }
0086 
0087 void NasaWorldWindToOpenStreetMapConverter::testReprojection()
0088 {
0089 //    qDebug() << "\nTesting osm pixel x -> lon[rad]";
0090 //    qDebug() << 0 << "->" << osmPixelXtoLonRad( 0 );
0091 //    qDebug() << m_osmMapEdgeLengthPixel / 4 << "->" << osmPixelXtoLonRad( m_osmMapEdgeLengthPixel / 4 );
0092 //    qDebug() << m_osmMapEdgeLengthPixel / 2 << "->" << osmPixelXtoLonRad( m_osmMapEdgeLengthPixel / 2 );
0093 //    qDebug() << m_osmMapEdgeLengthPixel / 4 * 3 << "->" << osmPixelXtoLonRad( m_osmMapEdgeLengthPixel / 4 * 3 );
0094 //    qDebug() << m_osmMapEdgeLengthPixel << "->" << osmPixelXtoLonRad( m_osmMapEdgeLengthPixel );
0095 
0096 //    qDebug() << "\nTesting osm pixel y -> lat[rad]";
0097 //    qDebug() << 0 << "->" << osmPixelYtoLatRad( 0 );
0098 //    qDebug() << m_osmMapEdgeLengthPixel / 4 << "->" << osmPixelYtoLatRad( m_osmMapEdgeLengthPixel / 4 );
0099 //    qDebug() << m_osmMapEdgeLengthPixel / 2 << "->" << osmPixelYtoLatRad( m_osmMapEdgeLengthPixel / 2 );
0100 //    qDebug() << m_osmMapEdgeLengthPixel / 4 * 3 << "->" << osmPixelYtoLatRad( m_osmMapEdgeLengthPixel / 4 * 3 );
0101 //    qDebug() << m_osmMapEdgeLengthPixel << "->" << osmPixelYtoLatRad( m_osmMapEdgeLengthPixel );
0102 
0103 //    qDebug() << "\nTesting lon[rad] -> nww pixel x";
0104 //    qDebug() <<       -M_PI << "->" << lonRadToNwwPixelX( -M_PI );
0105 //    qDebug() << -M_PI / 2.0 << "->" << lonRadToNwwPixelX( -M_PI / 2.0 );
0106 //    qDebug() <<           0 << "->" << lonRadToNwwPixelX(     0 );
0107 //    qDebug() <<  M_PI / 2.0 << "->" << lonRadToNwwPixelX(  M_PI / 2.0 );
0108 //    qDebug() <<        M_PI << "->" << lonRadToNwwPixelX(  M_PI );
0109 
0110 //    qDebug() << "\nTesting lat[rad] -> nww pixel y";
0111 //    qDebug() <<  M_PI / 2.0 << "->" << latRadToNwwPixelY(  M_PI / 2.0 );
0112 //    qDebug() <<           0 << "->" << latRadToNwwPixelY(     0 );
0113 //    qDebug() << -M_PI / 2.0 << "->" << latRadToNwwPixelY( -M_PI / 2.0 );
0114 }
0115 
0116 void NasaWorldWindToOpenStreetMapConverter::assignNextCluster( OsmTileClusterRenderer * renderer )
0117 {
0118     if ( m_nextClusterX == m_osmMapEdgeLengthClusters || m_nextClusterY == m_osmMapEdgeLengthClusters )
0119         return;
0120 
0121     QMetaObject::invokeMethod( renderer, "renderOsmTileCluster", Qt::QueuedConnection,
0122                                Q_ARG( int, m_nextClusterX ), Q_ARG( int, m_nextClusterY ));
0123     incNextCluster();
0124 }
0125 
0126 void NasaWorldWindToOpenStreetMapConverter::checkAndCreateLevelDirectory() const
0127 {
0128     QDir const levelDirectory( m_osmBaseDirectory.path() + QString("/%1").arg( m_osmTileLevel ));
0129     if ( !levelDirectory.exists() ) {
0130         bool const created = levelDirectory.mkpath( levelDirectory.path() );
0131         if ( !created ) {
0132             // maybe it was created in the meantime by something else
0133             if ( !levelDirectory.exists() )
0134                 qFatal("Unable to create directory '%s'.", levelDirectory.path().toStdString().c_str());
0135         }
0136     }
0137 }
0138 
0139 void NasaWorldWindToOpenStreetMapConverter::incNextCluster()
0140 {
0141     ++m_nextClusterY;
0142     if ( m_nextClusterY == m_osmMapEdgeLengthClusters ) {
0143         m_nextClusterY = 0;
0144         ++m_nextClusterX;
0145         if ( m_nextClusterX == m_osmMapEdgeLengthClusters )
0146             emit finished();
0147     }
0148 }
0149 
0150 #include "moc_NasaWorldWindToOpenStreetMapConverter.cpp"