File indexing completed on 2024-05-05 03:49:17
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Adam Dabrowski <adabrowski@piap.pl> <adamdbrw@gmail.com> 0004 // 0005 0006 0007 #include <MarbleQuickItem.h> 0008 #include <QQuickWindow> 0009 #include <QScreen> 0010 #include <QPainter> 0011 #include <QPaintDevice> 0012 #include <QtMath> 0013 #include <QQmlContext> 0014 #include <QSettings> 0015 0016 #include <MarbleModel.h> 0017 #include <MarbleMap.h> 0018 #include <ViewportParams.h> 0019 #include <GeoPainter.h> 0020 #include <GeoDataLookAt.h> 0021 #include <Planet.h> 0022 #include <MarbleAbstractPresenter.h> 0023 #include <AbstractFloatItem.h> 0024 #include <MarbleInputHandler.h> 0025 #include <PositionTracking.h> 0026 #include <PositionProviderPlugin.h> 0027 #include <PluginManager.h> 0028 #include <RenderPlugin.h> 0029 #include <MarbleMath.h> 0030 #include <StyleBuilder.h> 0031 #include <GeoDataLatLonAltBox.h> 0032 #include <GeoDataCoordinates.h> 0033 #include <ReverseGeocodingRunnerManager.h> 0034 #include <routing/RoutingManager.h> 0035 #include <routing/RoutingModel.h> 0036 #include <routing/Route.h> 0037 #include <BookmarkManager.h> 0038 #include "GeoDataRelation.h" 0039 #include "osm/OsmPlacemarkData.h" 0040 #include "GeoDataDocument.h" 0041 #include <geodata/parser/GeoSceneTypes.h> 0042 #include <geodata/scene/GeoSceneDocument.h> 0043 #include <geodata/scene/GeoSceneMap.h> 0044 #include <geodata/scene/GeoSceneLayer.h> 0045 #include <geodata/scene/GeoSceneTextureTileDataset.h> 0046 0047 namespace Marble 0048 { 0049 //TODO - move to separate files 0050 class QuickItemSelectionRubber : public AbstractSelectionRubber 0051 { //TODO: support rubber selection in MarbleQuickItem 0052 public: 0053 QuickItemSelectionRubber(); 0054 void show() override { m_visible = true; } 0055 void hide() override { m_visible = false; } 0056 bool isVisible() const override { return m_visible; } 0057 const QRect &geometry() const override { return m_geometry; } 0058 void setGeometry(const QRect &/*geometry*/) override {} 0059 private: 0060 QRect m_geometry; 0061 bool m_visible; 0062 }; 0063 0064 //TODO - implement missing functionalities 0065 class MarbleQuickInputHandler : public MarbleDefaultInputHandler 0066 { 0067 public: 0068 MarbleQuickInputHandler(MarbleAbstractPresenter *marblePresenter, MarbleQuickItem *marbleQuick) 0069 : MarbleDefaultInputHandler(marblePresenter) 0070 ,m_marbleQuick(marbleQuick) 0071 { 0072 setInertialEarthRotationEnabled(false); //Disabled by default, it's buggy. TODO - fix 0073 } 0074 0075 bool acceptMouse() override 0076 { 0077 return true; 0078 } 0079 0080 void pinch(QPointF center, qreal scale, Qt::GestureState state) 0081 { //TODO - this whole thing should be moved to MarbleAbstractPresenter 0082 (void)handlePinch(center, scale, state); 0083 } 0084 0085 void handleMouseButtonPressAndHold(const QPoint &position) override 0086 { 0087 m_marbleQuick->reverseGeocoding(position); 0088 } 0089 0090 private Q_SLOTS: 0091 void showLmbMenu(int x, int y) override 0092 { 0093 m_marbleQuick->selectPlacemarkAt(x, y); 0094 emit m_marbleQuick->lmbMenuRequested(QPoint(x,y)); 0095 } 0096 0097 void showRmbMenu(int x, int y) override { 0098 emit m_marbleQuick->rmbMenuRequested(QPoint(x,y)); 0099 } 0100 void openItemToolTip() override {} 0101 void setCursor(const QCursor &cursor) override 0102 { 0103 m_marbleQuick->setCursor(cursor); 0104 } 0105 0106 private Q_SLOTS: 0107 void installPluginEventFilter(RenderPlugin *) override {} 0108 0109 private: 0110 bool layersEventFilter(QObject *o, QEvent *e) override 0111 { 0112 return m_marbleQuick->layersEventFilter(o, e); 0113 } 0114 0115 //empty - don't check. It would be invalid with quick items 0116 void checkReleasedMove(QMouseEvent *) override {} 0117 0118 bool handleTouch(QTouchEvent *event) override 0119 { 0120 if (event->touchPoints().count() > 1) 0121 { //not handling multi-touch at all, let PinchArea or MultiPointTouchArea take care of it 0122 return false; 0123 } 0124 0125 if (event->touchPoints().count() == 1) 0126 { //handle - but do not accept. I.e. pinchArea still needs to get this 0127 QTouchEvent::TouchPoint p = event->touchPoints().at(0); 0128 if (event->type() == QEvent::TouchBegin) 0129 { 0130 QMouseEvent press(QMouseEvent::MouseButtonPress, p.pos(), 0131 Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); 0132 handleMouseEvent(&press); 0133 } 0134 else if (event->type() == QEvent::TouchUpdate) 0135 { 0136 QMouseEvent move(QMouseEvent::MouseMove, p.pos(), 0137 Qt::NoButton, Qt::LeftButton, Qt::NoModifier); 0138 handleMouseEvent(&move); 0139 } 0140 else if (event->type() == QEvent::TouchEnd) 0141 { 0142 QMouseEvent release(QMouseEvent::MouseButtonRelease, p.pos(), 0143 Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); 0144 handleMouseEvent(&release); 0145 } 0146 } 0147 return false; 0148 } 0149 0150 AbstractSelectionRubber *selectionRubber() override 0151 { 0152 return &m_selectionRubber; 0153 } 0154 0155 MarbleQuickItem *m_marbleQuick; 0156 QuickItemSelectionRubber m_selectionRubber; 0157 // bool m_usePinchArea; 0158 }; 0159 0160 class MarbleQuickItemPrivate 0161 { 0162 public: 0163 explicit MarbleQuickItemPrivate(MarbleQuickItem *marble) : 0164 m_marble(marble), 0165 m_model(), 0166 m_map(&m_model), 0167 m_presenter(&m_map), 0168 m_positionVisible(false), 0169 m_currentPosition(marble), 0170 m_inputHandler(&m_presenter, marble), 0171 m_placemarkDelegate(nullptr), 0172 m_placemarkItem(nullptr), 0173 m_placemark(nullptr), 0174 m_reverseGeocoding(&m_model), 0175 m_showScaleBar(false), 0176 m_enabledRelationTypes(GeoDataRelation::RouteFerry | 0177 GeoDataRelation::RouteTrain | 0178 GeoDataRelation::RouteSubway | 0179 GeoDataRelation::RouteTram | 0180 GeoDataRelation::RouteBus | 0181 GeoDataRelation::RouteTrolleyBus | 0182 GeoDataRelation::RouteHiking), 0183 m_showPublicTransport(false), 0184 m_showOutdoorActivities(false), 0185 m_heading(0.0), 0186 m_hoverEnabled(false), 0187 m_invertColorEnabled(false) 0188 { 0189 m_currentPosition.setName(QObject::tr("Current Location")); 0190 m_relationTypeConverter["road"] = GeoDataRelation::RouteRoad; 0191 m_relationTypeConverter["detour"] = GeoDataRelation::RouteDetour; 0192 m_relationTypeConverter["ferry"] = GeoDataRelation::RouteFerry; 0193 m_relationTypeConverter["train"] = GeoDataRelation::RouteTrain; 0194 m_relationTypeConverter["subway"] = GeoDataRelation::RouteSubway; 0195 m_relationTypeConverter["tram"] = GeoDataRelation::RouteTram; 0196 m_relationTypeConverter["bus"] = GeoDataRelation::RouteBus; 0197 m_relationTypeConverter["trolley-bus"] = GeoDataRelation::RouteTrolleyBus; 0198 m_relationTypeConverter["bicycle"] = GeoDataRelation::RouteBicycle; 0199 m_relationTypeConverter["mountainbike"] = GeoDataRelation::RouteMountainbike; 0200 m_relationTypeConverter["foot"] = GeoDataRelation::RouteFoot; 0201 m_relationTypeConverter["hiking"] = GeoDataRelation::RouteHiking; 0202 m_relationTypeConverter["horse"] = GeoDataRelation::RouteHorse; 0203 m_relationTypeConverter["inline-skates"] = GeoDataRelation::RouteInlineSkates; 0204 m_relationTypeConverter["downhill"] = GeoDataRelation::RouteSkiDownhill; 0205 m_relationTypeConverter["ski-nordic"] = GeoDataRelation::RouteSkiNordic; 0206 m_relationTypeConverter["skitour"] = GeoDataRelation::RouteSkitour; 0207 m_relationTypeConverter["sled"] = GeoDataRelation::RouteSled; 0208 } 0209 0210 void updateVisibleRoutes(); 0211 void changeBlending(bool enabled, const QString &blendingName); 0212 void changeStyleBuilder(bool invert); 0213 0214 private: 0215 MarbleQuickItem *m_marble; 0216 friend class MarbleQuickItem; 0217 MarbleModel m_model; 0218 MarbleMap m_map; 0219 Marble::MapTheme m_mapTheme; 0220 MarbleAbstractPresenter m_presenter; 0221 bool m_positionVisible; 0222 Placemark m_currentPosition; 0223 0224 MarbleQuickInputHandler m_inputHandler; 0225 QQmlComponent* m_placemarkDelegate; 0226 QQuickItem* m_placemarkItem; 0227 Placemark* m_placemark; 0228 ReverseGeocodingRunnerManager m_reverseGeocoding; 0229 0230 bool m_showScaleBar; 0231 QMap<QString, GeoDataRelation::RelationType> m_relationTypeConverter; 0232 GeoDataRelation::RelationTypes m_enabledRelationTypes; 0233 bool m_showPublicTransport; 0234 bool m_showOutdoorActivities; 0235 qreal m_heading; 0236 bool m_hoverEnabled; 0237 bool m_invertColorEnabled; 0238 }; 0239 0240 MarbleQuickItem::MarbleQuickItem(QQuickItem *parent) : QQuickPaintedItem(parent) 0241 ,d(new MarbleQuickItemPrivate(this)) 0242 { 0243 setRenderTarget(QQuickPaintedItem::FramebufferObject); 0244 setOpaquePainting(true); 0245 qRegisterMetaType<Placemark*>("Placemark*"); 0246 d->m_map.setMapQualityForViewContext(NormalQuality, Animation); 0247 0248 for (AbstractFloatItem *item: d->m_map.floatItems()) { 0249 if (item->nameId() == QLatin1String("license")) { 0250 item->setPosition(QPointF(5.0, -10.0)); 0251 } else { 0252 item->hide(); 0253 } 0254 } 0255 0256 d->m_model.positionTracking()->setTrackVisible(false); 0257 d->m_mapTheme.setMap(this); 0258 0259 connect(&d->m_map, SIGNAL(repaintNeeded(QRegion)), this, SLOT(update())); 0260 connect(this, &MarbleQuickItem::widthChanged, this, &MarbleQuickItem::resizeMap); 0261 connect(this, &MarbleQuickItem::heightChanged, this, &MarbleQuickItem::resizeMap); 0262 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::updatePositionVisibility); 0263 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::radiusChanged); 0264 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::zoomChanged); 0265 connect(&d->m_reverseGeocoding, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)), 0266 this, SLOT(handleReverseGeocoding(GeoDataCoordinates,GeoDataPlacemark))); 0267 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::handleVisibleLatLonAltBoxChanged); 0268 connect(d->m_map.model(), &MarbleModel::workOfflineChanged, this, &MarbleQuickItem::workOfflineChanged); 0269 0270 setAcceptedMouseButtons(Qt::AllButtons); 0271 installEventFilter(&d->m_inputHandler); 0272 } 0273 0274 void MarbleQuickItem::resizeMap() 0275 { 0276 0277 d->m_map.setSize(qMax(100, int(width())), qMax(100, int(height()))); 0278 update(); 0279 updatePositionVisibility(); 0280 } 0281 0282 void MarbleQuickItem::positionDataStatusChanged(PositionProviderStatus status) 0283 { 0284 bool const positionAvailable = status == PositionProviderStatusAvailable; 0285 emit positionAvailableChanged(positionAvailable); 0286 updatePositionVisibility(); 0287 } 0288 0289 void MarbleQuickItem::positionChanged(const GeoDataCoordinates &, GeoDataAccuracy) 0290 { 0291 updatePositionVisibility(); 0292 } 0293 0294 void MarbleQuickItem::updatePositionVisibility() 0295 { 0296 updatePlacemarks(); 0297 bool isVisible = false; 0298 if ( positionAvailable() ) { 0299 qreal x, y; 0300 bool globeHidesPoint; 0301 bool const valid = d->m_map.viewport()->screenCoordinates(d->m_model.positionTracking()->currentLocation(), x, y, globeHidesPoint); 0302 isVisible = valid && !globeHidesPoint; 0303 } 0304 0305 if ( isVisible != d->m_positionVisible ) { 0306 d->m_positionVisible = isVisible; 0307 emit positionVisibleChanged( isVisible ); 0308 } 0309 } 0310 0311 void MarbleQuickItem::updateCurrentPosition(const GeoDataCoordinates &coordinates) 0312 { 0313 d->m_currentPosition.placemark().setCoordinate(coordinates); 0314 emit currentPositionChanged(&d->m_currentPosition); 0315 } 0316 0317 void MarbleQuickItem::updatePlacemarks() 0318 { 0319 if (!d->m_placemarkDelegate || !d->m_placemark) { 0320 return; 0321 } 0322 0323 if (!d->m_placemarkItem) { 0324 QQmlContext * context = new QQmlContext(qmlContext(d->m_placemarkDelegate)); 0325 QObject * component = d->m_placemarkDelegate->create(context); 0326 d->m_placemarkItem = qobject_cast<QQuickItem*>( component ); 0327 if (d->m_placemarkItem) { 0328 d->m_placemarkItem->setParentItem( this ); 0329 d->m_placemarkItem->setProperty("placemark", QVariant::fromValue(d->m_placemark)); 0330 } else { 0331 delete component; 0332 return; 0333 } 0334 } 0335 0336 qreal x = 0; 0337 qreal y = 0; 0338 const bool visible = d->m_map.viewport()->screenCoordinates(d->m_placemark->placemark().coordinate(), x, y); 0339 d->m_placemarkItem->setVisible(visible); 0340 if (visible) { 0341 d->m_placemarkItem->setProperty("xPos", QVariant(x)); 0342 d->m_placemarkItem->setProperty("yPos", QVariant(y)); 0343 } 0344 } 0345 0346 void MarbleQuickItem::handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark) 0347 { 0348 if (d->m_placemark && d->m_placemark->placemark().coordinate() == coordinates) { 0349 d->m_placemark->setGeoDataPlacemark(placemark); 0350 updatePlacemarks(); 0351 } 0352 } 0353 0354 void MarbleQuickItem::handleVisibleLatLonAltBoxChanged(const GeoDataLatLonAltBox &latLonAltBox) 0355 { 0356 Q_UNUSED(latLonAltBox) 0357 0358 if (d->m_heading != d->m_map.heading()) { 0359 d->m_heading = d->m_map.heading(); 0360 emit headingChanged(d->m_heading); 0361 } 0362 emit visibleLatLonAltBoxChanged(); 0363 emit geoItemUpdateRequested(); 0364 } 0365 0366 void MarbleQuickItem::paint(QPainter *painter) 0367 { //TODO - much to be done here still, i.e paint !enabled version 0368 QPaintDevice * paintDevice = painter->device(); 0369 QRect rect = contentsBoundingRect().toRect(); 0370 0371 painter->end(); 0372 { 0373 GeoPainter geoPainter(paintDevice, d->m_map.viewport(), d->m_map.mapQuality()); 0374 0375 double scale = 1.0; 0376 // For HighDPI displays take QT_SCALE_FACTOR into account: 0377 QQuickWindow * window = this->window(); 0378 if (window) { 0379 QScreen * screen = window->screen(); 0380 scale = screen != nullptr ? screen->devicePixelRatio() : 1.0; 0381 if (scale != 1) { 0382 geoPainter.scale(scale, scale); 0383 } 0384 } 0385 0386 d->m_map.paint(geoPainter, rect); 0387 } 0388 painter->begin(paintDevice); 0389 } 0390 0391 void MarbleQuickItem::classBegin() 0392 { 0393 } 0394 0395 void MarbleQuickItem::componentComplete() 0396 { 0397 } 0398 0399 void Marble::MarbleQuickItem::MarbleQuickItem::hoverMoveEvent(QHoverEvent *event) { 0400 if (d->m_hoverEnabled) { 0401 emit hoverPositionChanged(event->pos()); 0402 } 0403 QQuickItem::hoverMoveEvent(event); 0404 } 0405 0406 int MarbleQuickItem::mapWidth() const 0407 { 0408 return d->m_map.width(); 0409 } 0410 0411 int MarbleQuickItem::mapHeight() const 0412 { 0413 return d->m_map.height(); 0414 } 0415 0416 bool MarbleQuickItem::showFrameRate() const 0417 { 0418 return d->m_map.showFrameRate(); 0419 } 0420 0421 MarbleQuickItem::Projection MarbleQuickItem::projection() const 0422 { 0423 return Projection(d->m_map.projection()); 0424 } 0425 0426 QString MarbleQuickItem::mapThemeId() const 0427 { 0428 return d->m_map.mapThemeId(); 0429 } 0430 0431 Marble::MapTheme *MarbleQuickItem::mapTheme() const 0432 { 0433 return &d->m_mapTheme; 0434 } 0435 0436 bool MarbleQuickItem::showAtmosphere() const 0437 { 0438 return d->m_map.showAtmosphere(); 0439 } 0440 0441 bool MarbleQuickItem::showCompass() const 0442 { 0443 return d->m_map.showCompass(); 0444 } 0445 0446 bool MarbleQuickItem::showClouds() const 0447 { 0448 return d->m_map.showClouds(); 0449 } 0450 0451 bool MarbleQuickItem::showCrosshairs() const 0452 { 0453 return d->m_map.showCrosshairs(); 0454 } 0455 0456 bool MarbleQuickItem::showGrid() const 0457 { 0458 return d->m_map.showGrid(); 0459 } 0460 0461 bool MarbleQuickItem::showOverviewMap() const 0462 { 0463 return d->m_map.showOverviewMap(); 0464 } 0465 0466 bool MarbleQuickItem::showOtherPlaces() const 0467 { 0468 return d->m_map.showOtherPlaces(); 0469 } 0470 0471 bool MarbleQuickItem::showScaleBar() const 0472 { 0473 return d->m_showScaleBar; 0474 } 0475 0476 bool MarbleQuickItem::showBackground() const 0477 { 0478 return d->m_map.showBackground(); 0479 } 0480 0481 bool MarbleQuickItem::showPositionMarker() const 0482 { 0483 QList<RenderPlugin *> plugins = d->m_map.renderPlugins(); 0484 for (const RenderPlugin * plugin: plugins) { 0485 if (plugin->nameId() == QLatin1String("positionMarker")) { 0486 return plugin->visible(); 0487 } 0488 } 0489 return false; 0490 } 0491 0492 bool MarbleQuickItem::showPublicTransport() const 0493 { 0494 return d->m_showPublicTransport; 0495 } 0496 0497 bool MarbleQuickItem::showOutdoorActivities() const 0498 { 0499 return d->m_showOutdoorActivities; 0500 } 0501 0502 QString MarbleQuickItem::positionProvider() const 0503 { 0504 if ( d->m_model.positionTracking()->positionProviderPlugin() ) { 0505 return d->m_model.positionTracking()->positionProviderPlugin()->nameId(); 0506 } 0507 0508 return QString(); 0509 } 0510 0511 MarbleModel* MarbleQuickItem::model() 0512 { 0513 return &d->m_model; 0514 } 0515 0516 const MarbleModel* MarbleQuickItem::model() const 0517 { 0518 return &d->m_model; 0519 } 0520 0521 MarbleMap* MarbleQuickItem::map() 0522 { 0523 return &d->m_map; 0524 } 0525 0526 const MarbleMap* MarbleQuickItem::map() const 0527 { 0528 return &d->m_map; 0529 } 0530 0531 bool MarbleQuickItem::inertialGlobeRotation() const 0532 { 0533 return d->m_inputHandler.inertialEarthRotationEnabled(); 0534 } 0535 0536 bool MarbleQuickItem::animationViewContext() const 0537 { 0538 return d->m_map.viewContext() == Animation; 0539 } 0540 0541 bool MarbleQuickItem::animationsEnabled() const 0542 { 0543 return d->m_presenter.animationsEnabled(); 0544 } 0545 0546 QQmlComponent *MarbleQuickItem::placemarkDelegate() const 0547 { 0548 return d->m_placemarkDelegate; 0549 } 0550 0551 void MarbleQuickItem::reverseGeocoding(const QPoint &point) 0552 { 0553 qreal lon, lat; 0554 d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat); 0555 auto const coordinates = GeoDataCoordinates(lon, lat, 0.0, GeoDataCoordinates::Degree); 0556 delete d->m_placemarkItem; 0557 d->m_placemarkItem = nullptr; 0558 delete d->m_placemark; 0559 d->m_placemark = new Placemark(this); 0560 d->m_placemark->placemark().setCoordinate(coordinates); 0561 d->m_reverseGeocoding.reverseGeocoding(coordinates); 0562 } 0563 0564 bool MarbleQuickItem::hoverEnabled() const 0565 { 0566 return d->m_hoverEnabled; 0567 } 0568 0569 void MarbleQuickItem::moveUp() 0570 { 0571 d->m_presenter.moveByStep( 0, -1, Marble::Linear ); 0572 } 0573 0574 void MarbleQuickItem::moveDown() 0575 { 0576 d->m_presenter.moveByStep( 0, 1, Marble::Linear ); 0577 } 0578 0579 void MarbleQuickItem::moveLeft() 0580 { 0581 d->m_presenter.moveByStep( -1, 0, Marble::Linear ); 0582 } 0583 0584 void MarbleQuickItem::moveRight() 0585 { 0586 d->m_presenter.moveByStep( 1, 0, Marble::Linear ); 0587 } 0588 0589 qreal MarbleQuickItem::speed() const 0590 { 0591 return d->m_model.positionTracking()->speed(); 0592 } 0593 0594 qreal MarbleQuickItem::angle() const 0595 { 0596 bool routeExists = d->m_model.routingManager()->routingModel()->route().distance() != 0.0; 0597 bool onRoute = !d->m_model.routingManager()->routingModel()->deviatedFromRoute(); 0598 if ( routeExists && onRoute) { 0599 GeoDataCoordinates curPoint = d->m_model.positionTracking()->positionProviderPlugin()->position(); 0600 return d->m_model.routingManager()->routingModel()->route().currentSegment().projectedDirection(curPoint); 0601 } else { 0602 return d->m_model.positionTracking()->direction(); 0603 } 0604 } 0605 0606 bool MarbleQuickItem::positionAvailable() const 0607 { 0608 return d->m_model.positionTracking()->status() == PositionProviderStatusAvailable; 0609 } 0610 0611 bool MarbleQuickItem::positionVisible() const 0612 { 0613 return d->m_positionVisible; 0614 } 0615 0616 qreal MarbleQuickItem::distanceFromPointToCurrentLocation(const QPoint & position) const 0617 { 0618 if ( positionAvailable() ) { 0619 qreal lon1; 0620 qreal lat1; 0621 d->m_map.viewport()->geoCoordinates(position.x(), position.y(), lon1, lat1, GeoDataCoordinates::Radian ); 0622 0623 GeoDataCoordinates currentCoordinates = d->m_model.positionTracking()->currentLocation(); 0624 qreal lon2 = currentCoordinates.longitude(); 0625 qreal lat2 = currentCoordinates.latitude(); 0626 0627 return distanceSphere(lon1, lat1, lon2, lat2) * d->m_model.planetRadius(); 0628 } 0629 return 0; 0630 } 0631 0632 qreal MarbleQuickItem::angleFromPointToCurrentLocation( const QPoint & position ) const 0633 { 0634 if ( positionAvailable() ) { 0635 qreal x, y; 0636 PositionTracking const * positionTracking = d->m_model.positionTracking(); 0637 map()->viewport()->screenCoordinates( positionTracking->currentLocation(), x, y ); 0638 return atan2( y-position.y(), x-position.x() ) * RAD2DEG; 0639 } 0640 return 0; 0641 } 0642 0643 Placemark * MarbleQuickItem::currentPosition() const 0644 { 0645 return &d->m_currentPosition; 0646 } 0647 0648 QPointF MarbleQuickItem::screenCoordinatesFromCoordinate(Coordinate * coordinate) const 0649 { 0650 qreal x, y; 0651 bool globeHidesPoint; 0652 bool const valid = d->m_map.viewport()->screenCoordinates(coordinate->coordinates(), x, y, globeHidesPoint); 0653 bool isVisible = valid && !globeHidesPoint; 0654 return isVisible ? QPointF(x, y) : QPointF(); 0655 } 0656 0657 QPointF MarbleQuickItem::screenCoordinatesFromGeoDataCoordinates(const GeoDataCoordinates & coordinates) const 0658 { 0659 qreal x, y; 0660 bool globeHidesPoint; 0661 d->m_map.viewport()->screenCoordinates(coordinates, x, y, globeHidesPoint); 0662 return !globeHidesPoint ? QPointF(x, y) : QPointF(); 0663 } 0664 0665 bool MarbleQuickItem::screenCoordinatesFromGeoDataLineString(const GeoDataLineString &lineString, QVector<QPolygonF *> &polygons) const 0666 { 0667 return d->m_map.viewport()->screenCoordinates(lineString, polygons); 0668 } 0669 0670 bool MarbleQuickItem::screenCoordinatesToCoordinate(const QPoint & point, Coordinate * coordinate) 0671 { 0672 GeoDataCoordinates geoDataCoordinates; 0673 bool success = screenCoordinatesToGeoDataCoordinates(point, geoDataCoordinates); 0674 if (!qobject_cast<Coordinate*>(coordinate)){ 0675 Coordinate * tmp(coordinate); 0676 coordinate = new Coordinate(geoDataCoordinates.longitude(), geoDataCoordinates.latitude(), 0, nullptr); 0677 QQmlEngine::setObjectOwnership(coordinate, QQmlEngine::JavaScriptOwnership); 0678 delete tmp; 0679 } 0680 else { 0681 coordinate->setLongitude(geoDataCoordinates.longitude()); 0682 coordinate->setLatitude(geoDataCoordinates.latitude()); 0683 } 0684 0685 return success; 0686 } 0687 0688 bool MarbleQuickItem::screenCoordinatesToGeoDataCoordinates(const QPoint & point, GeoDataCoordinates & coordinates) 0689 { 0690 qreal lon = 0.0 , lat = 0.0; 0691 bool const valid = d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat); 0692 coordinates.setLongitude(lon); 0693 coordinates.setLatitude(lat); 0694 return valid; 0695 } 0696 0697 void MarbleQuickItem::setRadius(int radius) 0698 { 0699 d->m_map.setRadius(radius); 0700 } 0701 0702 void MarbleQuickItem::setHeading(qreal heading) 0703 { 0704 if (qFuzzyCompare(d->m_heading, heading)) 0705 return; 0706 0707 d->m_map.setHeading(heading); 0708 d->m_heading = heading; 0709 0710 emit headingChanged(d->m_heading); 0711 } 0712 0713 void MarbleQuickItem::setHoverEnabled(bool hoverEnabled) 0714 { 0715 if (d->m_hoverEnabled == hoverEnabled) 0716 return; 0717 0718 d->m_hoverEnabled = hoverEnabled; 0719 0720 setAcceptHoverEvents(hoverEnabled); 0721 setFlag(ItemAcceptsInputMethod, hoverEnabled); 0722 0723 emit hoverEnabledChanged(d->m_hoverEnabled); 0724 } 0725 0726 void MarbleQuickItem::setZoom(int newZoom, FlyToMode mode) 0727 { 0728 d->m_presenter.setZoom(newZoom, mode); 0729 } 0730 0731 void MarbleQuickItem::setZoomToMaximumLevel() 0732 { 0733 d->m_presenter.setZoom(d->m_map.maximumZoom()); 0734 } 0735 0736 void MarbleQuickItem::centerOn(const GeoDataPlacemark& placemark, bool animated) 0737 { 0738 d->m_presenter.centerOn(placemark, animated); 0739 } 0740 0741 void MarbleQuickItem::centerOn(const GeoDataLatLonBox& box, bool animated) 0742 { 0743 d->m_presenter.centerOn(box, animated); 0744 } 0745 0746 void MarbleQuickItem::centerOn(const GeoDataCoordinates &coordinate) 0747 { 0748 GeoDataLookAt target = d->m_presenter.lookAt(); 0749 target.setCoordinates(coordinate); 0750 d->m_presenter.flyTo(target, Automatic); 0751 } 0752 0753 void MarbleQuickItem::centerOn(qreal longitude, qreal latitude) 0754 { 0755 d->m_presenter.centerOn(longitude, latitude); 0756 } 0757 0758 void MarbleQuickItem::centerOnCoordinates(qreal longitude, qreal latitude) { 0759 centerOn(longitude, latitude); 0760 } 0761 0762 void MarbleQuickItem::centerOnCurrentPosition() 0763 { 0764 GeoDataCoordinates coordinates = d->m_model.positionTracking()->currentLocation(); 0765 if ( coordinates == GeoDataCoordinates() ) { 0766 return; 0767 } 0768 0769 d->m_presenter.centerOn(coordinates, true); 0770 if (d->m_presenter.zoom() < 3000) { 0771 d->m_presenter.setZoom(3500); 0772 } 0773 } 0774 0775 void MarbleQuickItem::selectPlacemarkAt(int x, int y) 0776 { 0777 auto features = d->m_map.whichFeatureAt(QPoint(x, y)); 0778 QVector<GeoDataPlacemark const *> placemarks; 0779 for(auto feature: features) { 0780 if (const auto placemark = geodata_cast<GeoDataPlacemark>(feature)) { 0781 placemarks << placemark; 0782 } 0783 } 0784 0785 for(auto placemark: placemarks) { 0786 if (d->m_placemark && placemark->coordinate() == d->m_placemark->placemark().coordinate()) { 0787 d->m_placemark->deleteLater(); 0788 d->m_placemark = nullptr; 0789 } else { 0790 if (d->m_placemark) { 0791 d->m_placemark->deleteLater(); 0792 } 0793 d->m_placemark = new Placemark(this); 0794 d->m_placemark->setGeoDataPlacemark(*placemark); 0795 } 0796 delete d->m_placemarkItem; 0797 d->m_placemarkItem = nullptr; 0798 updatePlacemarks(); 0799 return; 0800 } 0801 0802 if (d->m_placemark) { 0803 d->m_placemark->deleteLater(); 0804 d->m_placemark = nullptr; 0805 delete d->m_placemarkItem; 0806 d->m_placemarkItem = nullptr; 0807 updatePlacemarks(); 0808 } 0809 } 0810 0811 void MarbleQuickItem::goHome() 0812 { 0813 d->m_presenter.goHome(); 0814 } 0815 0816 void MarbleQuickItem::zoomIn(FlyToMode mode) 0817 { 0818 d->m_presenter.zoomIn(mode); 0819 } 0820 0821 void MarbleQuickItem::zoomOut(FlyToMode mode) 0822 { 0823 d->m_presenter.zoomOut(mode); 0824 } 0825 0826 void MarbleQuickItem::handlePinchStarted(const QPointF &point) 0827 { 0828 pinch(point, 1, Qt::GestureStarted); 0829 } 0830 0831 void MarbleQuickItem::handlePinchFinished(const QPointF &point) 0832 { 0833 pinch(point, 1, Qt::GestureFinished); 0834 } 0835 0836 void MarbleQuickItem::handlePinchUpdated(const QPointF &point, qreal scale) 0837 { 0838 scale = sqrt(sqrt(scale)); 0839 scale = qBound(static_cast<qreal>(0.5), scale, static_cast<qreal>(2.0)); 0840 pinch(point, scale, Qt::GestureUpdated); 0841 } 0842 0843 void MarbleQuickItem::setMapWidth(int mapWidth) 0844 { 0845 if (d->m_map.width() == mapWidth) { 0846 return; 0847 } 0848 0849 d->m_map.setSize(mapWidth, mapHeight()); 0850 emit mapWidthChanged(mapWidth); 0851 } 0852 0853 void MarbleQuickItem::setMapHeight(int mapHeight) 0854 { 0855 if (this->mapHeight() == mapHeight) { 0856 return; 0857 } 0858 0859 d->m_map.setSize(mapWidth(), mapHeight); 0860 emit mapHeightChanged(mapHeight); 0861 } 0862 0863 void MarbleQuickItem::setShowFrameRate(bool showFrameRate) 0864 { 0865 if (this->showFrameRate() == showFrameRate) { 0866 return; 0867 } 0868 0869 d->m_map.setShowFrameRate(showFrameRate); 0870 emit showFrameRateChanged(showFrameRate); 0871 } 0872 0873 void MarbleQuickItem::setProjection(Projection projection) 0874 { 0875 if (this->projection() == projection) { 0876 return; 0877 } 0878 0879 d->m_map.setProjection(Marble::Projection(projection)); 0880 emit projectionChanged(projection); 0881 } 0882 0883 void MarbleQuickItem::setMapThemeId(const QString& mapThemeId) 0884 { 0885 if (this->mapThemeId() == mapThemeId) { 0886 return; 0887 } 0888 0889 bool invertColor = invertColorEnabled(); 0890 0891 bool const showCompass = d->m_map.showCompass(); 0892 bool const showOverviewMap = d->m_map.showOverviewMap(); 0893 bool const showOtherPlaces = d->m_map.showOtherPlaces(); 0894 bool const showGrid = d->m_map.showGrid(); 0895 0896 d->m_map.setMapThemeId(mapThemeId); 0897 0898 // Map themes are allowed to change properties. Enforce ours. 0899 d->m_map.setShowCompass(showCompass); 0900 d->m_map.setShowOverviewMap(showOverviewMap); 0901 d->m_map.setShowOtherPlaces(showOtherPlaces); 0902 d->m_map.setShowGrid(showGrid); 0903 d->m_map.setShowScaleBar(d->m_showScaleBar); 0904 0905 emit mapThemeIdChanged(mapThemeId); 0906 0907 setInvertColorEnabled(invertColor); 0908 } 0909 0910 void MarbleQuickItem::setShowAtmosphere(bool showAtmosphere) 0911 { 0912 if (this->showAtmosphere() == showAtmosphere) { 0913 return; 0914 } 0915 0916 d->m_map.setShowAtmosphere(showAtmosphere); 0917 emit showAtmosphereChanged(showAtmosphere); 0918 } 0919 0920 void MarbleQuickItem::setShowCompass(bool showCompass) 0921 { 0922 if (this->showCompass() == showCompass) { 0923 return; 0924 } 0925 0926 d->m_map.setShowCompass(showCompass); 0927 emit showCompassChanged(showCompass); 0928 } 0929 0930 void MarbleQuickItem::setShowClouds(bool showClouds) 0931 { 0932 if (this->showClouds() == showClouds) { 0933 return; 0934 } 0935 0936 d->m_map.setShowClouds(showClouds); 0937 emit showCloudsChanged(showClouds); 0938 } 0939 0940 void MarbleQuickItem::setShowCrosshairs(bool showCrosshairs) 0941 { 0942 if (this->showCrosshairs() == showCrosshairs) { 0943 return; 0944 } 0945 0946 d->m_map.setShowCrosshairs(showCrosshairs); 0947 emit showCrosshairsChanged(showCrosshairs); 0948 } 0949 0950 void MarbleQuickItem::setShowGrid(bool showGrid) 0951 { 0952 if (this->showGrid() == showGrid) { 0953 return; 0954 } 0955 0956 d->m_map.setShowGrid(showGrid); 0957 emit showGridChanged(showGrid); 0958 } 0959 0960 void MarbleQuickItem::setShowOverviewMap(bool showOverviewMap) 0961 { 0962 if (this->showOverviewMap() == showOverviewMap) { 0963 return; 0964 } 0965 0966 d->m_map.setShowOverviewMap(showOverviewMap); 0967 emit showOverviewMapChanged(showOverviewMap); 0968 } 0969 0970 void MarbleQuickItem::setShowOtherPlaces(bool showOtherPlaces) 0971 { 0972 if (this->showOtherPlaces() == showOtherPlaces) { 0973 return; 0974 } 0975 0976 d->m_map.setShowOtherPlaces(showOtherPlaces); 0977 emit showOtherPlacesChanged(showOtherPlaces); 0978 } 0979 0980 void MarbleQuickItem::setShowScaleBar(bool showScaleBar) 0981 { 0982 if (d->m_showScaleBar == showScaleBar) { 0983 return; 0984 } 0985 0986 d->m_showScaleBar = showScaleBar; 0987 d->m_map.setShowScaleBar(d->m_showScaleBar); 0988 emit showScaleBarChanged(showScaleBar); 0989 } 0990 0991 void MarbleQuickItem::setShowBackground(bool showBackground) 0992 { 0993 if (this->showBackground() == showBackground) { 0994 return; 0995 } 0996 0997 d->m_map.setShowBackground(showBackground); 0998 emit showBackgroundChanged(showBackground); 0999 } 1000 1001 void MarbleQuickItem::setShowPositionMarker(bool showPositionMarker) 1002 { 1003 if (this->showPositionMarker() == showPositionMarker) { 1004 return; 1005 } 1006 1007 QList<RenderPlugin *> plugins = d->m_map.renderPlugins(); 1008 for ( RenderPlugin * plugin: plugins ) { 1009 if (plugin->nameId() == QLatin1String("positionMarker")) { 1010 plugin->setVisible(showPositionMarker); 1011 break; 1012 } 1013 } 1014 1015 emit showPositionMarkerChanged(showPositionMarker); 1016 } 1017 1018 void MarbleQuickItem::setShowPublicTransport(bool enabled) 1019 { 1020 if (d->m_showPublicTransport != enabled) { 1021 d->m_showPublicTransport = enabled; 1022 d->updateVisibleRoutes(); 1023 emit showPublicTransportChanged(enabled); 1024 } 1025 } 1026 1027 void MarbleQuickItem::setShowOutdoorActivities(bool showOutdoorActivities) 1028 { 1029 if (d->m_showOutdoorActivities != showOutdoorActivities) { 1030 d->m_showOutdoorActivities = showOutdoorActivities; 1031 d->updateVisibleRoutes(); 1032 emit showOutdoorActivitiesChanged(showOutdoorActivities); 1033 } 1034 } 1035 1036 void MarbleQuickItem::setPositionProvider(const QString &positionProvider) 1037 { 1038 QString name; 1039 if ( d->m_model.positionTracking()->positionProviderPlugin() ) { 1040 name = d->m_model.positionTracking()->positionProviderPlugin()->nameId(); 1041 if ( name == positionProvider ) { 1042 return; 1043 } 1044 } 1045 1046 if ( positionProvider.isEmpty() ) { 1047 d->m_model.positionTracking()->setPositionProviderPlugin( nullptr ); 1048 return; 1049 } 1050 1051 QList<const PositionProviderPlugin*> plugins = d->m_model.pluginManager()->positionProviderPlugins(); 1052 for (const PositionProviderPlugin* plugin: plugins) { 1053 if ( plugin->nameId() == positionProvider) { 1054 PositionProviderPlugin * newPlugin = plugin->newInstance(); 1055 d->m_model.positionTracking()->setPositionProviderPlugin(newPlugin); 1056 connect(newPlugin, SIGNAL(statusChanged(PositionProviderStatus)), this, SLOT(positionDataStatusChanged(PositionProviderStatus))); 1057 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SLOT(updateCurrentPosition(GeoDataCoordinates))); 1058 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(speedChanged())); 1059 connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(angleChanged())); 1060 emit positionProviderChanged(positionProvider); 1061 break; 1062 } 1063 } 1064 } 1065 1066 void MarbleQuickItem::setInertialGlobeRotation(bool inertialGlobeRotation) 1067 { 1068 if (inertialGlobeRotation == d->m_inputHandler.inertialEarthRotationEnabled()) { 1069 return; 1070 } 1071 1072 d->m_inputHandler.setInertialEarthRotationEnabled(inertialGlobeRotation); 1073 emit inertialGlobeRotationChanged(inertialGlobeRotation); 1074 } 1075 1076 void MarbleQuickItem::setAnimationViewContext(bool animationViewContext) 1077 { 1078 d->m_map.setViewContext(animationViewContext ? Animation : Still ); 1079 1080 emit inertialGlobeRotationChanged(animationViewContext); 1081 } 1082 1083 void MarbleQuickItem::setAnimationsEnabled(bool animationsEnabled) 1084 { 1085 if (d->m_presenter.animationsEnabled() == animationsEnabled) 1086 return; 1087 1088 d->m_presenter.setAnimationsEnabled(animationsEnabled); 1089 emit animationsEnabledChanged(d->m_presenter.animationsEnabled()); 1090 } 1091 1092 void MarbleQuickItem::setPluginSetting(const QString &pluginId, const QString &key, const QString &value) 1093 { 1094 for (RenderPlugin* plugin: d->m_map.renderPlugins()) { 1095 if (plugin->nameId() == pluginId) { 1096 plugin->setSetting(key, value); 1097 } 1098 } 1099 } 1100 1101 void MarbleQuickItem::setPropertyEnabled(const QString &property, bool enabled) 1102 { 1103 d->m_map.setPropertyValue(property, enabled); 1104 } 1105 1106 bool MarbleQuickItem::isPropertyEnabled(const QString &property) const 1107 { 1108 return d->m_map.propertyValue(property); 1109 } 1110 1111 void MarbleQuickItem::setWorkOffline(bool enabled) 1112 { 1113 if (d->m_map.model()->workOffline() == enabled) 1114 return; 1115 1116 else { 1117 d->m_map.model()->setWorkOffline(enabled); 1118 } 1119 } 1120 1121 void MarbleQuickItem::setInvertColorEnabled(bool enabled, const QString &blendingName) 1122 { 1123 d->changeBlending(enabled, blendingName); 1124 1125 d->changeStyleBuilder(enabled); 1126 1127 if (d->m_invertColorEnabled == enabled) 1128 return; 1129 1130 d->m_invertColorEnabled = enabled; 1131 1132 emit invertColorEnabledChanged(d->m_invertColorEnabled); 1133 } 1134 1135 bool MarbleQuickItem::invertColorEnabled() 1136 { 1137 return d->m_invertColorEnabled; 1138 } 1139 1140 bool MarbleQuickItem::workOffline() 1141 { 1142 return d->m_map.model()->workOffline(); 1143 } 1144 1145 void MarbleQuickItem::setShowRuntimeTrace(bool showRuntimeTrace) 1146 { 1147 d->m_map.setShowRuntimeTrace(showRuntimeTrace); 1148 update(); 1149 } 1150 1151 void MarbleQuickItem::setShowDebugPolygons(bool showDebugPolygons) 1152 { 1153 d->m_map.setShowDebugPolygons(showDebugPolygons); 1154 update(); 1155 } 1156 1157 void MarbleQuickItem::setShowDebugPlacemarks(bool showDebugPlacemarks) 1158 { 1159 d->m_map.setShowDebugPlacemarks(showDebugPlacemarks); 1160 update(); 1161 } 1162 1163 void MarbleQuickItem::setShowDebugBatches(bool showDebugBatches) 1164 { 1165 d->m_map.setShowDebugBatchRender(showDebugBatches); 1166 update(); 1167 } 1168 1169 void MarbleQuickItem::setPlacemarkDelegate(QQmlComponent *placemarkDelegate) 1170 { 1171 if (d->m_placemarkDelegate == placemarkDelegate) { 1172 return; 1173 } 1174 1175 delete d->m_placemarkItem; 1176 d->m_placemarkItem = nullptr; 1177 d->m_placemarkDelegate = placemarkDelegate; 1178 emit placemarkDelegateChanged(placemarkDelegate); 1179 } 1180 1181 void MarbleQuickItem::loadSettings() 1182 { 1183 QSettings settings; 1184 settings.beginGroup(QStringLiteral("MarbleQuickItem")); 1185 double lon = settings.value(QStringLiteral("centerLon"), QVariant(0.0)).toDouble(); 1186 double lat = settings.value(QStringLiteral("centerLat"), QVariant(0.0)).toDouble(); 1187 if (lat == 0.0 && lon == 0.0) { 1188 centerOnCurrentPosition(); 1189 } else { 1190 centerOn(lon, lat); 1191 } 1192 int const zoom = settings.value(QStringLiteral("zoom"), QVariant(0)).toInt(); 1193 if (zoom > 0) { 1194 setZoom(zoom); 1195 } 1196 auto const defaultRelationTypes = QStringList() << "ferry" << "train" << "subway" << "tram" << "bus" << "trolley-bus" << "hiking"; 1197 auto const visibleRelationTypes = settings.value(QStringLiteral("visibleRelationTypes"), defaultRelationTypes).toStringList(); 1198 d->m_enabledRelationTypes = GeoDataRelation::UnknownType; 1199 for (auto const &route: visibleRelationTypes) { 1200 d->m_enabledRelationTypes |= d->m_relationTypeConverter.value(route, GeoDataRelation::UnknownType); 1201 } 1202 setShowPublicTransport(settings.value(QStringLiteral("showPublicTransport"), false).toBool()); 1203 setShowOutdoorActivities(settings.value(QStringLiteral("showOutdoorActivities"), false).toBool()); 1204 settings.endGroup(); 1205 d->m_model.routingManager()->readSettings(); 1206 d->m_model.bookmarkManager()->loadFile(QStringLiteral("bookmarks/bookmarks.kml")); 1207 d->m_model.bookmarkManager()->setShowBookmarks(true); 1208 d->updateVisibleRoutes(); 1209 } 1210 1211 void MarbleQuickItem::writeSettings() 1212 { 1213 QSettings settings; 1214 settings.beginGroup(QStringLiteral("MarbleQuickItem")); 1215 settings.setValue(QStringLiteral("centerLon"), QVariant(d->m_map.centerLongitude())); 1216 settings.setValue(QStringLiteral("centerLat"), QVariant(d->m_map.centerLatitude())); 1217 settings.setValue(QStringLiteral("zoom"), QVariant(zoom())); 1218 QStringList enabledRoutes; 1219 QMap<GeoDataRelation::RelationType, QString> relationConverter; 1220 for (auto iter = d->m_relationTypeConverter.cbegin(), end = d->m_relationTypeConverter.cend(); iter != end; ++iter) { 1221 relationConverter[iter.value()] = iter.key(); 1222 } 1223 for (auto iter = relationConverter.cbegin(), end = relationConverter.cend(); iter != end; ++iter) { 1224 if (d->m_enabledRelationTypes & iter.key()) { 1225 enabledRoutes << iter.value(); 1226 } 1227 } 1228 settings.setValue(QStringLiteral("visibleRelationTypes"), enabledRoutes); 1229 settings.setValue(QStringLiteral("showPublicTransport"), d->m_showPublicTransport); 1230 settings.setValue(QStringLiteral("showOutdoorActivities"), d->m_showOutdoorActivities); 1231 1232 settings.endGroup(); 1233 d->m_model.routingManager()->writeSettings(); 1234 } 1235 1236 void MarbleQuickItem::reloadTiles() 1237 { 1238 d->m_map.reload(); 1239 } 1240 1241 void MarbleQuickItem::highlightRouteRelation(qint64 osmId, bool enabled) 1242 { 1243 d->m_map.highlightRouteRelation(osmId, enabled); 1244 } 1245 1246 void MarbleQuickItem::setRelationTypeVisible(const QString &relationType, bool visible) 1247 { 1248 auto const relation = d->m_relationTypeConverter.value(relationType, GeoDataRelation::UnknownType); 1249 if (visible) { 1250 d->m_enabledRelationTypes |= relation; 1251 } else { 1252 d->m_enabledRelationTypes &= ~relation; 1253 } 1254 d->updateVisibleRoutes(); 1255 } 1256 1257 bool MarbleQuickItem::isRelationTypeVisible(const QString &relationType) const 1258 { 1259 auto const relation = d->m_relationTypeConverter.value(relationType, GeoDataRelation::UnknownType); 1260 return d->m_enabledRelationTypes & relation; 1261 } 1262 1263 QObject *MarbleQuickItem::getEventFilter() const 1264 { //We would want to install the same event filter for abstract layer QuickItems such as PinchArea 1265 return &d->m_inputHandler; 1266 } 1267 1268 void MarbleQuickItem::pinch(const QPointF& center, qreal scale, Qt::GestureState state) 1269 { 1270 d->m_inputHandler.pinch(center, scale, state); 1271 } 1272 1273 MarbleInputHandler *MarbleQuickItem::inputHandler() 1274 { 1275 return &d->m_inputHandler; 1276 } 1277 1278 int MarbleQuickItem::radius() const 1279 { 1280 return d->m_map.radius(); 1281 } 1282 1283 qreal MarbleQuickItem::heading() const 1284 { 1285 return d->m_map.heading(); 1286 } 1287 1288 1289 int MarbleQuickItem::zoom() const 1290 { 1291 return d->m_presenter.logzoom(); 1292 } 1293 1294 int MarbleQuickItem::minimumZoom() const 1295 { 1296 return d->m_presenter.minimumZoom(); 1297 } 1298 1299 int MarbleQuickItem::maximumZoom() const 1300 { 1301 return d->m_presenter.maximumZoom(); 1302 } 1303 1304 bool MarbleQuickItem::layersEventFilter(QObject *, QEvent *) 1305 { //Does nothing, but can be reimplemented in a subclass 1306 return false; 1307 } 1308 1309 QuickItemSelectionRubber::QuickItemSelectionRubber() : 1310 m_visible(false) 1311 { 1312 // nothing to do 1313 } 1314 1315 void MarbleQuickItemPrivate::updateVisibleRoutes() 1316 { 1317 GeoDataRelation::RelationTypes relationTypes = m_enabledRelationTypes; 1318 if (!m_showPublicTransport) { 1319 relationTypes &= ~GeoDataRelation::RouteTrain; 1320 relationTypes &= ~GeoDataRelation::RouteSubway; 1321 relationTypes &= ~GeoDataRelation::RouteTram; 1322 relationTypes &= ~GeoDataRelation::RouteBus; 1323 relationTypes &= ~GeoDataRelation::RouteTrolleyBus; 1324 } 1325 if (!m_showOutdoorActivities) { 1326 relationTypes &= ~GeoDataRelation::RouteBicycle; 1327 relationTypes &= ~GeoDataRelation::RouteMountainbike; 1328 relationTypes &= ~GeoDataRelation::RouteFoot; 1329 relationTypes &= ~GeoDataRelation::RouteHiking; 1330 relationTypes &= ~GeoDataRelation::RouteHorse; 1331 relationTypes &= ~GeoDataRelation::RouteInlineSkates; 1332 relationTypes &= ~GeoDataRelation::RouteSkiDownhill; 1333 relationTypes &= ~GeoDataRelation::RouteSkiNordic; 1334 relationTypes &= ~GeoDataRelation::RouteSkitour; 1335 relationTypes &= ~GeoDataRelation::RouteSled; 1336 } 1337 m_map.setVisibleRelationTypes(relationTypes); 1338 } 1339 1340 void MarbleQuickItemPrivate::changeBlending(bool enabled, const QString &blendingName) 1341 { 1342 GeoSceneDocument * mapTheme = m_map.model()->mapTheme(); 1343 if (mapTheme == nullptr) return; 1344 1345 GeoSceneMap * map = mapTheme->map(); 1346 if (map == nullptr) return; 1347 1348 GeoSceneTextureTileDataset * textureDataset = nullptr; 1349 if (map->hasTextureLayers()) { 1350 for (auto layer : map->layers()) { 1351 for (auto dataset : layer->datasets()) { 1352 if (dataset->nodeType() == GeoSceneTypes::GeoSceneTextureTileType) { 1353 textureDataset = dynamic_cast<GeoSceneTextureTileDataset*>(dataset); 1354 break; 1355 } 1356 } 1357 } 1358 if (textureDataset == nullptr) return; 1359 if (enabled && textureDataset->blending().isEmpty()) { 1360 textureDataset->setBlending(blendingName); 1361 m_map.clearVolatileTileCache(); 1362 } 1363 else if (!enabled && textureDataset->blending() == blendingName) { 1364 textureDataset->setBlending(""); 1365 m_map.clearVolatileTileCache(); 1366 } 1367 } 1368 } 1369 1370 void MarbleQuickItemPrivate::changeStyleBuilder(bool invert) 1371 { 1372 GeoSceneDocument * mapTheme = m_map.model()->mapTheme(); 1373 if (mapTheme == nullptr) return; 1374 1375 GeoSceneMap * map = mapTheme->map(); 1376 if (map == nullptr) return; 1377 1378 if (map->hasVectorLayers()) { 1379 StyleBuilder * styleBuilder = const_cast<StyleBuilder*>(m_map.styleBuilder()); 1380 1381 if (invert) { 1382 styleBuilder->setStyleEffect(InvertedEffect); 1383 } 1384 else { 1385 styleBuilder->setStyleEffect(NoEffect); 1386 } 1387 styleBuilder->reset(); 1388 // trigger groundlayer update 1389 emit m_map.model()->themeChanged(QString()); 1390 } 1391 } 1392 } 1393 1394 #include "moc_MarbleQuickItem.cpp"