File: main.cpp

package info (click to toggle)
marble 4%3A16.08.3-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 76,596 kB
  • ctags: 22,881
  • sloc: cpp: 177,552; xml: 39,363; ansic: 7,204; python: 2,209; sh: 1,140; makefile: 230; perl: 222; ruby: 97; java: 66
file content (116 lines) | stat: -rw-r--r-- 3,756 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//
// 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 2013      Dennis Nienhüser <nienhueser@kde.org>
// Loosely based on MarblePhysics.cpp
//

/**
  * Animated jump from a source point to a destination point, recording
  * the result to a video.
  */

#include <marble/MarbleWidget.h>
#include <marble/GeoDataCoordinates.h>
#include <marble/GeoDataLineString.h>
#include <marble/RenderPlugin.h>
#include <marble/Quaternion.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <QTimeLine>
#include <qmath.h>
#include <QApplication>

#include <cstdio>

using namespace Marble;
using namespace cv;

namespace {
    // Some stuff you might want to change

    // The map theme in use
    QString const mapTheme = "earth/mapquest-open-aerial/mapquest-open-aerial.dgml";

    // Enabled plugins. Everything else will be disabled
    QStringList const features = QStringList() << "stars" << "atmosphere";

    // Camera starting point: Position and zoom level
    GeoDataCoordinates const source(   8.40314, 49.01302, 0.0, GeoDataCoordinates::Degree);
    double const sourceZoomLevel = 11;

    // Camera destination point: Position and zoom level
    GeoDataCoordinates const destination( -101.36631, 43.13718, 0.0, GeoDataCoordinates::Degree);
    double const destinationZoomLevel = 14;

    // Minimum zoom level (in the middle of the animation)
    double const jumpZoomLevel = 5.5;

    // Length of the video
    QTimeLine timeLine( 20 * 1000 );

    // Frames per second
    int const fps = 30;

    // Target video file name
    std::string const videoFile = "marble-animated-zoom.avi";

    // Video resolution
    Size frameSize( 1280, 720 );
}

void interpolate( MarbleWidget* widget, qreal value )
{
    GeoDataCoordinates coordinates;
    qreal lon, lat;
    Quaternion::slerp( source.quaternion(), destination.quaternion(), value ).getSpherical( lon, lat );
    coordinates.setLongitude( lon );
    coordinates.setLatitude( lat );
    widget->centerOn( coordinates );
    widget->setRadius( exp(jumpZoomLevel) + (value < 0.5 ? exp(sourceZoomLevel*(1.0-2*value)) : exp(destinationZoomLevel*(2*value-1.0))) );
}

void animatedFlight( MarbleWidget *mapWidget )
{
    mapWidget->resize( frameSize.width, frameSize.height );
    VideoWriter videoWriter( videoFile, CV_FOURCC('D','I','V','X'), fps, frameSize );
    Mat buffer;
    buffer.create(frameSize, CV_8UC3);
    timeLine.setCurveShape( QTimeLine::EaseInOutCurve );
    int const frameTime = qRound( 1000.0 / fps );
    for ( int i=1; i<=timeLine.duration(); i+=frameTime ) {
        printf("[%i%% done]\r", cvRound( (100.0*i)/timeLine.duration() ) );
        fflush(stdout);
        interpolate( mapWidget, timeLine.valueForTime( i ) );
        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; i<fps; ++i ) {
        videoWriter.write( buffer ); // one second stand-still at end
    }
    printf("Wrote %s\n", videoFile.c_str());
}

int main(int argc, char** argv)
{
    QApplication app(argc,argv);
    MarbleWidget *mapWidget = new MarbleWidget;
    mapWidget->setMapThemeId(mapTheme);
    foreach( RenderPlugin* plugin, mapWidget->renderPlugins() ) {
        if ( !features.contains( plugin->nameId() ) ) {
            plugin->setEnabled( false );
        }
    }

    animatedFlight( mapWidget );
    return 0;
}