1 // SPDX-License-Identifier: LGPL-2.1-or-later 2 // 3 // SPDX-FileCopyrightText: 2014 Adam Dabrowski <adabrowski@piap.pl> <adamdbrw@gmail.com> 4 // 5 6 7 #include <MarbleQuickItem.h> 8 #include <QPainter> 9 #include <QPaintDevice> 10 #include <QtMath> 11 #include <QQmlContext> 12 #include <QSettings> 13 14 #include <MarbleModel.h> 15 #include <MarbleMap.h> 16 #include <ViewportParams.h> 17 #include <GeoPainter.h> 18 #include <GeoDataLookAt.h> 19 #include <Planet.h> 20 #include <MarbleAbstractPresenter.h> 21 #include <AbstractFloatItem.h> 22 #include <MarbleInputHandler.h> 23 #include <PositionTracking.h> 24 #include <PositionProviderPlugin.h> 25 #include <PluginManager.h> 26 #include <RenderPlugin.h> 27 #include <MarbleMath.h> 28 #include <GeoDataLatLonAltBox.h> 29 #include <GeoDataCoordinates.h> 30 #include <ReverseGeocodingRunnerManager.h> 31 #include <routing/RoutingManager.h> 32 #include <routing/RoutingModel.h> 33 #include <routing/Route.h> 34 #include <BookmarkManager.h> 35 #include "GeoDataRelation.h" 36 #include "osm/OsmPlacemarkData.h" 37 #include "GeoDataDocument.h" 38 39 namespace Marble 40 { 41 //TODO - move to separate files 42 class QuickItemSelectionRubber : public AbstractSelectionRubber 43 { //TODO: support rubber selection in MarbleQuickItem 44 public: 45 QuickItemSelectionRubber(); show()46 void show() override { m_visible = true; } hide()47 void hide() override { m_visible = false; } isVisible() const48 bool isVisible() const override { return m_visible; } geometry() const49 const QRect &geometry() const override { return m_geometry; } setGeometry(const QRect &)50 void setGeometry(const QRect &/*geometry*/) override {} 51 private: 52 QRect m_geometry; 53 bool m_visible; 54 }; 55 56 //TODO - implement missing functionalities 57 class MarbleQuickInputHandler : public MarbleDefaultInputHandler 58 { 59 public: MarbleQuickInputHandler(MarbleAbstractPresenter * marblePresenter,MarbleQuickItem * marbleQuick)60 MarbleQuickInputHandler(MarbleAbstractPresenter *marblePresenter, MarbleQuickItem *marbleQuick) 61 : MarbleDefaultInputHandler(marblePresenter) 62 ,m_marbleQuick(marbleQuick) 63 { 64 setInertialEarthRotationEnabled(false); //Disabled by default, it's buggy. TODO - fix 65 } 66 acceptMouse()67 bool acceptMouse() override 68 { 69 return true; 70 } 71 pinch(QPointF center,qreal scale,Qt::GestureState state)72 void pinch(QPointF center, qreal scale, Qt::GestureState state) 73 { //TODO - this whole thing should be moved to MarbleAbstractPresenter 74 (void)handlePinch(center, scale, state); 75 } 76 handleMouseButtonPressAndHold(const QPoint & position)77 void handleMouseButtonPressAndHold(const QPoint &position) override 78 { 79 m_marbleQuick->reverseGeocoding(position); 80 } 81 82 private Q_SLOTS: showLmbMenu(int x,int y)83 void showLmbMenu(int x, int y) override 84 { 85 m_marbleQuick->selectPlacemarkAt(x, y); 86 emit m_marbleQuick->lmbMenuRequested(QPoint(x,y)); 87 } 88 showRmbMenu(int x,int y)89 void showRmbMenu(int x, int y) override { 90 emit m_marbleQuick->rmbMenuRequested(QPoint(x,y)); 91 } openItemToolTip()92 void openItemToolTip() override {} setCursor(const QCursor & cursor)93 void setCursor(const QCursor &cursor) override 94 { 95 m_marbleQuick->setCursor(cursor); 96 } 97 98 private Q_SLOTS: installPluginEventFilter(RenderPlugin *)99 void installPluginEventFilter(RenderPlugin *) override {} 100 101 private: layersEventFilter(QObject * o,QEvent * e)102 bool layersEventFilter(QObject *o, QEvent *e) override 103 { 104 return m_marbleQuick->layersEventFilter(o, e); 105 } 106 107 //empty - don't check. It would be invalid with quick items checkReleasedMove(QMouseEvent *)108 void checkReleasedMove(QMouseEvent *) override {} 109 handleTouch(QTouchEvent * event)110 bool handleTouch(QTouchEvent *event) override 111 { 112 if (event->touchPoints().count() > 1) 113 { //not handling multi-touch at all, let PinchArea or MultiPointTouchArea take care of it 114 return false; 115 } 116 117 if (event->touchPoints().count() == 1) 118 { //handle - but do not accept. I.e. pinchArea still needs to get this 119 QTouchEvent::TouchPoint p = event->touchPoints().at(0); 120 if (event->type() == QEvent::TouchBegin) 121 { 122 QMouseEvent press(QMouseEvent::MouseButtonPress, p.pos(), 123 Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); 124 handleMouseEvent(&press); 125 } 126 else if (event->type() == QEvent::TouchUpdate) 127 { 128 QMouseEvent move(QMouseEvent::MouseMove, p.pos(), 129 Qt::NoButton, Qt::LeftButton, Qt::NoModifier); 130 handleMouseEvent(&move); 131 } 132 else if (event->type() == QEvent::TouchEnd) 133 { 134 QMouseEvent release(QMouseEvent::MouseButtonRelease, p.pos(), 135 Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); 136 handleMouseEvent(&release); 137 } 138 } 139 return false; 140 } 141 selectionRubber()142 AbstractSelectionRubber *selectionRubber() override 143 { 144 return &m_selectionRubber; 145 } 146 147 MarbleQuickItem *m_marbleQuick; 148 QuickItemSelectionRubber m_selectionRubber; 149 bool m_usePinchArea; 150 }; 151 152 class MarbleQuickItemPrivate 153 { 154 public: MarbleQuickItemPrivate(MarbleQuickItem * marble)155 explicit MarbleQuickItemPrivate(MarbleQuickItem *marble) : 156 m_marble(marble), 157 m_model(), 158 m_map(&m_model), 159 m_presenter(&m_map), 160 m_positionVisible(false), 161 m_currentPosition(marble), 162 m_inputHandler(&m_presenter, marble), 163 m_placemarkDelegate(nullptr), 164 m_placemarkItem(nullptr), 165 m_placemark(nullptr), 166 m_reverseGeocoding(&m_model), 167 m_showScaleBar(false), 168 m_enabledRelationTypes(GeoDataRelation::RouteFerry | 169 GeoDataRelation::RouteTrain | 170 GeoDataRelation::RouteSubway | 171 GeoDataRelation::RouteTram | 172 GeoDataRelation::RouteBus | 173 GeoDataRelation::RouteTrolleyBus | 174 GeoDataRelation::RouteHiking), 175 m_showPublicTransport(false), 176 m_showOutdoorActivities(false), 177 m_heading(0.0), 178 m_hoverEnabled(false) 179 { 180 m_currentPosition.setName(QObject::tr("Current Location")); 181 m_relationTypeConverter["road"] = GeoDataRelation::RouteRoad; 182 m_relationTypeConverter["detour"] = GeoDataRelation::RouteDetour; 183 m_relationTypeConverter["ferry"] = GeoDataRelation::RouteFerry; 184 m_relationTypeConverter["train"] = GeoDataRelation::RouteTrain; 185 m_relationTypeConverter["subway"] = GeoDataRelation::RouteSubway; 186 m_relationTypeConverter["tram"] = GeoDataRelation::RouteTram; 187 m_relationTypeConverter["bus"] = GeoDataRelation::RouteBus; 188 m_relationTypeConverter["trolley-bus"] = GeoDataRelation::RouteTrolleyBus; 189 m_relationTypeConverter["bicycle"] = GeoDataRelation::RouteBicycle; 190 m_relationTypeConverter["mountainbike"] = GeoDataRelation::RouteMountainbike; 191 m_relationTypeConverter["foot"] = GeoDataRelation::RouteFoot; 192 m_relationTypeConverter["hiking"] = GeoDataRelation::RouteHiking; 193 m_relationTypeConverter["horse"] = GeoDataRelation::RouteHorse; 194 m_relationTypeConverter["inline-skates"] = GeoDataRelation::RouteInlineSkates; 195 m_relationTypeConverter["downhill"] = GeoDataRelation::RouteSkiDownhill; 196 m_relationTypeConverter["ski-nordic"] = GeoDataRelation::RouteSkiNordic; 197 m_relationTypeConverter["skitour"] = GeoDataRelation::RouteSkitour; 198 m_relationTypeConverter["sled"] = GeoDataRelation::RouteSled; 199 } 200 201 void updateVisibleRoutes(); 202 203 private: 204 MarbleQuickItem *m_marble; 205 friend class MarbleQuickItem; 206 MarbleModel m_model; 207 MarbleMap m_map; 208 MarbleAbstractPresenter m_presenter; 209 bool m_positionVisible; 210 Placemark m_currentPosition; 211 212 MarbleQuickInputHandler m_inputHandler; 213 QQmlComponent* m_placemarkDelegate; 214 QQuickItem* m_placemarkItem; 215 Placemark* m_placemark; 216 ReverseGeocodingRunnerManager m_reverseGeocoding; 217 218 bool m_showScaleBar; 219 QMap<QString, GeoDataRelation::RelationType> m_relationTypeConverter; 220 GeoDataRelation::RelationTypes m_enabledRelationTypes; 221 bool m_showPublicTransport; 222 bool m_showOutdoorActivities; 223 qreal m_heading; 224 bool m_hoverEnabled; 225 }; 226 MarbleQuickItem(QQuickItem * parent)227 MarbleQuickItem::MarbleQuickItem(QQuickItem *parent) : QQuickPaintedItem(parent) 228 ,d(new MarbleQuickItemPrivate(this)) 229 { 230 setRenderTarget(QQuickPaintedItem::FramebufferObject); 231 setOpaquePainting(true); 232 qRegisterMetaType<Placemark*>("Placemark*"); 233 d->m_map.setMapQualityForViewContext(NormalQuality, Animation); 234 235 for (AbstractFloatItem *item: d->m_map.floatItems()) { 236 if (item->nameId() == QLatin1String("license")) { 237 item->setPosition(QPointF(5.0, -10.0)); 238 } else { 239 item->hide(); 240 } 241 } 242 243 d->m_model.positionTracking()->setTrackVisible(false); 244 245 connect(&d->m_map, SIGNAL(repaintNeeded(QRegion)), this, SLOT(update())); 246 connect(this, &MarbleQuickItem::widthChanged, this, &MarbleQuickItem::resizeMap); 247 connect(this, &MarbleQuickItem::heightChanged, this, &MarbleQuickItem::resizeMap); 248 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::updatePositionVisibility); 249 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::visibleLatLonAltBoxChanged); 250 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::radiusChanged); 251 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::zoomChanged); 252 connect(&d->m_reverseGeocoding, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)), 253 this, SLOT(handleReverseGeocoding(GeoDataCoordinates,GeoDataPlacemark))); 254 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::handleVisibleLatLonAltBoxChanged); 255 256 setAcceptedMouseButtons(Qt::AllButtons); 257 installEventFilter(&d->m_inputHandler); 258 } 259 resizeMap()260 void MarbleQuickItem::resizeMap() 261 { 262 d->m_map.setSize(qMax(100, int(width())), qMax(100, int(height()))); 263 update(); 264 updatePositionVisibility(); 265 } 266 positionDataStatusChanged(PositionProviderStatus status)267 void MarbleQuickItem::positionDataStatusChanged(PositionProviderStatus status) 268 { 269 bool const positionAvailable = status == PositionProviderStatusAvailable; 270 emit positionAvailableChanged(positionAvailable); 271 updatePositionVisibility(); 272 } 273 positionChanged(const GeoDataCoordinates &,GeoDataAccuracy)274 void MarbleQuickItem::positionChanged(const GeoDataCoordinates &, GeoDataAccuracy) 275 { 276 updatePositionVisibility(); 277 } 278 updatePositionVisibility()279 void MarbleQuickItem::updatePositionVisibility() 280 { 281 updatePlacemarks(); 282 bool isVisible = false; 283 if ( positionAvailable() ) { 284 qreal x, y; 285 bool globeHidesPoint; 286 bool const valid = d->m_map.viewport()->screenCoordinates(d->m_model.positionTracking()->currentLocation(), x, y, globeHidesPoint); 287 isVisible = valid && !globeHidesPoint; 288 } 289 290 if ( isVisible != d->m_positionVisible ) { 291 d->m_positionVisible = isVisible; 292 emit positionVisibleChanged( isVisible ); 293 } 294 } 295 updateCurrentPosition(const GeoDataCoordinates & coordinates)296 void MarbleQuickItem::updateCurrentPosition(const GeoDataCoordinates &coordinates) 297 { 298 d->m_currentPosition.placemark().setCoordinate(coordinates); 299 emit currentPositionChanged(&d->m_currentPosition); 300 } 301 updatePlacemarks()302 void MarbleQuickItem::updatePlacemarks() 303 { 304 if (!d->m_placemarkDelegate || !d->m_placemark) { 305 return; 306 } 307 308 if (!d->m_placemarkItem) { 309 QQmlContext * context = new QQmlContext(qmlContext(d->m_placemarkDelegate)); 310 QObject * component = d->m_placemarkDelegate->create(context); 311 d->m_placemarkItem = qobject_cast<QQuickItem*>( component ); 312 if (d->m_placemarkItem) { 313 d->m_placemarkItem->setParentItem( this ); 314 d->m_placemarkItem->setProperty("placemark", QVariant::fromValue(d->m_placemark)); 315 } else { 316 delete component; 317 return; 318 } 319 } 320 321 qreal x = 0; 322 qreal y = 0; 323 const bool visible = d->m_map.viewport()->screenCoordinates(d->m_placemark->placemark().coordinate(), x, y); 324 d->m_placemarkItem->setVisible(visible); 325 if (visible) { 326 d->m_placemarkItem->setProperty("xPos", QVariant(x)); 327 d->m_placemarkItem->setProperty("yPos", QVariant(y)); 328 } 329 } 330 handleReverseGeocoding(const GeoDataCoordinates & coordinates,const GeoDataPlacemark & placemark)331 void MarbleQuickItem::handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark) 332 { 333 if (d->m_placemark && d->m_placemark->placemark().coordinate() == coordinates) { 334 d->m_placemark->setGeoDataPlacemark(placemark); 335 updatePlacemarks(); 336 } 337 } 338 handleVisibleLatLonAltBoxChanged(const GeoDataLatLonAltBox & latLonAltBox)339 void MarbleQuickItem::handleVisibleLatLonAltBoxChanged(const GeoDataLatLonAltBox &latLonAltBox) 340 { 341 Q_UNUSED(latLonAltBox) 342 343 if (d->m_heading != d->m_map.heading()) { 344 d->m_heading = d->m_map.heading(); 345 emit headingChanged(d->m_heading); 346 } 347 } 348 paint(QPainter * painter)349 void MarbleQuickItem::paint(QPainter *painter) 350 { //TODO - much to be done here still, i.e paint !enabled version 351 QPaintDevice *paintDevice = painter->device(); 352 QRect rect = contentsBoundingRect().toRect(); 353 354 painter->end(); 355 { 356 GeoPainter geoPainter(paintDevice, d->m_map.viewport(), d->m_map.mapQuality()); 357 d->m_map.paint(geoPainter, rect); 358 } 359 painter->begin(paintDevice); 360 } 361 classBegin()362 void MarbleQuickItem::classBegin() 363 { 364 } 365 componentComplete()366 void MarbleQuickItem::componentComplete() 367 { 368 } 369 hoverMoveEvent(QHoverEvent * event)370 void Marble::MarbleQuickItem::MarbleQuickItem::hoverMoveEvent(QHoverEvent *event) { 371 if (d->m_hoverEnabled) { 372 emit hoverPositionChanged(event->pos()); 373 } 374 QQuickItem::hoverMoveEvent(event); 375 } 376 mapWidth() const377 int MarbleQuickItem::mapWidth() const 378 { 379 return d->m_map.width(); 380 } 381 mapHeight() const382 int MarbleQuickItem::mapHeight() const 383 { 384 return d->m_map.height(); 385 } 386 showFrameRate() const387 bool MarbleQuickItem::showFrameRate() const 388 { 389 return d->m_map.showFrameRate(); 390 } 391 projection() const392 MarbleQuickItem::Projection MarbleQuickItem::projection() const 393 { 394 return Projection(d->m_map.projection()); 395 } 396 mapThemeId() const397 QString MarbleQuickItem::mapThemeId() const 398 { 399 return d->m_map.mapThemeId(); 400 } 401 showAtmosphere() const402 bool MarbleQuickItem::showAtmosphere() const 403 { 404 return d->m_map.showAtmosphere(); 405 } 406 showCompass() const407 bool MarbleQuickItem::showCompass() const 408 { 409 return d->m_map.showCompass(); 410 } 411 showClouds() const412 bool MarbleQuickItem::showClouds() const 413 { 414 return d->m_map.showClouds(); 415 } 416 showCrosshairs() const417 bool MarbleQuickItem::showCrosshairs() const 418 { 419 return d->m_map.showCrosshairs(); 420 } 421 showGrid() const422 bool MarbleQuickItem::showGrid() const 423 { 424 return d->m_map.showGrid(); 425 } 426 showOverviewMap() const427 bool MarbleQuickItem::showOverviewMap() const 428 { 429 return d->m_map.showOverviewMap(); 430 } 431 showOtherPlaces() const432 bool MarbleQuickItem::showOtherPlaces() const 433 { 434 return d->m_map.showOtherPlaces(); 435 } 436 showScaleBar() const437 bool MarbleQuickItem::showScaleBar() const 438 { 439 return d->m_showScaleBar; 440 } 441 showBackground() const442 bool MarbleQuickItem::showBackground() const 443 { 444 return d->m_map.showBackground(); 445 } 446 showPositionMarker() const447 bool MarbleQuickItem::showPositionMarker() const 448 { 449 QList<RenderPlugin *> plugins = d->m_map.renderPlugins(); 450 for (const RenderPlugin * plugin: plugins) { 451 if (plugin->nameId() == QLatin1String("positionMarker")) { 452 return plugin->visible(); 453 } 454 } 455 return false; 456 } 457 showPublicTransport() const458 bool MarbleQuickItem::showPublicTransport() const 459 { 460 return d->m_showPublicTransport; 461 } 462 showOutdoorActivities() const463 bool MarbleQuickItem::showOutdoorActivities() const 464 { 465 return d->m_showOutdoorActivities; 466 } 467 positionProvider() const468 QString MarbleQuickItem::positionProvider() const 469 { 470 if ( d->m_model.positionTracking()->positionProviderPlugin() ) { 471 return d->m_model.positionTracking()->positionProviderPlugin()->nameId(); 472 } 473 474 return QString(); 475 } 476 model()477 MarbleModel* MarbleQuickItem::model() 478 { 479 return &d->m_model; 480 } 481 model() const482 const MarbleModel* MarbleQuickItem::model() const 483 { 484 return &d->m_model; 485 } 486 map()487 MarbleMap* MarbleQuickItem::map() 488 { 489 return &d->m_map; 490 } 491 map() const492 const MarbleMap* MarbleQuickItem::map() const 493 { 494 return &d->m_map; 495 } 496 inertialGlobeRotation() const497 bool MarbleQuickItem::inertialGlobeRotation() const 498 { 499 return d->m_inputHandler.inertialEarthRotationEnabled(); 500 } 501 animationViewContext() const502 bool MarbleQuickItem::animationViewContext() const 503 { 504 return d->m_map.viewContext() == Animation; 505 } 506 animationsEnabled() const507 bool MarbleQuickItem::animationsEnabled() const 508 { 509 return d->m_presenter.animationsEnabled(); 510 } 511 placemarkDelegate() const512 QQmlComponent *MarbleQuickItem::placemarkDelegate() const 513 { 514 return d->m_placemarkDelegate; 515 } 516 reverseGeocoding(const QPoint & point)517 void MarbleQuickItem::reverseGeocoding(const QPoint &point) 518 { 519 qreal lon, lat; 520 d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat); 521 auto const coordinates = GeoDataCoordinates(lon, lat, 0.0, GeoDataCoordinates::Degree); 522 delete d->m_placemarkItem; 523 d->m_placemarkItem = nullptr; 524 delete d->m_placemark; 525 d->m_placemark = new Placemark(this); 526 d->m_placemark->placemark().setCoordinate(coordinates); 527 d->m_reverseGeocoding.reverseGeocoding(coordinates); 528 } 529 hoverEnabled() const530 bool MarbleQuickItem::hoverEnabled() const 531 { 532 return d->m_hoverEnabled; 533 } 534 moveUp()535 void MarbleQuickItem::moveUp() 536 { 537 d->m_presenter.moveByStep( 0, -1, Marble::Automatic ); 538 } 539 moveDown()540 void MarbleQuickItem::moveDown() 541 { 542 d->m_presenter.moveByStep( 0, 1, Marble::Automatic ); 543 } 544 moveLeft()545 void MarbleQuickItem::moveLeft() 546 { 547 d->m_presenter.moveByStep( -1, 0, Marble::Automatic ); 548 } 549 moveRight()550 void MarbleQuickItem::moveRight() 551 { 552 d->m_presenter.moveByStep( 1, 0, Marble::Automatic ); 553 } 554 speed() const555 qreal MarbleQuickItem::speed() const 556 { 557 return d->m_model.positionTracking()->speed(); 558 } 559 angle() const560 qreal MarbleQuickItem::angle() const 561 { 562 bool routeExists = d->m_model.routingManager()->routingModel()->route().distance() != 0.0; 563 bool onRoute = !d->m_model.routingManager()->routingModel()->deviatedFromRoute(); 564 if ( routeExists && onRoute) { 565 GeoDataCoordinates curPoint = d->m_model.positionTracking()->positionProviderPlugin()->position(); 566 return d->m_model.routingManager()->routingModel()->route().currentSegment().projectedDirection(curPoint); 567 } else { 568 return d->m_model.positionTracking()->direction(); 569 } 570 } 571 positionAvailable() const572 bool MarbleQuickItem::positionAvailable() const 573 { 574 return d->m_model.positionTracking()->status() == PositionProviderStatusAvailable; 575 } 576 positionVisible() const577 bool MarbleQuickItem::positionVisible() const 578 { 579 return d->m_positionVisible; 580 } 581 distanceFromPointToCurrentLocation(const QPoint & position) const582 qreal MarbleQuickItem::distanceFromPointToCurrentLocation(const QPoint & position) const 583 { 584 if ( positionAvailable() ) { 585 qreal lon1; 586 qreal lat1; 587 d->m_map.viewport()->geoCoordinates(position.x(), position.y(), lon1, lat1, GeoDataCoordinates::Radian ); 588 589 GeoDataCoordinates currentCoordinates = d->m_model.positionTracking()->currentLocation(); 590 qreal lon2 = currentCoordinates.longitude(); 591 qreal lat2 = currentCoordinates.latitude(); 592 593 return distanceSphere(lon1, lat1, lon2, lat2) * d->m_model.planetRadius(); 594 } 595 return 0; 596 } 597 angleFromPointToCurrentLocation(const QPoint & position) const598 qreal MarbleQuickItem::angleFromPointToCurrentLocation( const QPoint & position ) const 599 { 600 if ( positionAvailable() ) { 601 qreal x, y; 602 PositionTracking const * positionTracking = d->m_model.positionTracking(); 603 map()->viewport()->screenCoordinates( positionTracking->currentLocation(), x, y ); 604 return atan2( y-position.y(), x-position.x() ) * RAD2DEG; 605 } 606 return 0; 607 } 608 currentPosition() const609 Placemark * MarbleQuickItem::currentPosition() const 610 { 611 return &d->m_currentPosition; 612 } 613 screenCoordinatesFromCoordinate(Coordinate * coordinate) const614 QPointF MarbleQuickItem::screenCoordinatesFromCoordinate(Coordinate * coordinate) const 615 { 616 qreal x, y; 617 bool globeHidesPoint; 618 bool const valid = d->m_map.viewport()->screenCoordinates(coordinate->coordinates(), x, y, globeHidesPoint); 619 bool isVisible = valid && !globeHidesPoint; 620 return isVisible ? QPointF(x, y) : QPointF(); 621 } 622 screenCoordinatesFromGeoDataCoordinates(const GeoDataCoordinates & coordinates) const623 QPointF MarbleQuickItem::screenCoordinatesFromGeoDataCoordinates(const GeoDataCoordinates & coordinates) const 624 { 625 qreal x, y; 626 bool globeHidesPoint; 627 d->m_map.viewport()->screenCoordinates(coordinates, x, y, globeHidesPoint); 628 return !globeHidesPoint ? QPointF(x, y) : QPointF(); 629 } 630 screenCoordinatesFromGeoDataLineString(const GeoDataLineString & lineString,QVector<QPolygonF * > & polygons) const631 bool MarbleQuickItem::screenCoordinatesFromGeoDataLineString(const GeoDataLineString &lineString, QVector<QPolygonF *> &polygons) const 632 { 633 return d->m_map.viewport()->screenCoordinates(lineString, polygons); 634 } 635 screenCoordinatesToCoordinate(const QPoint & point,Coordinate * coordinate)636 bool MarbleQuickItem::screenCoordinatesToCoordinate(const QPoint & point, Coordinate * coordinate) 637 { 638 GeoDataCoordinates geoDataCoordinates; 639 bool success = screenCoordinatesToGeoDataCoordinates(point, geoDataCoordinates); 640 if (!qobject_cast<Coordinate*>(coordinate)){ 641 Coordinate * tmp(coordinate); 642 coordinate = new Coordinate(geoDataCoordinates.longitude(), geoDataCoordinates.latitude(), 0, nullptr); 643 QQmlEngine::setObjectOwnership(coordinate, QQmlEngine::JavaScriptOwnership); 644 delete tmp; 645 } 646 else { 647 coordinate->setLongitude(geoDataCoordinates.longitude()); 648 coordinate->setLatitude(geoDataCoordinates.latitude()); 649 } 650 651 return success; 652 } 653 screenCoordinatesToGeoDataCoordinates(const QPoint & point,GeoDataCoordinates & coordinates)654 bool MarbleQuickItem::screenCoordinatesToGeoDataCoordinates(const QPoint & point, GeoDataCoordinates & coordinates) 655 { 656 qreal lon = 0.0 , lat = 0.0; 657 bool const valid = d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat); 658 coordinates.setLongitude(lon); 659 coordinates.setLatitude(lat); 660 return valid; 661 } 662 setRadius(int radius)663 void MarbleQuickItem::setRadius(int radius) 664 { 665 d->m_map.setRadius(radius); 666 } 667 setHeading(qreal heading)668 void MarbleQuickItem::setHeading(qreal heading) 669 { 670 if (qFuzzyCompare(d->m_heading, heading)) 671 return; 672 673 d->m_map.setHeading(heading); 674 d->m_heading = heading; 675 676 emit headingChanged(d->m_heading); 677 } 678 setHoverEnabled(bool hoverEnabled)679 void MarbleQuickItem::setHoverEnabled(bool hoverEnabled) 680 { 681 if (d->m_hoverEnabled == hoverEnabled) 682 return; 683 684 d->m_hoverEnabled = hoverEnabled; 685 686 setAcceptHoverEvents(hoverEnabled); 687 setFlag(ItemAcceptsInputMethod, hoverEnabled); 688 689 emit hoverEnabledChanged(d->m_hoverEnabled); 690 } 691 setZoom(int newZoom,FlyToMode mode)692 void MarbleQuickItem::setZoom(int newZoom, FlyToMode mode) 693 { 694 d->m_presenter.setZoom(newZoom, mode); 695 } 696 setZoomToMaximumLevel()697 void MarbleQuickItem::setZoomToMaximumLevel() 698 { 699 d->m_presenter.setZoom(d->m_map.maximumZoom()); 700 } 701 centerOn(const GeoDataPlacemark & placemark,bool animated)702 void MarbleQuickItem::centerOn(const GeoDataPlacemark& placemark, bool animated) 703 { 704 d->m_presenter.centerOn(placemark, animated); 705 } 706 centerOn(const GeoDataLatLonBox & box,bool animated)707 void MarbleQuickItem::centerOn(const GeoDataLatLonBox& box, bool animated) 708 { 709 d->m_presenter.centerOn(box, animated); 710 } 711 centerOn(const GeoDataCoordinates & coordinate)712 void MarbleQuickItem::centerOn(const GeoDataCoordinates &coordinate) 713 { 714 GeoDataLookAt target = d->m_presenter.lookAt(); 715 target.setCoordinates(coordinate); 716 d->m_presenter.flyTo(target, Automatic); 717 } 718 centerOn(qreal longitude,qreal latitude)719 void MarbleQuickItem::centerOn(qreal longitude, qreal latitude) 720 { 721 d->m_presenter.centerOn(longitude, latitude); 722 } 723 centerOnCoordinates(qreal longitude,qreal latitude)724 void MarbleQuickItem::centerOnCoordinates(qreal longitude, qreal latitude) { 725 centerOn(longitude, latitude); 726 } 727 centerOnCurrentPosition()728 void MarbleQuickItem::centerOnCurrentPosition() 729 { 730 GeoDataCoordinates coordinates = d->m_model.positionTracking()->currentLocation(); 731 if ( coordinates == GeoDataCoordinates() ) { 732 return; 733 } 734 735 d->m_presenter.centerOn(coordinates, true); 736 if (d->m_presenter.zoom() < 3000) { 737 d->m_presenter.setZoom(3500); 738 } 739 } 740 selectPlacemarkAt(int x,int y)741 void MarbleQuickItem::selectPlacemarkAt(int x, int y) 742 { 743 auto features = d->m_map.whichFeatureAt(QPoint(x, y)); 744 QVector<GeoDataPlacemark const *> placemarks; 745 for(auto feature: features) { 746 if (const auto placemark = geodata_cast<GeoDataPlacemark>(feature)) { 747 placemarks << placemark; 748 } 749 } 750 751 for(auto placemark: placemarks) { 752 if (d->m_placemark && placemark->coordinate() == d->m_placemark->placemark().coordinate()) { 753 d->m_placemark->deleteLater(); 754 d->m_placemark = nullptr; 755 } else { 756 if (d->m_placemark) { 757 d->m_placemark->deleteLater(); 758 } 759 d->m_placemark = new Placemark(this); 760 d->m_placemark->setGeoDataPlacemark(*placemark); 761 } 762 delete d->m_placemarkItem; 763 d->m_placemarkItem = nullptr; 764 updatePlacemarks(); 765 return; 766 } 767 768 if (d->m_placemark) { 769 d->m_placemark->deleteLater(); 770 d->m_placemark = nullptr; 771 delete d->m_placemarkItem; 772 d->m_placemarkItem = nullptr; 773 updatePlacemarks(); 774 } 775 } 776 goHome()777 void MarbleQuickItem::goHome() 778 { 779 d->m_presenter.goHome(); 780 } 781 zoomIn(FlyToMode mode)782 void MarbleQuickItem::zoomIn(FlyToMode mode) 783 { 784 d->m_presenter.zoomIn(mode); 785 } 786 zoomOut(FlyToMode mode)787 void MarbleQuickItem::zoomOut(FlyToMode mode) 788 { 789 d->m_presenter.zoomOut(mode); 790 } 791 handlePinchStarted(const QPointF & point)792 void MarbleQuickItem::handlePinchStarted(const QPointF &point) 793 { 794 pinch(point, 1, Qt::GestureStarted); 795 } 796 handlePinchFinished(const QPointF & point)797 void MarbleQuickItem::handlePinchFinished(const QPointF &point) 798 { 799 pinch(point, 1, Qt::GestureFinished); 800 } 801 handlePinchUpdated(const QPointF & point,qreal scale)802 void MarbleQuickItem::handlePinchUpdated(const QPointF &point, qreal scale) 803 { 804 scale = sqrt(sqrt(scale)); 805 scale = qBound(static_cast<qreal>(0.5), scale, static_cast<qreal>(2.0)); 806 pinch(point, scale, Qt::GestureUpdated); 807 } 808 setMapWidth(int mapWidth)809 void MarbleQuickItem::setMapWidth(int mapWidth) 810 { 811 if (d->m_map.width() == mapWidth) { 812 return; 813 } 814 815 d->m_map.setSize(mapWidth, mapHeight()); 816 emit mapWidthChanged(mapWidth); 817 } 818 setMapHeight(int mapHeight)819 void MarbleQuickItem::setMapHeight(int mapHeight) 820 { 821 if (this->mapHeight() == mapHeight) { 822 return; 823 } 824 825 d->m_map.setSize(mapWidth(), mapHeight); 826 emit mapHeightChanged(mapHeight); 827 } 828 setShowFrameRate(bool showFrameRate)829 void MarbleQuickItem::setShowFrameRate(bool showFrameRate) 830 { 831 if (this->showFrameRate() == showFrameRate) { 832 return; 833 } 834 835 d->m_map.setShowFrameRate(showFrameRate); 836 emit showFrameRateChanged(showFrameRate); 837 } 838 setProjection(Projection projection)839 void MarbleQuickItem::setProjection(Projection projection) 840 { 841 if (this->projection() == projection) { 842 return; 843 } 844 845 d->m_map.setProjection(Marble::Projection(projection)); 846 emit projectionChanged(projection); 847 } 848 setMapThemeId(const QString & mapThemeId)849 void MarbleQuickItem::setMapThemeId(const QString& mapThemeId) 850 { 851 if (this->mapThemeId() == mapThemeId) { 852 return; 853 } 854 855 bool const showCompass = d->m_map.showCompass(); 856 bool const showOverviewMap = d->m_map.showOverviewMap(); 857 bool const showOtherPlaces = d->m_map.showOtherPlaces(); 858 bool const showGrid = d->m_map.showGrid(); 859 860 d->m_map.setMapThemeId(mapThemeId); 861 862 // Map themes are allowed to change properties. Enforce ours. 863 d->m_map.setShowCompass(showCompass); 864 d->m_map.setShowOverviewMap(showOverviewMap); 865 d->m_map.setShowOtherPlaces(showOtherPlaces); 866 d->m_map.setShowGrid(showGrid); 867 d->m_map.setShowScaleBar(d->m_showScaleBar); 868 869 emit mapThemeIdChanged(mapThemeId); 870 } 871 setShowAtmosphere(bool showAtmosphere)872 void MarbleQuickItem::setShowAtmosphere(bool showAtmosphere) 873 { 874 if (this->showAtmosphere() == showAtmosphere) { 875 return; 876 } 877 878 d->m_map.setShowAtmosphere(showAtmosphere); 879 emit showAtmosphereChanged(showAtmosphere); 880 } 881 setShowCompass(bool showCompass)882 void MarbleQuickItem::setShowCompass(bool showCompass) 883 { 884 if (this->showCompass() == showCompass) { 885 return; 886 } 887 888 d->m_map.setShowCompass(showCompass); 889 emit showCompassChanged(showCompass); 890 } 891 setShowClouds(bool showClouds)892 void MarbleQuickItem::setShowClouds(bool showClouds) 893 { 894 if (this->showClouds() == showClouds) { 895 return; 896 } 897 898 d->m_map.setShowClouds(showClouds); 899 emit showCloudsChanged(showClouds); 900 } 901 setShowCrosshairs(bool showCrosshairs)902 void MarbleQuickItem::setShowCrosshairs(bool showCrosshairs) 903 { 904 if (this->showCrosshairs() == showCrosshairs) { 905 return; 906 } 907 908 d->m_map.setShowCrosshairs(showCrosshairs); 909 emit showCrosshairsChanged(showCrosshairs); 910 } 911 setShowGrid(bool showGrid)912 void MarbleQuickItem::setShowGrid(bool showGrid) 913 { 914 if (this->showGrid() == showGrid) { 915 return; 916 } 917 918 d->m_map.setShowGrid(showGrid); 919 emit showGridChanged(showGrid); 920 } 921 setShowOverviewMap(bool showOverviewMap)922 void MarbleQuickItem::setShowOverviewMap(bool showOverviewMap) 923 { 924 if (this->showOverviewMap() == showOverviewMap) { 925 return; 926 } 927 928 d->m_map.setShowOverviewMap(showOverviewMap); 929 emit showOverviewMapChanged(showOverviewMap); 930 } 931 setShowOtherPlaces(bool showOtherPlaces)932 void MarbleQuickItem::setShowOtherPlaces(bool showOtherPlaces) 933 { 934 if (this->showOtherPlaces() == showOtherPlaces) { 935 return; 936 } 937 938 d->m_map.setShowOtherPlaces(showOtherPlaces); 939 emit showOtherPlacesChanged(showOtherPlaces); 940 } 941 setShowScaleBar(bool showScaleBar)942 void MarbleQuickItem::setShowScaleBar(bool showScaleBar) 943 { 944 if (d->m_showScaleBar == showScaleBar) { 945 return; 946 } 947 948 d->m_showScaleBar = showScaleBar; 949 d->m_map.setShowScaleBar(d->m_showScaleBar); 950 emit showScaleBarChanged(showScaleBar); 951 } 952 setShowBackground(bool showBackground)953 void MarbleQuickItem::setShowBackground(bool showBackground) 954 { 955 if (this->showBackground() == showBackground) { 956 return; 957 } 958 959 d->m_map.setShowBackground(showBackground); 960 emit showBackgroundChanged(showBackground); 961 } 962 setShowPositionMarker(bool showPositionMarker)963 void MarbleQuickItem::setShowPositionMarker(bool showPositionMarker) 964 { 965 if (this->showPositionMarker() == showPositionMarker) { 966 return; 967 } 968 969 QList<RenderPlugin *> plugins = d->m_map.renderPlugins(); 970 for ( RenderPlugin * plugin: plugins ) { 971 if (plugin->nameId() == QLatin1String("positionMarker")) { 972 plugin->setVisible(showPositionMarker); 973 break; 974 } 975 } 976 977 emit showPositionMarkerChanged(showPositionMarker); 978 } 979 setShowPublicTransport(bool enabled)980 void MarbleQuickItem::setShowPublicTransport(bool enabled) 981 { 982 if (d->m_showPublicTransport != enabled) { 983 d->m_showPublicTransport = enabled; 984 d->updateVisibleRoutes(); 985 emit showPublicTransportChanged(enabled); 986 } 987 } 988 setShowOutdoorActivities(bool showOutdoorActivities)989 void MarbleQuickItem::setShowOutdoorActivities(bool showOutdoorActivities) 990 { 991 if (d->m_showOutdoorActivities != showOutdoorActivities) { 992 d->m_showOutdoorActivities = showOutdoorActivities; 993 d->updateVisibleRoutes(); 994 emit showOutdoorActivitiesChanged(showOutdoorActivities); 995 } 996 } 997 setPositionProvider(const QString & positionProvider)998 void MarbleQuickItem::setPositionProvider(const QString &positionProvider) 999 { 1000 QString name; 1001 if ( d->m_model.positionTracking()->positionProviderPlugin() ) { 1002 name = d->m_model.positionTracking()->positionProviderPlugin()->nameId(); 1003 if ( name == positionProvider ) { 1004 return; 1005 } 1006 } 1007 1008 if ( positionProvider.isEmpty() ) { 1009 d->m_model.positionTracking()->setPositionProviderPlugin( nullptr ); 1010 return; 1011 } 1012 1013 QList<const PositionProviderPlugin*> plugins = d->m_model.pluginManager()->positionProviderPlugins(); 1014 for (const PositionProviderPlugin* plugin: plugins) { 1015 if ( plugin->nameId() == positionProvider) { 1016 PositionProviderPlugin * newPlugin = plugin->newInstance(); 1017 d->m_model.positionTracking()->setPositionProviderPlugin(newPlugin); 1018 connect(newPlugin, SIGNAL(statusChanged(PositionProviderStatus)), this, SLOT(positionDataStatusChanged(PositionProviderStatus))); 1019 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SLOT(updateCurrentPosition(GeoDataCoordinates))); 1020 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(speedChanged())); 1021 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(angleChanged())); 1022 emit positionProviderChanged(positionProvider); 1023 break; 1024 } 1025 } 1026 } 1027 setInertialGlobeRotation(bool inertialGlobeRotation)1028 void MarbleQuickItem::setInertialGlobeRotation(bool inertialGlobeRotation) 1029 { 1030 if (inertialGlobeRotation == d->m_inputHandler.inertialEarthRotationEnabled()) { 1031 return; 1032 } 1033 1034 d->m_inputHandler.setInertialEarthRotationEnabled(inertialGlobeRotation); 1035 emit inertialGlobeRotationChanged(inertialGlobeRotation); 1036 } 1037 setAnimationViewContext(bool animationViewContext)1038 void MarbleQuickItem::setAnimationViewContext(bool animationViewContext) 1039 { 1040 d->m_map.setViewContext(animationViewContext ? Animation : Still ); 1041 1042 emit inertialGlobeRotationChanged(animationViewContext); 1043 } 1044 setAnimationsEnabled(bool animationsEnabled)1045 void MarbleQuickItem::setAnimationsEnabled(bool animationsEnabled) 1046 { 1047 if (d->m_presenter.animationsEnabled() == animationsEnabled) 1048 return; 1049 1050 d->m_presenter.setAnimationsEnabled(animationsEnabled); 1051 emit animationsEnabledChanged(d->m_presenter.animationsEnabled()); 1052 } 1053 setPluginSetting(const QString & pluginId,const QString & key,const QString & value)1054 void MarbleQuickItem::setPluginSetting(const QString &pluginId, const QString &key, const QString &value) 1055 { 1056 for (RenderPlugin* plugin: d->m_map.renderPlugins()) { 1057 if (plugin->nameId() == pluginId) { 1058 plugin->setSetting(key, value); 1059 } 1060 } 1061 } 1062 setPropertyEnabled(const QString & property,bool enabled)1063 void MarbleQuickItem::setPropertyEnabled(const QString &property, bool enabled) 1064 { 1065 d->m_map.setPropertyValue(property, enabled); 1066 } 1067 isPropertyEnabled(const QString & property) const1068 bool MarbleQuickItem::isPropertyEnabled(const QString &property) const 1069 { 1070 return d->m_map.propertyValue(property); 1071 } 1072 setShowRuntimeTrace(bool showRuntimeTrace)1073 void MarbleQuickItem::setShowRuntimeTrace(bool showRuntimeTrace) 1074 { 1075 d->m_map.setShowRuntimeTrace(showRuntimeTrace); 1076 update(); 1077 } 1078 setShowDebugPolygons(bool showDebugPolygons)1079 void MarbleQuickItem::setShowDebugPolygons(bool showDebugPolygons) 1080 { 1081 d->m_map.setShowDebugPolygons(showDebugPolygons); 1082 update(); 1083 } 1084 setShowDebugPlacemarks(bool showDebugPlacemarks)1085 void MarbleQuickItem::setShowDebugPlacemarks(bool showDebugPlacemarks) 1086 { 1087 d->m_map.setShowDebugPlacemarks(showDebugPlacemarks); 1088 update(); 1089 } 1090 setShowDebugBatches(bool showDebugBatches)1091 void MarbleQuickItem::setShowDebugBatches(bool showDebugBatches) 1092 { 1093 d->m_map.setShowDebugBatchRender(showDebugBatches); 1094 update(); 1095 } 1096 setPlacemarkDelegate(QQmlComponent * placemarkDelegate)1097 void MarbleQuickItem::setPlacemarkDelegate(QQmlComponent *placemarkDelegate) 1098 { 1099 if (d->m_placemarkDelegate == placemarkDelegate) { 1100 return; 1101 } 1102 1103 delete d->m_placemarkItem; 1104 d->m_placemarkItem = nullptr; 1105 d->m_placemarkDelegate = placemarkDelegate; 1106 emit placemarkDelegateChanged(placemarkDelegate); 1107 } 1108 loadSettings()1109 void MarbleQuickItem::loadSettings() 1110 { 1111 QSettings settings; 1112 settings.beginGroup(QStringLiteral("MarbleQuickItem")); 1113 double lon = settings.value(QStringLiteral("centerLon"), QVariant(0.0)).toDouble(); 1114 double lat = settings.value(QStringLiteral("centerLat"), QVariant(0.0)).toDouble(); 1115 if (lat == 0.0 && lon == 0.0) { 1116 centerOnCurrentPosition(); 1117 } else { 1118 centerOn(lon, lat); 1119 } 1120 int const zoom = settings.value(QStringLiteral("zoom"), QVariant(0)).toInt(); 1121 if (zoom > 0) { 1122 setZoom(zoom); 1123 } 1124 auto const defaultRelationTypes = QStringList() << "ferry" << "train" << "subway" << "tram" << "bus" << "trolley-bus" << "hiking"; 1125 auto const visibleRelationTypes = settings.value(QStringLiteral("visibleRelationTypes"), defaultRelationTypes).toStringList(); 1126 d->m_enabledRelationTypes = GeoDataRelation::UnknownType; 1127 for (auto const &route: visibleRelationTypes) { 1128 d->m_enabledRelationTypes |= d->m_relationTypeConverter.value(route, GeoDataRelation::UnknownType); 1129 } 1130 setShowPublicTransport(settings.value(QStringLiteral("showPublicTransport"), false).toBool()); 1131 setShowOutdoorActivities(settings.value(QStringLiteral("showOutdoorActivities"), false).toBool()); 1132 settings.endGroup(); 1133 d->m_model.routingManager()->readSettings(); 1134 d->m_model.bookmarkManager()->loadFile(QStringLiteral("bookmarks/bookmarks.kml")); 1135 d->m_model.bookmarkManager()->setShowBookmarks(true); 1136 d->updateVisibleRoutes(); 1137 } 1138 writeSettings()1139 void MarbleQuickItem::writeSettings() 1140 { 1141 QSettings settings; 1142 settings.beginGroup(QStringLiteral("MarbleQuickItem")); 1143 settings.setValue(QStringLiteral("centerLon"), QVariant(d->m_map.centerLongitude())); 1144 settings.setValue(QStringLiteral("centerLat"), QVariant(d->m_map.centerLatitude())); 1145 settings.setValue(QStringLiteral("zoom"), QVariant(zoom())); 1146 QStringList enabledRoutes; 1147 QMap<GeoDataRelation::RelationType, QString> relationConverter; 1148 for (auto iter = d->m_relationTypeConverter.cbegin(), end = d->m_relationTypeConverter.cend(); iter != end; ++iter) { 1149 relationConverter[iter.value()] = iter.key(); 1150 } 1151 for (auto iter = relationConverter.cbegin(), end = relationConverter.cend(); iter != end; ++iter) { 1152 if (d->m_enabledRelationTypes & iter.key()) { 1153 enabledRoutes << iter.value(); 1154 } 1155 } 1156 settings.setValue(QStringLiteral("visibleRelationTypes"), enabledRoutes); 1157 settings.setValue(QStringLiteral("showPublicTransport"), d->m_showPublicTransport); 1158 settings.setValue(QStringLiteral("showOutdoorActivities"), d->m_showOutdoorActivities); 1159 1160 settings.endGroup(); 1161 d->m_model.routingManager()->writeSettings(); 1162 } 1163 reloadTiles()1164 void MarbleQuickItem::reloadTiles() 1165 { 1166 d->m_map.reload(); 1167 } 1168 highlightRouteRelation(qint64 osmId,bool enabled)1169 void MarbleQuickItem::highlightRouteRelation(qint64 osmId, bool enabled) 1170 { 1171 d->m_map.highlightRouteRelation(osmId, enabled); 1172 } 1173 setRelationTypeVisible(const QString & relationType,bool visible)1174 void MarbleQuickItem::setRelationTypeVisible(const QString &relationType, bool visible) 1175 { 1176 auto const relation = d->m_relationTypeConverter.value(relationType, GeoDataRelation::UnknownType); 1177 if (visible) { 1178 d->m_enabledRelationTypes |= relation; 1179 } else { 1180 d->m_enabledRelationTypes &= ~relation; 1181 } 1182 d->updateVisibleRoutes(); 1183 } 1184 isRelationTypeVisible(const QString & relationType) const1185 bool MarbleQuickItem::isRelationTypeVisible(const QString &relationType) const 1186 { 1187 auto const relation = d->m_relationTypeConverter.value(relationType, GeoDataRelation::UnknownType); 1188 return d->m_enabledRelationTypes & relation; 1189 } 1190 getEventFilter() const1191 QObject *MarbleQuickItem::getEventFilter() const 1192 { //We would want to install the same event filter for abstract layer QuickItems such as PinchArea 1193 return &d->m_inputHandler; 1194 } 1195 pinch(const QPointF & center,qreal scale,Qt::GestureState state)1196 void MarbleQuickItem::pinch(const QPointF& center, qreal scale, Qt::GestureState state) 1197 { 1198 d->m_inputHandler.pinch(center, scale, state); 1199 } 1200 inputHandler()1201 MarbleInputHandler *MarbleQuickItem::inputHandler() 1202 { 1203 return &d->m_inputHandler; 1204 } 1205 radius() const1206 int MarbleQuickItem::radius() const 1207 { 1208 return d->m_map.radius(); 1209 } 1210 heading() const1211 qreal MarbleQuickItem::heading() const 1212 { 1213 return d->m_map.heading(); 1214 } 1215 1216 zoom() const1217 int MarbleQuickItem::zoom() const 1218 { 1219 return d->m_presenter.logzoom(); 1220 } 1221 minimumZoom() const1222 int MarbleQuickItem::minimumZoom() const 1223 { 1224 return d->m_presenter.minimumZoom(); 1225 } 1226 maximumZoom() const1227 int MarbleQuickItem::maximumZoom() const 1228 { 1229 return d->m_presenter.maximumZoom(); 1230 } 1231 layersEventFilter(QObject *,QEvent *)1232 bool MarbleQuickItem::layersEventFilter(QObject *, QEvent *) 1233 { //Does nothing, but can be reimplemented in a subclass 1234 return false; 1235 } 1236 QuickItemSelectionRubber()1237 QuickItemSelectionRubber::QuickItemSelectionRubber() : 1238 m_visible(false) 1239 { 1240 // nothing to do 1241 } 1242 updateVisibleRoutes()1243 void MarbleQuickItemPrivate::updateVisibleRoutes() 1244 { 1245 GeoDataRelation::RelationTypes relationTypes = m_enabledRelationTypes; 1246 if (!m_showPublicTransport) { 1247 relationTypes &= ~GeoDataRelation::RouteTrain; 1248 relationTypes &= ~GeoDataRelation::RouteSubway; 1249 relationTypes &= ~GeoDataRelation::RouteTram; 1250 relationTypes &= ~GeoDataRelation::RouteBus; 1251 relationTypes &= ~GeoDataRelation::RouteTrolleyBus; 1252 } 1253 if (!m_showOutdoorActivities) { 1254 relationTypes &= ~GeoDataRelation::RouteBicycle; 1255 relationTypes &= ~GeoDataRelation::RouteMountainbike; 1256 relationTypes &= ~GeoDataRelation::RouteFoot; 1257 relationTypes &= ~GeoDataRelation::RouteHiking; 1258 relationTypes &= ~GeoDataRelation::RouteHorse; 1259 relationTypes &= ~GeoDataRelation::RouteInlineSkates; 1260 relationTypes &= ~GeoDataRelation::RouteSkiDownhill; 1261 relationTypes &= ~GeoDataRelation::RouteSkiNordic; 1262 relationTypes &= ~GeoDataRelation::RouteSkitour; 1263 relationTypes &= ~GeoDataRelation::RouteSled; 1264 } 1265 m_map.setVisibleRelationTypes(relationTypes); 1266 } 1267 1268 } 1269