Пример #1
0
void RoutingLayerPrivate::renderRequest( GeoPainter *painter )
{
    m_regions.clear();
    for ( int i = 0; i < m_routeRequest->size(); ++i ) {
        const GeoDataCoordinates pos = m_routeRequest->at( i );
        if ( pos.isValid() ) {
            QPixmap pixmap = m_routeRequest->pixmap( i );
            painter->drawPixmap( pos, pixmap );
            QRegion region = painter->regionFromRect( pos, pixmap.width(), pixmap.height() );
            m_regions.push_front( RequestRegion( i, region ) );
        }
    }
}
Пример #2
0
void RoutingPluginPrivate::toggleGuidanceMode( bool enabled )
{
    if( !m_marbleWidget || m_guidanceModeEnabled == enabled ) {
        return;
    }

    m_guidanceModeEnabled = enabled;
    updateButtonVisibility();

    if( enabled ) {
        QObject::connect( m_routingModel, SIGNAL(positionChanged()),
                 m_parent, SLOT(updateDestinationInformation()) );
    } else {
        QObject::disconnect( m_routingModel, SIGNAL(positionChanged()),
                    m_parent, SLOT(updateDestinationInformation()) );
    }

    if ( enabled ) {
        QString const text = QObject::tr( "Starting guidance mode, please wait..." );
        m_widget.instructionLabel->setText( richText( "%1" ).arg( text ) );
    }

    if ( enabled ) {
        RouteRequest* request = m_marbleWidget->model()->routingManager()->routeRequest();
        if ( request && request->size() > 0 ) {
            GeoDataCoordinates source = request->source();
            if ( source.isValid() ) {
                GeoDataLookAt view;
                view.setCoordinates( source );
                // By happy coincidence this equals OpenStreetMap tile level 15
                view.setRange( 851.807 );
                m_marbleWidget->flyTo( view );
            }
        }
    }

    m_marbleWidget->model()->routingManager()->setGuidanceModeEnabled( enabled );

    if ( enabled ) {
        m_routeCompleted = false;
    }

    forceRepaint();
}
Пример #3
0
void PlacemarkLayout::removePlacemarks( QModelIndex parent, int first, int last )
{
    Q_ASSERT( first < m_placemarkModel.rowCount() );
    Q_ASSERT( last < m_placemarkModel.rowCount() );
    for( int i=first; i<=last; ++i ) {
        QModelIndex index = m_placemarkModel.index( i, 0, parent );
        Q_ASSERT( index.isValid() );
        const GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole ) ));
        const GeoDataCoordinates coordinates = placemarkIconCoordinates( placemark );
        if ( !coordinates.isValid() ) {
            continue;
        }

        int zoomLevel = placemark->zoomLevel();
        TileId key = TileId::fromCoordinates( coordinates, zoomLevel );
        m_placemarkCache[key].removeAll( placemark );
    }
    emit repaintNeeded();
}
Пример #4
0
void ElevationProfileFloatItem::paintContent( QPainter *painter )
{
    // do not try to draw if not initialized
    if(!isInitialized()) {
        return;
    }
    painter->save();
    painter->setRenderHint( QPainter::Antialiasing, true );
    painter->setFont( font() );

    if ( ! ( m_activeDataSource->isDataAvailable() && m_eleData.size() > 0 ) ) {
        painter->setPen( QColor( Qt::black ) );
        QString text = tr( "Create a route or load a track from file to view its elevation profile." );
        painter->drawText( contentRect().toRect(), Qt::TextWordWrap | Qt::AlignCenter, text );
        painter->restore();
        return;
    }
    if ( m_zoomToViewport && ( m_lastVisiblePoint - m_firstVisiblePoint < 5 ) ) {
        painter->setPen( QColor( Qt::black ) );
        QString text = tr( "Not enough points in the current viewport.\nTry to disable 'Zoom to viewport'." );
        painter->drawText( contentRect().toRect(), Qt::TextWordWrap | Qt::AlignCenter, text );
        painter->restore();
        return;
    }

    QString intervalStr;
    int lastStringEnds;

    // draw viewport bounds
    if ( ! m_zoomToViewport && ( m_firstVisiblePoint > 0 || m_lastVisiblePoint < m_eleData.size() - 1 ) ) {
        QColor color( Qt::black );
        color.setAlpha( 64 );
        QRect rect;
        rect.setLeft( m_leftGraphMargin + m_eleData.value( m_firstVisiblePoint ).x() * m_eleGraphWidth / m_axisX.range() );
        rect.setTop( 0 );
        rect.setWidth( ( m_eleData.value( m_lastVisiblePoint ).x() - m_eleData.value( m_firstVisiblePoint ).x() ) * m_eleGraphWidth / m_axisX.range() );
        rect.setHeight( m_eleGraphHeight );
        painter->fillRect( rect, color );
    }

    // draw X and Y axis
    painter->setPen( Oxygen::aluminumGray4 );
    painter->drawLine( m_leftGraphMargin, m_eleGraphHeight, contentSize().width(), m_eleGraphHeight );
    painter->drawLine( m_leftGraphMargin, m_eleGraphHeight, m_leftGraphMargin, 0 );

    // draw Y grid and labels
    painter->setPen( QColor( Qt::black ) );
    QPen dashedPen( Qt::DashLine );
    dashedPen.setColor( Oxygen::aluminumGray4 );
    QRect labelRect( 0, 0, m_leftGraphMargin - 1, m_fontHeight + 2 );
    lastStringEnds = m_eleGraphHeight + m_fontHeight;
//     painter->drawText( m_leftGraphMargin + 1, m_fontHeight, "[" + m_axisY.unit() + "]" );
    foreach ( const AxisTick &tick, m_axisY.ticks() ) {
        const int posY = m_eleGraphHeight - tick.position;
        painter->setPen( dashedPen );
        painter->drawLine( m_leftGraphMargin, posY, contentSize().width(), posY );

        labelRect.moveCenter( QPoint( labelRect.center().x(), posY ) );
        if ( labelRect.top() < 0 ) {
            // don't cut off uppermost label
            labelRect.moveTop( 0 );
        }
        if ( labelRect.bottom() >= lastStringEnds ) {
            // Don't print overlapping labels
            continue;
        }
        lastStringEnds = labelRect.top();
        painter->setPen( QColor( Qt::black ) );
        intervalStr.setNum( tick.value * m_axisY.scale() );
        painter->drawText( labelRect, Qt::AlignRight, intervalStr );
    }

    // draw X grid and labels
    painter->setPen( QColor( Qt::black ) );
    labelRect.moveTop( m_eleGraphHeight + 1 );
    lastStringEnds = 0;
    foreach ( const AxisTick &tick, m_axisX.ticks() ) {
        const int posX = m_leftGraphMargin + tick.position;
        painter->setPen( dashedPen );
        painter->drawLine( posX, 0, posX, m_eleGraphHeight );

        intervalStr.setNum( tick.value * m_axisX.scale() );
        if ( tick.position == m_axisX.ticks().last().position ) {
            intervalStr += ' ' + m_axisX.unit();
        }
        labelRect.setWidth( QFontMetricsF( font() ).width( intervalStr ) * 1.5 );
        labelRect.moveCenter( QPoint( posX, labelRect.center().y() ) );
        if ( labelRect.right() > m_leftGraphMargin + m_eleGraphWidth ) {
            // don't cut off rightmost label
            labelRect.moveRight( m_leftGraphMargin + m_eleGraphWidth );
        }
        if ( labelRect.left() <= lastStringEnds ) {
            // Don't print overlapping labels
            continue;
        }
        lastStringEnds = labelRect.right();
        painter->setPen( QColor( Qt::black ) );
        painter->drawText( labelRect, Qt::AlignCenter, intervalStr );
    }

    // display elevation gain/loss data
    painter->setPen( QColor( Qt::black ) );
    intervalStr = tr( "Difference: %1 %2" )
                   .arg( QString::number( m_gain - m_loss, 'f', 0 ) )
                   .arg( m_axisY.unit() );
    intervalStr += QString::fromUtf8( "  (↗ %1 %3  ↘ %2 %3)" )
                   .arg( QString::number( m_gain, 'f', 0 ) )
                   .arg( QString::number( m_loss, 'f', 0 ) )
                   .arg( m_axisY.unit() );
    painter->drawText( contentRect().toRect(), Qt::AlignBottom | Qt::AlignCenter, intervalStr );

    // draw elevation profile
    painter->setPen( QColor( Qt::black ) );
    bool const highRes = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::HighResolution;
    QPen pen = painter->pen();
    pen.setWidth( highRes ? 2 : 1 );
    painter->setPen( pen );

    QLinearGradient fillGradient( 0, 0, 0, m_eleGraphHeight );
    QColor startColor = Oxygen::forestGreen4;
    QColor endColor = Oxygen::hotOrange4;
    startColor.setAlpha( 200 );
    endColor.setAlpha( 32 );
    fillGradient.setColorAt( 0.0, startColor );
    fillGradient.setColorAt( 1.0, endColor );
    QBrush brush = QBrush( fillGradient );
    painter->setBrush( brush );

    QPoint oldPos;
    oldPos.setX( m_leftGraphMargin );
    oldPos.setY( ( m_axisY.minValue() - m_axisY.minValue() )
                 * m_eleGraphHeight / ( m_axisY.range() / m_shrinkFactorY ) );
    oldPos.setY( m_eleGraphHeight - oldPos.y() );
    QPainterPath path;
    path.moveTo( oldPos.x(), m_eleGraphHeight );
    path.lineTo( oldPos.x(), oldPos.y() );

    const int start = m_zoomToViewport ? m_firstVisiblePoint : 0;
    const int end = m_zoomToViewport ? m_lastVisiblePoint : m_eleData.size() - 1;
    for ( int i = start; i <= end; ++i ) {
        QPoint newPos;
        if ( i == start ) {
            // make sure the plot always starts at the y-axis
            newPos.setX( 0 );
        } else {
            newPos.setX( ( m_eleData.value(i).x() - m_axisX.minValue() ) * m_eleGraphWidth / m_axisX.range() );
        }
        newPos.rx() += m_leftGraphMargin;
        if ( newPos.x() != oldPos.x() || newPos.y() != oldPos.y()  ) {
            newPos.setY( ( m_eleData.value(i).y() - m_axisY.minValue() )
                         * m_eleGraphHeight / ( m_axisY.range() * m_shrinkFactorY ) );
            newPos.setY( m_eleGraphHeight - newPos.y() );
            path.lineTo( newPos.x(), newPos.y() );
            oldPos = newPos;
        }
    }
    path.lineTo( oldPos.x(), m_eleGraphHeight );
    // fill
    painter->setPen( QPen( Qt::NoPen ) );
    painter->drawPath( path );
    // contour
    // "remove" the first and last path element first, they are only used to fill down to the bottom
    painter->setBrush( QBrush( Qt::NoBrush ) );
    path.setElementPositionAt( 0, path.elementAt( 1 ).x,  path.elementAt( 1 ).y );
    path.setElementPositionAt( path.elementCount()-1,
                               path.elementAt( path.elementCount()-2 ).x,
                               path.elementAt( path.elementCount()-2 ).y );
    painter->setPen( pen );
    painter->drawPath( path );

    pen.setWidth( 1 );
    painter->setPen( pen );

    // draw interactive cursor
    const GeoDataCoordinates currentPoint = m_markerPlacemark->coordinate();
    if ( currentPoint.isValid() ) {
        painter->setPen( QColor( Qt::white ) );
        painter->drawLine( m_leftGraphMargin + m_cursorPositionX, 0,
                           m_leftGraphMargin + m_cursorPositionX, m_eleGraphHeight );
        qreal xpos = m_axisX.minValue() + ( m_cursorPositionX / m_eleGraphWidth ) * m_axisX.range();
        qreal ypos = m_eleGraphHeight - ( ( currentPoint.altitude() - m_axisY.minValue() ) / ( qMax<qreal>( 1.0, m_axisY.range() ) * m_shrinkFactorY ) ) * m_eleGraphHeight;

        painter->drawLine( m_leftGraphMargin + m_cursorPositionX - 5, ypos,
                           m_leftGraphMargin + m_cursorPositionX + 5, ypos );
        intervalStr.setNum( xpos * m_axisX.scale(), 'f', 2 );
        intervalStr += ' ' + m_axisX.unit();
        int currentStringBegin = m_leftGraphMargin + m_cursorPositionX
                             - QFontMetricsF( font() ).width( intervalStr ) / 2;
        painter->drawText( currentStringBegin, contentSize().height() - 1.5 * m_fontHeight, intervalStr );

        intervalStr.setNum( currentPoint.altitude(), 'f', 1 );
        intervalStr += ' ' + m_axisY.unit();
        if ( m_cursorPositionX + QFontMetricsF( font() ).width( intervalStr ) + m_leftGraphMargin
                < m_eleGraphWidth ) {
            currentStringBegin = ( m_leftGraphMargin + m_cursorPositionX + 5 + 2 );
        } else {
            currentStringBegin = m_leftGraphMargin + m_cursorPositionX - 5
                                 - QFontMetricsF( font() ).width( intervalStr ) * 1.5;
        }
        // Make sure the text still fits into the window
        while ( ypos < m_fontHeight ) {
            ypos++;
        }
        painter->drawText( currentStringBegin, ypos + m_fontHeight / 2, intervalStr );
    }

    painter->restore();
}