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 ) ); }
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() ); }
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(); }
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(); }
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; }
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 ) ); }
void OpenCachingComModel::updateHome() { qreal lon, lat; int zoom; marbleModel()->home( lon, lat, zoom ); m_homeCoordinates = GeoDataCoordinates(lon, lat, 0, GeoDataCoordinates::Degree); }
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(); }
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() ); }
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; } } }
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()) ); }
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 ) ); }
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)) ); } }
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; }
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 ); } }
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; }
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); }
} 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 );
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)); } } }
void FoursquarePlugin::initialize() { FoursquareModel *model = new FoursquareModel( marbleModel(), this ); setModel( model ); setNumberOfItems( 20 ); // Do we hardcode that? }