diff --git a/examples/cpp/tour-preview/tour-preview.cpp b/examples/cpp/tour-preview/tour-preview.cpp index ae45c6f3b..fa09ac481 100644 --- a/examples/cpp/tour-preview/tour-preview.cpp +++ b/examples/cpp/tour-preview/tour-preview.cpp @@ -1,165 +1,165 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2014 Dennis Nienhüser // /** * Does an animated camera flight using a given route loaded from * a .kml file and writes an .avi (DIVX) video of it. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Marble; using namespace cv; class Waiter: private QThread { public: using QThread::msleep; }; namespace { // Some stuff you might want to change // The map theme in use QString const mapTheme = "earth/openstreetmap/openstreetmap.dgml"; // Enabled plugins. Everything else will be disabled QStringList const features = QStringList() << "stars" << "atmosphere"; // Frames per second int const fps = 30; // Target video file name std::string const videoFile = "marble-tour-preview.avi"; // Video resolution Size frameSize( 1280, 720 ); // Camera velocity in km/h double const velocity = 200.0; } GeoDataTour* createTour( const Route &route ) { GeoDataTour* tour = new GeoDataTour; tour->setPlaylist( new GeoDataPlaylist ); GeoDataLineString path = route.path(); if ( path.size() < 1 ) { return tour; } // Extract tour points at about all 500 meters GeoDataCoordinates last = path.at( 0 ); for ( int i=1; i 1 && distance < 500 ) { // Ignore waypoints that are quite close continue; } last = coordinates; // Create a point in the tour from the given route point GeoDataLookAt* lookat = new GeoDataLookAt; coordinates.setAltitude( 800 ); lookat->setCoordinates( coordinates ); lookat->setRange( 800 ); GeoDataFlyTo* flyto = new GeoDataFlyTo; double const duration = qBound( 0.2, distance / velocity / 3.6, 10.0 ); flyto->setDuration( duration ); flyto->setView( lookat ); flyto->setFlyToMode( GeoDataFlyTo::Smooth ); tour->playlist()->addPrimitive( flyto ); } return tour; } void animatedFlight( MarbleWidget *mapWidget, GeoDataTour* tour ) { mapWidget->resize( frameSize.width, frameSize.height ); TourPlayback* playback = new TourPlayback; playback->setMarbleWidget( mapWidget ); playback->setTour( tour ); QObject::connect( playback, SIGNAL(centerOn(GeoDataCoordinates)), mapWidget, SLOT(centerOn(GeoDataCoordinates)) ); double const shift = 1.0 / fps; double const duration = playback->duration(); VideoWriter videoWriter( videoFile, CV_FOURCC('D','I','V','X'), fps, frameSize ); Mat buffer; buffer.create(frameSize, CV_8UC3); for ( double position = 0.0; position <= duration; position += shift ) { printf("[%i%% done]\r", cvRound( (100.0*position)/duration ) ); fflush(stdout); playback->seek( position ); QImage screenshot = QPixmap::grabWidget( mapWidget ).toImage().convertToFormat( QImage::Format_RGB888 ); Mat converter( frameSize, CV_8UC3 ); converter.data = screenshot.bits(); cvtColor( converter, buffer, CV_RGB2BGR ); videoWriter.write( buffer ); } for ( int i=0; isetMapThemeId(mapTheme); foreach( RenderPlugin* plugin, mapWidget->renderPlugins() ) { if ( !features.contains( plugin->nameId() ) ) { plugin->setEnabled( false ); } } mapWidget->model()->routingManager()->loadRoute(argv[1]); Route const route = mapWidget->model()->routingManager()->routingModel()->route(); if ( route.size() == 0 ) { qDebug() << "Failed to open route " << argv[1]; return 1; } GeoDataCoordinates start = route.path().at( 0 ); start.setLongitude( start.longitude() + 1e-6 ); mapWidget->centerOn( start ); mapWidget->setDistance( 0.8 ); animatedFlight( mapWidget, createTour( route ) ); return 0; }