示例#1
0
void FoursquareModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number )
{
    if( marbleModel()->planetId() != "earth" ) {
        return;
    }
    
    QString clientId = "YPRWSYFW1RVL4PJQ2XS5G14RTOGTHOKZVHC1EP5KCCCYQPZF";
    QString clientSecret = "5L2JDCAYQCEJWY5FNDU4A1RWATE4E5FIIXXRM41YBTFSERUH";
    
    QString apiUrl( "https://api.foursquare.com/v2/venues/search" );
    qreal const distanceLon = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.east(), box.north() );
    qreal const distanceLat = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.west(), box.south() );
    qreal const area = distanceLon * distanceLat;
    if ( area > 10 * 1000 * KM2METER * KM2METER ) {
        // Large area (> 10.000 km^2) => too large for bbox queries
        apiUrl += "?ll=" + QString::number( box.center().latitude(Marble::GeoDataCoordinates::Degree) );
        apiUrl += ',' + QString::number( box.center().longitude(Marble::GeoDataCoordinates::Degree) );
        apiUrl += "&intent=checkin";
    } else {
        apiUrl += "?ne=" + QString::number( box.north(Marble::GeoDataCoordinates::Degree) );
        apiUrl += ',' + QString::number( box.east(Marble::GeoDataCoordinates::Degree) );
        apiUrl += "&sw=" + QString::number( box.south(Marble::GeoDataCoordinates::Degree) );
        apiUrl += ',' + QString::number( box.west(Marble::GeoDataCoordinates::Degree) );
        apiUrl += "&intent=browse";
    }
    apiUrl += "&limit=" + QString::number( number );
    apiUrl += "&client_id=" + clientId;
    apiUrl += "&client_secret=" + clientSecret;
    apiUrl += "&v=20120601";
    downloadDescriptionFile( QUrl( apiUrl ) );
}
示例#2
0
void SatellitesPlugin::initialize()
{
    // FIXME: remove the const_cast, it may be best to create a new type of
    // plugins where marbleModel() is not const, since traditional
    // RenderPlugins do not require that
    m_satModel = new SatellitesModel(
        const_cast<MarbleModel *>( marbleModel() )->treeModel(),
        marbleModel()->clock() );

    m_configModel = new SatellitesConfigModel( this );
    m_configDialog->configWidget()->treeView->setModel( m_configModel );

    connect( m_satModel, SIGNAL(fileParsed(QString)),
        SLOT(dataSourceParsed(QString)) );
    connect( m_satModel, SIGNAL(fileParsed(QString)),
        SLOT(updateDataSourceConfig(QString)) );
    connect( m_configDialog, SIGNAL(dataSourcesReloadRequested()),
        SLOT(updateSettings()) );
    connect( m_configDialog, SIGNAL(accepted()), SLOT(writeSettings()) );
    connect( m_configDialog, SIGNAL(rejected()), SLOT(readSettings()) );
    connect( m_configDialog->configWidget()->buttonBox->button(
        QDialogButtonBox::Reset ),
        SIGNAL(clicked()), SLOT(restoreDefaultSettings()) );
    connect( m_configDialog, SIGNAL(userDataSourcesChanged()),
        SLOT(writeSettings()) );
    connect( m_configDialog, SIGNAL(userDataSourceAdded(QString)),
        SLOT(userDataSourceAdded(QString)) );

    m_isInitialized = true;
    readSettings();
    updateSettings();
    enableModel( enabled() );
}
示例#3
0
void License::updateLicenseText()
{
    const GeoSceneDocument *const mapTheme = marbleModel()->mapTheme();
    if ( !mapTheme )
        return;

    const GeoSceneHead *const head = mapTheme->head();
    if ( !head )
        return;

    const GeoSceneLicense *license = marbleModel()->mapTheme()->head()->license();
    m_label->setText( m_showFullLicense ? license->license() : license->shortLicense() );
    m_label->setToolTip( license->license() );
    if( license->attribution() == GeoSceneLicense::Always ) {
        setUserCheckable( false );
    } else if( license->attribution() == GeoSceneLicense::Never ) {
        setVisible( false );
        setUserCheckable( false );
    } else if( license->attribution() == GeoSceneLicense::OptIn ) {
        setUserCheckable( true );
        setVisible( false );
    } else {
        setUserCheckable( true );
        setVisible( true );
    }
    QSizeF const magic( 6,0 );
    m_widgetItem->setSize( m_label->sizeHint()+magic );
    setSize( m_label->sizeHint()+magic );
    update();
    emit repaintNeeded();
}
示例#4
0
void RoutingPlugin::initialize()
{
    QWidget *widget = new QWidget;
    d->m_widget.setupUi( widget );
    d->m_widgetItem = new WidgetGraphicsItem( this );
    d->m_widgetItem->setWidget( widget );

    PositionProviderPlugin* activePlugin = marbleModel()->positionTracking()->positionProviderPlugin();
    d->updateGpsButton( activePlugin );
    connect( marbleModel()->positionTracking(),
             SIGNAL(positionProviderPluginChanged(PositionProviderPlugin*)),
             this, SLOT(updateGpsButton(PositionProviderPlugin*)) );

    d->m_widget.routingButton->setEnabled( false );
    connect( d->m_widget.instructionLabel, SIGNAL(linkActivated(QString)),
             this, SLOT(reverseRoute()) );

#if QT_VERSION < 0x050000
    bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
    if ( smallScreen ) {
        /** @todo: The maemo styling of the progressbar adds a black background and some frame
          * which are even painted when no background painting is requested like WidgetItem does.
          * This looks really bad on a float item. Using a different style here, but that is only
          * a workaround.
          */
        d->m_widget.progressBar->setStyle( new QPlastiqueStyle );
    }
#endif

    MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
    layout->addItem( d->m_widgetItem, 0, 0 );
    setLayout( layout );
    d->updateButtonVisibility();
}
示例#5
0
void PositionMarker::initialize()
{
    if ( marbleModel() ) {
        connect( marbleModel()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
                this, SLOT(setPosition(GeoDataCoordinates)) );
        m_isInitialized = true;
    }
    loadDefaultCursor();
}
void OpenCachingComPlugin::initialize()
{
    OpenCachingComModel *model = new OpenCachingComModel( marbleModel(), this );
    setModel( model );
    setNumberOfItems( numberOfItemsOnScreen );
    m_isInitialized = true;
}
示例#7
0
void OpenCachingComModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number )
{
    if( marbleModel()->planetId() != "earth" )
    {
        return;
    }

    if ( m_previousbox.contains( box ) )
    {
        return;
    }

    QString url("http://www.opencaching.com/api/geocache/?Authorization=");
    url += AUTHKEY + QString("&bbox=%1,%2,%3,%4")
        .arg( box.south( GeoDataCoordinates::Degree ) )
        .arg( box.west(GeoDataCoordinates::Degree ) )
        .arg( box.north(GeoDataCoordinates::Degree ) )
        .arg( box.east(GeoDataCoordinates::Degree ) );
    if(!m_previousbox.isNull())
    {
        url += QString("&exclude_bbox=%1,%2,%3,%4")
            .arg( m_previousbox.south( GeoDataCoordinates::Degree ) )
            .arg( m_previousbox.west(GeoDataCoordinates::Degree ) )
            .arg( m_previousbox.north(GeoDataCoordinates::Degree ) )
            .arg( m_previousbox.east(GeoDataCoordinates::Degree ) );
    }
    url += "&limit=" + QString::number( number );
    // TODO Limit to user set tags/types/difficulty - when there is a config dialog...

    m_previousbox = box;

//     qDebug()<<"Fetching more caches: "<<url;
    downloadDescriptionFile( QUrl( url ) );
}
示例#8
0
void OpenCachingComModel::updateHome()
{
    qreal lon, lat;
    int zoom;
    marbleModel()->home( lon, lat, zoom );
    m_homeCoordinates = GeoDataCoordinates(lon, lat, 0, GeoDataCoordinates::Degree);
}
示例#9
0
void GpsInfo::updateLocation( GeoDataCoordinates coordinates, qreal)
{
    PositionTracking *tracking = marbleModel()->positionTracking();
    qreal speed = tracking->speed();
    qreal direction = tracking->direction();
    qreal altitude = coordinates.altitude();
    qreal precision = tracking->accuracy().horizontal;
    QString speedString;
    QString distanceString;

    switch ( m_locale->measurementSystem() ) {
    case MarbleLocale::ImperialSystem:
        //miles per hour
        speedString = tr("mph");
        speed *= HOUR2SEC * METER2KM * KM2MI;
        distanceString = tr("ft");
        altitude *= M2FT;
        precision *= M2FT;
        break;

    case MarbleLocale::MetricSystem:
        //kilometers per hour
        speedString = tr("km/h");
        speed *= HOUR2SEC * METER2KM;
        distanceString = tr("m");
        break;

    case MarbleLocale::NauticalSystem:
        // nm per hour (knots)
        speedString = tr("kt");
        speed *= HOUR2SEC * METER2KM * KM2NM;
        distanceString = tr("nm");
        break;
    }

    m_widget.SpeedValue->setText( QString( " %1 %2" )
                                 .arg( QLocale().toString(speed, 'f', 1 ) )
                                 .arg( speedString ) );
    m_widget.AltitudeValue->setText( QString( " %1 %2" )
                                    .arg( QLocale().toString(altitude, 'f', 1 ) )
                                    .arg( distanceString ) );
    m_widget.DirectionValue->setText( QString( " %1 %2" )
                                     .arg( QLocale().toString(direction, 'f', 1 ) )
                                     .arg( "d" ) );
    m_widget.PrecisionValue->setText( QString( " %1 %2" )
                                     .arg( QLocale().toString(precision, 'f', 1 ) )
                                     .arg( distanceString ) );

    int const minimumWidth = m_widgetItem->widget()->sizeHint().width();
    if ( size().width() < minimumWidth ) {
        m_widgetItem->setSize( QSizeF( minimumWidth, size().height() ) );
    }

    update();
    emit repaintNeeded();
}
示例#10
0
void EarthquakePlugin::setSettings( const QHash<QString,QVariant> &settings )
{
    AbstractDataPlugin::setSettings( settings );

    setNumberOfItems( settings.value( "numResults", 20 ).toInt() );
    m_minMagnitude = settings.value( "minMagnitude", 0.0 ).toReal();
    m_startDate = settings.value( "startDate", QDateTime::fromString( "2006-02-04", "yyyy-MM-dd" ) ).toDateTime();
    m_endDate = settings.value( "endDate", marbleModel()->clockDateTime() ).toDateTime();
    m_maximumNumberOfItems = settings.value( "maximumNumberOfItems", m_maximumNumberOfItems ).toInt();

    emit settingsChanged( nameId() );
}
示例#11
0
void RoutingPlugin::initialize()
{
    QWidget *widget = new QWidget;
    d->m_widget.setupUi( widget );
    d->m_widgetItem = new WidgetGraphicsItem( this );
    d->m_widgetItem->setWidget( widget );

    PositionProviderPlugin* activePlugin = marbleModel()->positionTracking()->positionProviderPlugin();
    d->updateGpsButton( activePlugin );
    connect( marbleModel()->positionTracking(),
             SIGNAL(positionProviderPluginChanged(PositionProviderPlugin*)),
             this, SLOT(updateGpsButton(PositionProviderPlugin*)) );

    d->m_widget.routingButton->setEnabled( false );
    connect( d->m_widget.instructionLabel, SIGNAL(linkActivated(QString)),
             this, SLOT(reverseRoute()) );

    MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
    layout->addItem( d->m_widgetItem, 0, 0 );
    setLayout( layout );
    d->updateButtonVisibility();
}
void RouteSimulationPositionProviderPlugin::initialize()
{
    m_currentIndex = -1;

    m_lineString.clear();

    GeoDataDocument* document = const_cast<MarbleModel *>( marbleModel() )->routingManager()->alternativeRoutesModel()->currentRoute();
    if ( document && document->size() > 0 ) {
        foreach( const GeoDataPlacemark *placemark, document->placemarkList() ) {
            GeoDataGeometry* geometry = placemark->geometry();
            GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( geometry );
            if ( lineString ) {
                m_lineString << *lineString;
            }
        }
    }
示例#13
0
void License::initialize ()
{
    delete m_widgetItem;
    m_widgetItem = new WidgetGraphicsItem( this );
    m_label = new QLabel;
    m_label->setStyle( new OutlinedStyle );
    m_label->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
    m_widgetItem->setWidget( m_label );

    MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
    layout->addItem( m_widgetItem, 0, 0 );
    setLayout( layout );
    setPadding( 0 );

    updateLicenseText();
    connect( marbleModel(), SIGNAL(themeChanged(QString)), this, SLOT(updateLicenseText()) );
}
示例#14
0
void EarthquakeModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number )
{
    if (marbleModel()->planetId() != QLatin1String("earth")) {
        return;
    }

    const QString geonamesUrl( QLatin1String("http://ws.geonames.org/earthquakesJSON") +
        QLatin1String("?north=")   + QString::number(box.north() * RAD2DEG) +
        QLatin1String("&south=")   + QString::number(box.south() * RAD2DEG) +
        QLatin1String("&east=")    + QString::number(box.east() * RAD2DEG) +
        QLatin1String("&west=")    + QString::number(box.west() * RAD2DEG) +
        QLatin1String("&date=")    + m_endDate.toString("yyyy-MM-dd") +
        QLatin1String("&maxRows=") + QString::number(number) +
        QLatin1String("&username=marble") +
        QLatin1String("&formatted=true"));
    downloadDescriptionFile( QUrl( geonamesUrl ) );
}
示例#15
0
void Speedometer::initialize ()
{
    if ( !m_widgetItem ) {
        QWidget *widget = new QWidget;
        m_widget.setupUi( widget );
        m_widgetItem = new WidgetGraphicsItem( this );
        m_widgetItem->setWidget( widget );

        MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
        layout->addItem( m_widgetItem, 0, 0 );
        setLayout( layout );
        setPadding( 0 );

        m_locale = MarbleGlobal::getInstance()->locale();
        connect( marbleModel()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
                this, SLOT(updateLocation(GeoDataCoordinates,qreal)) );
    }
}
示例#16
0
void ProgressFloatItem::initialize()
{
    const HttpDownloadManager* manager = marbleModel()->downloadManager();
    Q_ASSERT( manager );
    connect( manager, SIGNAL(progressChanged(int,int)), this, SLOT(handleProgress(int,int)) , Qt::UniqueConnection );
    connect( manager, SIGNAL(jobRemoved()), this, SLOT(removeProgressItem()), Qt::UniqueConnection );

    // Calculate font size
    QFont myFont = font();
    const QString text = "100%";
    int fontSize = myFont.pointSize();
    while( QFontMetrics( myFont ).boundingRect( text ).width() < contentRect().width() - 2 ) {
        ++fontSize;
        myFont.setPointSize( fontSize );
    }
    m_fontSize = fontSize - 1;

    m_isInitialized = true;
}
示例#17
0
void ControlView::openGeoUri( const QString& geoUriString )
{
    GeoUriParser uriParser( geoUriString );
    if ( uriParser.parse() ) {
        if ( uriParser.planet().id() != marbleModel()->planet()->id() ) {
            MapThemeManager *manager = mapThemeManager();
            foreach( const QString& planetName, manager->mapThemeIds()) {
                if ( planetName.startsWith(uriParser.planet().id(), Qt::CaseInsensitive)) {
                    m_marbleWidget->setMapThemeId(planetName);
                    break;
                }
            }
        }
        m_marbleWidget->centerOn( uriParser.coordinates() );
        if ( uriParser.coordinates().altitude() > 0.0 )
        {
            m_marbleWidget->setDistance( uriParser.coordinates().altitude() * METER2KM );
        }
    }
示例#18
0
bool MeasureToolPlugin::render( GeoPainter *painter,
                          ViewportParams *viewport,
                          const QString& renderPos,
                          GeoSceneLayer * layer )
{
    Q_UNUSED(renderPos)
    Q_UNUSED(layer)

    m_latLonAltBox = viewport->viewLatLonAltBox();

    // No way to paint anything if the list is empty.
    if ( m_measureLineString.isEmpty() )
        return true;

    painter->save();

    // Prepare for painting the measure line string and paint it.
    painter->setPen( m_pen );

    if ( m_showDistanceLabel || m_showBearingLabel || m_showBearingChangeLabel ) {
        drawSegments( painter );
    } else {
        painter->drawPolyline( m_measureLineString );
    }

    // Paint the nodes of the paths.
    drawMeasurePoints( painter );

    m_totalDistance = m_measureLineString.length( marbleModel()->planet()->radius() );

    if ( m_measureLineString.size() > 1 )
        drawInfobox(painter);

    painter->restore();

    return true;
}
示例#19
0
void EarthquakePlugin::initialize()
{
    EarthquakeModel *model = new EarthquakeModel( marbleModel(), this );
    setModel( model );
    setNumberOfItems( 20 );
}
bool ElevationProfileFloatItem::eventFilter( QObject *object, QEvent *e )
{
    if ( !enabled() || !visible() ) {
        return false;
    }

    MarbleWidget *widget = dynamic_cast<MarbleWidget*>( object );
    if ( !widget ) {
        return AbstractFloatItem::eventFilter(object,e);
    }

    if ( widget && !m_marbleWidget ) {
        m_marbleWidget = widget;
        connect( this, SIGNAL(dataUpdated()), this, SLOT(updateVisiblePoints()) );
        connect( m_marbleWidget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
                 this, SLOT(updateVisiblePoints()) );
        connect( this, SIGNAL(settingsChanged(QString)), this, SLOT(updateVisiblePoints()) );
    }

    if ( e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove ) {
        GeoDataTreeModel *const treeModel = const_cast<MarbleModel *>( marbleModel() )->treeModel();

        QMouseEvent *event = static_cast<QMouseEvent*>( e  );
        QRectF plotRect = QRectF ( m_leftGraphMargin, 0, m_eleGraphWidth, contentSize().height() );
        plotRect.translate( positivePosition() );
        plotRect.translate( padding(), padding() );

        // for antialiasing: increase size by 1 px to each side
        plotRect.translate(-1, -1);
        plotRect.setSize(plotRect.size() + QSize(2, 2) );

        const bool cursorAboveFloatItem = plotRect.contains(event->pos());

        if ( cursorAboveFloatItem ) {
            const int start = m_zoomToViewport ? m_firstVisiblePoint : 0;
            const int end = m_zoomToViewport ? m_lastVisiblePoint : m_eleData.size();

            // Double click triggers recentering the map at the specified position
            if ( e->type() == QEvent::MouseButtonDblClick ) {
                const QPointF mousePosition = event->pos() - plotRect.topLeft();
                const int xPos = mousePosition.x();
                for ( int i = start; i < end; ++i) {
                    const int plotPos = ( m_eleData.value(i).x() - m_axisX.minValue() ) * m_eleGraphWidth / m_axisX.range();
                    if ( plotPos >= xPos ) {
                        widget->centerOn( m_points[i], true );
                        break;
                    }
                }
                return true;
            }

            if ( e->type() == QEvent::MouseMove && !(event->buttons() & Qt::LeftButton) ) {
                // Cross hair cursor when moving above the float item
                // and mark the position on the graph
                widget->setCursor(QCursor(Qt::CrossCursor));
                if ( m_cursorPositionX != event->pos().x() - plotRect.left() ) {
                    m_cursorPositionX = event->pos().x() - plotRect.left();
                    const qreal xpos = m_axisX.minValue() + ( m_cursorPositionX / m_eleGraphWidth ) * m_axisX.range();
                    GeoDataCoordinates currentPoint; // invalid coordinates
                    for ( int i = start; i < end; ++i) {
                        if ( m_eleData.value(i).x() >= xpos ) {
                            currentPoint = m_points[i];
                            currentPoint.setAltitude( m_eleData.value(i).y() );
                            break;
                        }
                    }
                    m_markerPlacemark->setCoordinate( currentPoint );
                    if ( m_documentIndex < 0 ) {
                        m_documentIndex = treeModel->addDocument( &m_markerDocument );
                    }
                    emit repaintNeeded();
                }

                return true;
            }
        }
        else {
            if ( m_documentIndex >= 0 ) {
                m_markerPlacemark->setCoordinate( GeoDataCoordinates() ); // set to invalid
                treeModel->removeDocument( &m_markerDocument );
                m_documentIndex = -1;
                emit repaintNeeded();
            }
        }
    }

    return AbstractFloatItem::eventFilter(object,e);
}
示例#21
0
}

bool PositionMarker::isInitialized() const
{
    return m_isInitialized;
}

bool PositionMarker::render( GeoPainter *painter,
                           ViewportParams *viewport,
                           const QString& renderPos,
                           GeoSceneLayer * layer )
{
    Q_UNUSED( renderPos )
    Q_UNUSED( layer )

    bool const gpsActive = marbleModel()->positionTracking()->positionProviderPlugin() != 0;
    if ( gpsActive ) {
        m_lastBoundingBox = viewport->viewLatLonAltBox();

        if( m_currentPosition != m_previousPosition ) {
            qreal screenPositionX, screenPositionY;
            viewport->screenCoordinates( m_currentPosition, screenPositionX, screenPositionY );
            const GeoDataCoordinates top( m_currentPosition.longitude(), m_currentPosition.latitude()+0.1 );
            qreal screenTopX, screenTopY;
            viewport->screenCoordinates( top, screenTopX, screenTopY );
            qreal const correction = -90.0 + RAD2DEG * atan2( screenPositionY -screenTopY, screenPositionX - screenTopX );
            const qreal rotation = m_heading + correction;

            if ( m_useCustomCursor ) {
                QTransform transform;
                transform.rotate( rotation );
示例#22
0
void MeasureToolPlugin::drawSegments( GeoPainter* painter )
{
    for ( int segmentIndex = 0; segmentIndex < m_measureLineString.size() - 1; ++segmentIndex ) {
        GeoDataLineString segment( Tessellate );
        segment << m_measureLineString[segmentIndex] ;
        segment << m_measureLineString[segmentIndex + 1];

        QPen shadowPen( Oxygen::aluminumGray5 );
        shadowPen.setWidthF(4.0);
        painter->setPen( shadowPen );
        painter->drawPolyline( segment );

        QString infoString;

        if ( (m_paintMode == Polygon && m_showDistanceLabel)
             || (m_paintMode == Circular && m_showRadius) ) {
            const qreal segmentLength = segment.length( marbleModel()->planet()->radius() );
            m_radius = segmentLength;

            infoString = meterToPreferredUnit(segmentLength);
        }

        if ( m_showBearingLabel && m_paintMode != Circular ) {
            GeoDataCoordinates coordinates = segment.first();
            qreal bearing = coordinates.bearing( segment.last(), GeoDataCoordinates::Degree );

            if ( bearing < 0 ) {
                bearing += 360;
            }
            QString bearingString = QString::fromUtf8( "%1°" ).arg( bearing, 0, 'f', 2 );
            if ( !infoString.isEmpty() ) {
                infoString.append( "\n" );
            }
            infoString.append( bearingString );
        }

        if ( m_showBearingChangeLabel && segmentIndex != 0 ) {
            GeoDataCoordinates currentCoordinates = m_measureLineString[segmentIndex];
            qreal currentBearing = currentCoordinates.bearing(m_measureLineString[segmentIndex+1]);
            qreal previousBearing = currentCoordinates.bearing( m_measureLineString[segmentIndex-1]);

            GeoDataLinearRing ring;
            painter->setPen( Qt::NoPen );
            painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );

            if (currentBearing < previousBearing) currentBearing += 2 * M_PI;
            ring << currentCoordinates;

            qreal angleLength = qAbs(m_latLonAltBox.north() - m_latLonAltBox.south()) / 20;

            qreal iterBearing = previousBearing;
            while ( iterBearing < currentBearing ) {
                ring << currentCoordinates.moveByBearing( iterBearing, angleLength );;
                iterBearing += 0.1;
            }

            ring << currentCoordinates.moveByBearing( currentBearing, angleLength );;

            painter->drawPolygon( ring );

            qreal currentBearingChange = (currentBearing - previousBearing) * RAD2DEG;
            if (currentBearingChange < 0) currentBearingChange += 360;
            QString bearingChangedString = QString::fromUtf8( "%1°" ).arg( currentBearingChange, 0, 'f', 2 );
            painter->setPen( Qt::black );
            GeoDataCoordinates textPosition = ring.latLonAltBox().center();
            qreal deltaEast = ring.latLonAltBox().east() - currentCoordinates.longitude();
            qreal deltaWest = currentCoordinates.longitude() - ring.latLonAltBox().west();
            if (deltaEast > deltaWest) {
                textPosition.setLongitude(currentCoordinates.longitude() + deltaEast / 2);
            }
            else {
                textPosition.setLongitude(currentCoordinates.longitude() - deltaWest);
            }
            painter->drawText(textPosition, bearingChangedString );
       }

        // Drawing ellipse around 1st point towards the 2nd
        if ( m_paintMode == Circular ) {
            GeoDataCoordinates currentCoordinates = m_measureLineString[segmentIndex];

            GeoDataLinearRing ring;

            // planetRadius - planet radius
            // d - distance between points
            // S - area of the painted circle
            qreal planetRadius = marbleModel()->planet()->radius();
            qreal d = m_measureLineString.length(1);
            m_circularArea = 2 * M_PI * planetRadius * planetRadius * (1 - qCos(d));

            qreal iterBearing = 0;
            while ( iterBearing < 2 * M_PI ) {
                ring << currentCoordinates.moveByBearing(iterBearing, d);
                iterBearing += 0.1;
            }

            painter->setPen( Qt::NoPen );
            painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );
            painter->drawPolygon(ring);

            if ( m_showCircularArea ) {
                painter->setPen(Qt::white);
                GeoDataCoordinates textPosition = ring.latLonAltBox().center();

                QString areaText = tr("Area:\n%1").arg(meterToPreferredUnit(m_circularArea, true));

                QFontMetrics fontMetrics = painter->fontMetrics();
                QRect boundingRect = fontMetrics.boundingRect(QRect(), Qt::AlignCenter, areaText);

                painter->drawText(textPosition,
                                  areaText,
                                  -boundingRect.width()/2, -boundingRect.height()*1.5,
                                  boundingRect.width(), boundingRect.height(),
                                  QTextOption(Qt::AlignCenter));
            }

            if ( m_showCircumference ) {
                painter->setPen(Qt::white);
                GeoDataCoordinates textPosition = ring.latLonAltBox().center();

                m_circumference = 2 * M_PI * planetRadius * qSin(d);

                QString circumferenceText = tr("Circumference:\n%1").arg(meterToPreferredUnit(m_circumference));

                QFontMetrics fontMetrics = painter->fontMetrics();
                QRect boundingRect = fontMetrics.boundingRect(QRect(),Qt::AlignCenter,
                                                              circumferenceText);

                painter->drawText(textPosition,
                                  circumferenceText,
                                  -boundingRect.width()/2, boundingRect.height(),
                                  boundingRect.width(), boundingRect.height(),
                                  QTextOption(Qt::AlignCenter));
            }
        }

        if ( !infoString.isEmpty() ) {
            QPen linePen;

            // have three alternating colors for the segments
            switch ( segmentIndex % 3 ) {
            case 0:
                linePen.setColor( Oxygen::brickRed4 );
                break;
            case 1:
                linePen.setColor( Oxygen::forestGreen4 );
                break;
            case 2:
                linePen.setColor( Oxygen::skyBlue4 );
                break;
            }

            linePen.setWidthF(2.0);
            painter->setPen( linePen );
            painter->drawPolyline( segment, infoString, LineCenter );
        }
    }

    if (m_paintMode == Polygon && m_measureLineString.size() > 2) {
        GeoDataLinearRing measureRing = m_measureLineString;

        if (m_showPolygonArea || m_showPerimeter) {
            painter->setPen( Qt::NoPen );
            painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );
            painter->drawPolygon(measureRing);

            QPen shadowPen( Oxygen::aluminumGray5 );
            shadowPen.setStyle(Qt::DashLine);
            shadowPen.setWidthF(3.0);
            painter->setPen( shadowPen );
            painter->drawPolyline(GeoDataLineString( Tessellate ) << m_measureLineString.first()
                                                      << m_measureLineString.last());
        }

        if (m_showPolygonArea) {
            qreal theta1 = 0.0;
            qreal n = m_measureLineString.size();

            for (int segmentIndex = 1; segmentIndex < m_measureLineString.size()-1; segmentIndex++) {
                GeoDataCoordinates current = m_measureLineString[segmentIndex];
                qreal prevBearing = current.bearing(m_measureLineString[segmentIndex-1]);
                qreal nextBearing = current.bearing(m_measureLineString[segmentIndex+1]);
                if (nextBearing < prevBearing)
                    nextBearing += 2 * M_PI;

                qreal angle = nextBearing - prevBearing;
                theta1 += angle;
            }

            // Traversing first vertex
            GeoDataCoordinates current = m_measureLineString[0];
            qreal prevBearing = current.bearing(m_measureLineString[n-1]);
            qreal nextBearing = current.bearing(m_measureLineString[1]);
            if (nextBearing < prevBearing)
                nextBearing += 2 * M_PI;
            qreal angle = nextBearing - prevBearing;
            theta1 += angle;

            // And the last one
            current = m_measureLineString[n-1];
            prevBearing = current.bearing(m_measureLineString[n-2]);
            nextBearing = current.bearing(m_measureLineString[0]);
            if (nextBearing < prevBearing)
                nextBearing += 2 * M_PI;
            angle = nextBearing - prevBearing;
            theta1 += angle;

            qreal theta2 = 2 * M_PI * n - theta1;

            // theta = smaller of theta1 and theta2
            qreal theta = (theta1 < theta2) ? theta1 : theta2;

            qreal planetRadius = marbleModel()->planet()->radius();
            qreal S = qAbs((theta - (n-2) * M_PI) * planetRadius * planetRadius);
            m_polygonArea = S;

            painter->setPen(Qt::white);
            GeoDataCoordinates textPosition = measureRing.latLonAltBox().center();

            QString areaText = tr("Area:\n%1").arg(meterToPreferredUnit(S, true));

            QFontMetrics fontMetrics = painter->fontMetrics();
            QRect boundingRect = fontMetrics.boundingRect(QRect(), Qt::AlignCenter, areaText);

            painter->drawText(textPosition,
                              areaText,
                              -boundingRect.width()/2, -(boundingRect.height()+fontMetrics.height()*0.25),
                              boundingRect.width(), boundingRect.height(),
                              QTextOption(Qt::AlignCenter));
        }

        if (m_showPerimeter) {
            painter->setPen(Qt::white);
            GeoDataCoordinates textPosition = measureRing.latLonAltBox().center();

            qreal P = measureRing.length(marbleModel()->planet()->radius());
            m_perimeter = P;
            QString perimeterText = tr("Perimeter:\n%1").arg(meterToPreferredUnit(P));

            QFontMetrics fontMetrics = painter->fontMetrics();
            QRect boundingRect = fontMetrics.boundingRect(QRect(),Qt::AlignCenter,
                                                          perimeterText);

            painter->drawText(textPosition,
                              perimeterText,
                              -boundingRect.width()/2, 0,
                              boundingRect.width(), boundingRect.height(),
                              QTextOption(Qt::AlignCenter));
        }
    }
}
示例#23
0
void FoursquarePlugin::initialize()
{
    FoursquareModel *model = new FoursquareModel( marbleModel(), this );
    setModel( model );
    setNumberOfItems( 20 ); // Do we hardcode that?
}