Marble

MarbleQuickItem.cpp
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 <QQuickWindow>
9#include <QScreen>
10#include <QPainter>
11#include <QPaintDevice>
12#include <QtMath>
13#include <QQmlContext>
14#include <QSettings>
15
16#include <MarbleModel.h>
17#include <MarbleMap.h>
18#include <ViewportParams.h>
19#include <GeoPainter.h>
20#include <GeoDataLookAt.h>
21#include <Planet.h>
22#include <MarbleAbstractPresenter.h>
23#include <AbstractFloatItem.h>
24#include <MarbleInputHandler.h>
25#include <PositionTracking.h>
26#include <PositionProviderPlugin.h>
27#include <PluginManager.h>
28#include <RenderPlugin.h>
29#include <MarbleMath.h>
30#include <StyleBuilder.h>
31#include <GeoDataLatLonAltBox.h>
32#include <GeoDataCoordinates.h>
33#include <ReverseGeocodingRunnerManager.h>
34#include <routing/RoutingManager.h>
35#include <routing/RoutingModel.h>
36#include <routing/Route.h>
37#include <BookmarkManager.h>
38#include "GeoDataRelation.h"
39#include "osm/OsmPlacemarkData.h"
40#include "GeoDataDocument.h"
41#include <geodata/parser/GeoSceneTypes.h>
42#include <geodata/scene/GeoSceneDocument.h>
43#include <geodata/scene/GeoSceneMap.h>
44#include <geodata/scene/GeoSceneLayer.h>
45#include <geodata/scene/GeoSceneTextureTileDataset.h>
46
47namespace Marble
48{
49 //TODO - move to separate files
50 class QuickItemSelectionRubber : public AbstractSelectionRubber
51 { //TODO: support rubber selection in MarbleQuickItem
52 public:
53 QuickItemSelectionRubber();
54 void show() override { m_visible = true; }
55 void hide() override { m_visible = false; }
56 bool isVisible() const override { return m_visible; }
57 const QRect &geometry() const override { return m_geometry; }
58 void setGeometry(const QRect &/*geometry*/) override {}
59 private:
60 QRect m_geometry;
61 bool m_visible;
62 };
63
64 //TODO - implement missing functionalities
65 class MarbleQuickInputHandler : public MarbleDefaultInputHandler
66 {
67 public:
68 MarbleQuickInputHandler(MarbleAbstractPresenter *marblePresenter, MarbleQuickItem *marbleQuick)
69 : MarbleDefaultInputHandler(marblePresenter)
70 ,m_marbleQuick(marbleQuick)
71 {
72 setInertialEarthRotationEnabled(false); //Disabled by default, it's buggy. TODO - fix
73 }
74
75 bool acceptMouse() override
76 {
77 return true;
78 }
79
80 void pinch(QPointF center, qreal scale, Qt::GestureState state)
81 { //TODO - this whole thing should be moved to MarbleAbstractPresenter
82 (void)handlePinch(center, scale, state);
83 }
84
85 void handleMouseButtonPressAndHold(const QPoint &position) override
86 {
87 m_marbleQuick->reverseGeocoding(position);
88 }
89
90 private Q_SLOTS:
91 void showLmbMenu(int x, int y) override
92 {
93 m_marbleQuick->selectPlacemarkAt(x, y);
94 emit m_marbleQuick->lmbMenuRequested(QPoint(x,y));
95 }
96
97 void showRmbMenu(int x, int y) override {
98 emit m_marbleQuick->rmbMenuRequested(QPoint(x,y));
99 }
100 void openItemToolTip() override {}
101 void setCursor(const QCursor &cursor) override
102 {
103 m_marbleQuick->setCursor(cursor);
104 }
105
106 private Q_SLOTS:
107 void installPluginEventFilter(RenderPlugin *) override {}
108
109 private:
110 bool layersEventFilter(QObject *o, QEvent *e) override
111 {
112 return m_marbleQuick->layersEventFilter(o, e);
113 }
114
115 //empty - don't check. It would be invalid with quick items
116 void checkReleasedMove(QMouseEvent *) override {}
117
118 bool handleTouch(QTouchEvent *event) override
119 {
120 if (event->touchPoints().count() > 1)
121 { //not handling multi-touch at all, let PinchArea or MultiPointTouchArea take care of it
122 return false;
123 }
124
125 if (event->touchPoints().count() == 1)
126 { //handle - but do not accept. I.e. pinchArea still needs to get this
127 QTouchEvent::TouchPoint p = event->touchPoints().at(0);
128 if (event->type() == QEvent::TouchBegin)
129 {
132 handleMouseEvent(&press);
133 }
134 else if (event->type() == QEvent::TouchUpdate)
135 {
138 handleMouseEvent(&move);
139 }
140 else if (event->type() == QEvent::TouchEnd)
141 {
144 handleMouseEvent(&release);
145 }
146 }
147 return false;
148 }
149
150 AbstractSelectionRubber *selectionRubber() override
151 {
152 return &m_selectionRubber;
153 }
154
155 MarbleQuickItem *m_marbleQuick;
156 QuickItemSelectionRubber m_selectionRubber;
157// bool m_usePinchArea;
158 };
159
160 class MarbleQuickItemPrivate
161 {
162 public:
163 explicit MarbleQuickItemPrivate(MarbleQuickItem *marble) :
164 m_marble(marble),
165 m_model(),
166 m_map(&m_model),
167 m_presenter(&m_map),
168 m_positionVisible(false),
169 m_currentPosition(marble),
170 m_inputHandler(&m_presenter, marble),
171 m_placemarkDelegate(nullptr),
172 m_placemarkItem(nullptr),
173 m_placemark(nullptr),
174 m_reverseGeocoding(&m_model),
175 m_showScaleBar(false),
176 m_enabledRelationTypes(GeoDataRelation::RouteFerry |
177 GeoDataRelation::RouteTrain |
178 GeoDataRelation::RouteSubway |
179 GeoDataRelation::RouteTram |
180 GeoDataRelation::RouteBus |
181 GeoDataRelation::RouteTrolleyBus |
182 GeoDataRelation::RouteHiking),
183 m_showPublicTransport(false),
184 m_showOutdoorActivities(false),
185 m_heading(0.0),
186 m_hoverEnabled(false),
187 m_invertColorEnabled(false)
188 {
189 m_currentPosition.setName(QObject::tr("Current Location"));
190 m_relationTypeConverter["road"] = GeoDataRelation::RouteRoad;
191 m_relationTypeConverter["detour"] = GeoDataRelation::RouteDetour;
192 m_relationTypeConverter["ferry"] = GeoDataRelation::RouteFerry;
193 m_relationTypeConverter["train"] = GeoDataRelation::RouteTrain;
194 m_relationTypeConverter["subway"] = GeoDataRelation::RouteSubway;
195 m_relationTypeConverter["tram"] = GeoDataRelation::RouteTram;
196 m_relationTypeConverter["bus"] = GeoDataRelation::RouteBus;
197 m_relationTypeConverter["trolley-bus"] = GeoDataRelation::RouteTrolleyBus;
198 m_relationTypeConverter["bicycle"] = GeoDataRelation::RouteBicycle;
199 m_relationTypeConverter["mountainbike"] = GeoDataRelation::RouteMountainbike;
200 m_relationTypeConverter["foot"] = GeoDataRelation::RouteFoot;
201 m_relationTypeConverter["hiking"] = GeoDataRelation::RouteHiking;
202 m_relationTypeConverter["horse"] = GeoDataRelation::RouteHorse;
203 m_relationTypeConverter["inline-skates"] = GeoDataRelation::RouteInlineSkates;
204 m_relationTypeConverter["downhill"] = GeoDataRelation::RouteSkiDownhill;
205 m_relationTypeConverter["ski-nordic"] = GeoDataRelation::RouteSkiNordic;
206 m_relationTypeConverter["skitour"] = GeoDataRelation::RouteSkitour;
207 m_relationTypeConverter["sled"] = GeoDataRelation::RouteSled;
208 }
209
210 void updateVisibleRoutes();
211 void changeBlending(bool enabled, const QString &blendingName);
212 void changeStyleBuilder(bool invert);
213
214 private:
215 MarbleQuickItem *m_marble;
216 friend class MarbleQuickItem;
217 MarbleModel m_model;
218 MarbleMap m_map;
219 Marble::MapTheme m_mapTheme;
220 MarbleAbstractPresenter m_presenter;
221 bool m_positionVisible;
222 Placemark m_currentPosition;
223
224 MarbleQuickInputHandler m_inputHandler;
225 QQmlComponent* m_placemarkDelegate;
226 QQuickItem* m_placemarkItem;
227 Placemark* m_placemark;
228 ReverseGeocodingRunnerManager m_reverseGeocoding;
229
230 bool m_showScaleBar;
231 QMap<QString, GeoDataRelation::RelationType> m_relationTypeConverter;
232 GeoDataRelation::RelationTypes m_enabledRelationTypes;
233 bool m_showPublicTransport;
234 bool m_showOutdoorActivities;
235 qreal m_heading;
236 bool m_hoverEnabled;
237 bool m_invertColorEnabled;
238 };
239
240 MarbleQuickItem::MarbleQuickItem(QQuickItem *parent) : QQuickPaintedItem(parent)
241 ,d(new MarbleQuickItemPrivate(this))
242 {
244 setOpaquePainting(true);
245 qRegisterMetaType<Placemark*>("Placemark*");
246 d->m_map.setMapQualityForViewContext(NormalQuality, Animation);
247
248 for (AbstractFloatItem *item: d->m_map.floatItems()) {
249 if (item->nameId() == QLatin1String("license")) {
250 item->setPosition(QPointF(5.0, -10.0));
251 } else {
252 item->hide();
253 }
254 }
255
256 d->m_model.positionTracking()->setTrackVisible(false);
257 d->m_mapTheme.setMap(this);
258
259 connect(&d->m_map, SIGNAL(repaintNeeded(QRegion)), this, SLOT(update()));
260 connect(this, &MarbleQuickItem::widthChanged, this, &MarbleQuickItem::resizeMap);
261 connect(this, &MarbleQuickItem::heightChanged, this, &MarbleQuickItem::resizeMap);
262 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::updatePositionVisibility);
263 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::radiusChanged);
264 connect(&d->m_map, &MarbleMap::radiusChanged, this, &MarbleQuickItem::zoomChanged);
265 connect(&d->m_reverseGeocoding, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)),
266 this, SLOT(handleReverseGeocoding(GeoDataCoordinates,GeoDataPlacemark)));
267 connect(&d->m_map, &MarbleMap::visibleLatLonAltBoxChanged, this, &MarbleQuickItem::handleVisibleLatLonAltBoxChanged);
268 connect(d->m_map.model(), &MarbleModel::workOfflineChanged, this, &MarbleQuickItem::workOfflineChanged);
269
270 setAcceptedMouseButtons(Qt::AllButtons);
271 installEventFilter(&d->m_inputHandler);
272 }
273
274 void MarbleQuickItem::resizeMap()
275 {
276
277 d->m_map.setSize(qMax(100, int(width())), qMax(100, int(height())));
278 update();
279 updatePositionVisibility();
280 }
281
282 void MarbleQuickItem::positionDataStatusChanged(PositionProviderStatus status)
283 {
284 bool const positionAvailable = status == PositionProviderStatusAvailable;
285 emit positionAvailableChanged(positionAvailable);
286 updatePositionVisibility();
287 }
288
289 void MarbleQuickItem::positionChanged(const GeoDataCoordinates &, GeoDataAccuracy)
290 {
291 updatePositionVisibility();
292 }
293
294 void MarbleQuickItem::updatePositionVisibility()
295 {
296 updatePlacemarks();
297 bool isVisible = false;
298 if ( positionAvailable() ) {
299 qreal x, y;
300 bool globeHidesPoint;
301 bool const valid = d->m_map.viewport()->screenCoordinates(d->m_model.positionTracking()->currentLocation(), x, y, globeHidesPoint);
302 isVisible = valid && !globeHidesPoint;
303 }
304
305 if ( isVisible != d->m_positionVisible ) {
306 d->m_positionVisible = isVisible;
307 emit positionVisibleChanged( isVisible );
308 }
309 }
310
311 void MarbleQuickItem::updateCurrentPosition(const GeoDataCoordinates &coordinates)
312 {
313 d->m_currentPosition.placemark().setCoordinate(coordinates);
314 emit currentPositionChanged(&d->m_currentPosition);
315 }
316
317 void MarbleQuickItem::updatePlacemarks()
318 {
319 if (!d->m_placemarkDelegate || !d->m_placemark) {
320 return;
321 }
322
323 if (!d->m_placemarkItem) {
324 QQmlContext * context = new QQmlContext(qmlContext(d->m_placemarkDelegate));
325 QObject * component = d->m_placemarkDelegate->create(context);
326 d->m_placemarkItem = qobject_cast<QQuickItem*>( component );
327 if (d->m_placemarkItem) {
328 d->m_placemarkItem->setParentItem( this );
329 d->m_placemarkItem->setProperty("placemark", QVariant::fromValue(d->m_placemark));
330 } else {
331 delete component;
332 return;
333 }
334 }
335
336 qreal x = 0;
337 qreal y = 0;
338 const bool visible = d->m_map.viewport()->screenCoordinates(d->m_placemark->placemark().coordinate(), x, y);
339 d->m_placemarkItem->setVisible(visible);
340 if (visible) {
341 d->m_placemarkItem->setProperty("xPos", QVariant(x));
342 d->m_placemarkItem->setProperty("yPos", QVariant(y));
343 }
344 }
345
346 void MarbleQuickItem::handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark)
347 {
348 if (d->m_placemark && d->m_placemark->placemark().coordinate() == coordinates) {
349 d->m_placemark->setGeoDataPlacemark(placemark);
350 updatePlacemarks();
351 }
352 }
353
354 void MarbleQuickItem::handleVisibleLatLonAltBoxChanged(const GeoDataLatLonAltBox &latLonAltBox)
355 {
356 Q_UNUSED(latLonAltBox)
357
358 if (d->m_heading != d->m_map.heading()) {
359 d->m_heading = d->m_map.heading();
360 emit headingChanged(d->m_heading);
361 }
362 emit visibleLatLonAltBoxChanged();
363 emit geoItemUpdateRequested();
364 }
365
366 void MarbleQuickItem::paint(QPainter *painter)
367 { //TODO - much to be done here still, i.e paint !enabled version
368 QPaintDevice * paintDevice = painter->device();
369 QRect rect = contentsBoundingRect().toRect();
370
371 painter->end();
372 {
373 GeoPainter geoPainter(paintDevice, d->m_map.viewport(), d->m_map.mapQuality());
374
375 double scale = 1.0;
376 // For HighDPI displays take QT_SCALE_FACTOR into account:
377 QQuickWindow * window = this->window();
378 if (window) {
379 QScreen * screen = window->screen();
380 scale = screen != nullptr ? screen->devicePixelRatio() : 1.0;
381 if (scale != 1) {
382 geoPainter.scale(scale, scale);
383 }
384 }
385
386 d->m_map.paint(geoPainter, rect);
387 }
388 painter->begin(paintDevice);
389 }
390
391 void MarbleQuickItem::classBegin()
392 {
393 }
394
395 void MarbleQuickItem::componentComplete()
396 {
397 }
398
399 void Marble::MarbleQuickItem::MarbleQuickItem::hoverMoveEvent(QHoverEvent *event) {
400 if (d->m_hoverEnabled) {
401 emit hoverPositionChanged(event->pos());
402 }
404 }
405
406 int MarbleQuickItem::mapWidth() const
407 {
408 return d->m_map.width();
409 }
410
411 int MarbleQuickItem::mapHeight() const
412 {
413 return d->m_map.height();
414 }
415
416 bool MarbleQuickItem::showFrameRate() const
417 {
418 return d->m_map.showFrameRate();
419 }
420
421 MarbleQuickItem::Projection MarbleQuickItem::projection() const
422 {
423 return Projection(d->m_map.projection());
424 }
425
426 QString MarbleQuickItem::mapThemeId() const
427 {
428 return d->m_map.mapThemeId();
429 }
430
431 Marble::MapTheme *MarbleQuickItem::mapTheme() const
432 {
433 return &d->m_mapTheme;
434 }
435
436 bool MarbleQuickItem::showAtmosphere() const
437 {
438 return d->m_map.showAtmosphere();
439 }
440
441 bool MarbleQuickItem::showCompass() const
442 {
443 return d->m_map.showCompass();
444 }
445
446 bool MarbleQuickItem::showClouds() const
447 {
448 return d->m_map.showClouds();
449 }
450
451 bool MarbleQuickItem::showCrosshairs() const
452 {
453 return d->m_map.showCrosshairs();
454 }
455
456 bool MarbleQuickItem::showGrid() const
457 {
458 return d->m_map.showGrid();
459 }
460
461 bool MarbleQuickItem::showOverviewMap() const
462 {
463 return d->m_map.showOverviewMap();
464 }
465
466 bool MarbleQuickItem::showOtherPlaces() const
467 {
468 return d->m_map.showOtherPlaces();
469 }
470
471 bool MarbleQuickItem::showScaleBar() const
472 {
473 return d->m_showScaleBar;
474 }
475
476 bool MarbleQuickItem::showBackground() const
477 {
478 return d->m_map.showBackground();
479 }
480
481 bool MarbleQuickItem::showPositionMarker() const
482 {
483 QList<RenderPlugin *> plugins = d->m_map.renderPlugins();
484 for (const RenderPlugin * plugin: plugins) {
485 if (plugin->nameId() == QLatin1String("positionMarker")) {
486 return plugin->visible();
487 }
488 }
489 return false;
490 }
491
492 bool MarbleQuickItem::showPublicTransport() const
493 {
494 return d->m_showPublicTransport;
495 }
496
497 bool MarbleQuickItem::showOutdoorActivities() const
498 {
499 return d->m_showOutdoorActivities;
500 }
501
502 QString MarbleQuickItem::positionProvider() const
503 {
504 if ( d->m_model.positionTracking()->positionProviderPlugin() ) {
505 return d->m_model.positionTracking()->positionProviderPlugin()->nameId();
506 }
507
508 return QString();
509 }
510
511 MarbleModel* MarbleQuickItem::model()
512 {
513 return &d->m_model;
514 }
515
516 const MarbleModel* MarbleQuickItem::model() const
517 {
518 return &d->m_model;
519 }
520
521 MarbleMap* MarbleQuickItem::map()
522 {
523 return &d->m_map;
524 }
525
526 const MarbleMap* MarbleQuickItem::map() const
527 {
528 return &d->m_map;
529 }
530
531 bool MarbleQuickItem::inertialGlobeRotation() const
532 {
533 return d->m_inputHandler.inertialEarthRotationEnabled();
534 }
535
536 bool MarbleQuickItem::animationViewContext() const
537 {
538 return d->m_map.viewContext() == Animation;
539 }
540
541 bool MarbleQuickItem::animationsEnabled() const
542 {
543 return d->m_presenter.animationsEnabled();
544 }
545
546 QQmlComponent *MarbleQuickItem::placemarkDelegate() const
547 {
548 return d->m_placemarkDelegate;
549 }
550
551 void MarbleQuickItem::reverseGeocoding(const QPoint &point)
552 {
553 qreal lon, lat;
554 d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat);
555 auto const coordinates = GeoDataCoordinates(lon, lat, 0.0, GeoDataCoordinates::Degree);
556 delete d->m_placemarkItem;
557 d->m_placemarkItem = nullptr;
558 delete d->m_placemark;
559 d->m_placemark = new Placemark(this);
560 d->m_placemark->placemark().setCoordinate(coordinates);
561 d->m_reverseGeocoding.reverseGeocoding(coordinates);
562 }
563
564 bool MarbleQuickItem::hoverEnabled() const
565 {
566 return d->m_hoverEnabled;
567 }
568
569 void MarbleQuickItem::moveUp()
570 {
571 d->m_presenter.moveByStep( 0, -1, Marble::Linear );
572 }
573
574 void MarbleQuickItem::moveDown()
575 {
576 d->m_presenter.moveByStep( 0, 1, Marble::Linear );
577 }
578
579 void MarbleQuickItem::moveLeft()
580 {
581 d->m_presenter.moveByStep( -1, 0, Marble::Linear );
582 }
583
584 void MarbleQuickItem::moveRight()
585 {
586 d->m_presenter.moveByStep( 1, 0, Marble::Linear );
587 }
588
589 qreal MarbleQuickItem::speed() const
590 {
591 return d->m_model.positionTracking()->speed();
592 }
593
594 qreal MarbleQuickItem::angle() const
595 {
596 bool routeExists = d->m_model.routingManager()->routingModel()->route().distance() != 0.0;
597 bool onRoute = !d->m_model.routingManager()->routingModel()->deviatedFromRoute();
598 if ( routeExists && onRoute) {
599 GeoDataCoordinates curPoint = d->m_model.positionTracking()->positionProviderPlugin()->position();
600 return d->m_model.routingManager()->routingModel()->route().currentSegment().projectedDirection(curPoint);
601 } else {
602 return d->m_model.positionTracking()->direction();
603 }
604 }
605
606 bool MarbleQuickItem::positionAvailable() const
607 {
608 return d->m_model.positionTracking()->status() == PositionProviderStatusAvailable;
609 }
610
611 bool MarbleQuickItem::positionVisible() const
612 {
613 return d->m_positionVisible;
614 }
615
616 qreal MarbleQuickItem::distanceFromPointToCurrentLocation(const QPoint & position) const
617 {
618 if ( positionAvailable() ) {
619 qreal lon1;
620 qreal lat1;
621 d->m_map.viewport()->geoCoordinates(position.x(), position.y(), lon1, lat1, GeoDataCoordinates::Radian );
622
623 GeoDataCoordinates currentCoordinates = d->m_model.positionTracking()->currentLocation();
624 qreal lon2 = currentCoordinates.longitude();
625 qreal lat2 = currentCoordinates.latitude();
626
627 return distanceSphere(lon1, lat1, lon2, lat2) * d->m_model.planetRadius();
628 }
629 return 0;
630 }
631
632 qreal MarbleQuickItem::angleFromPointToCurrentLocation( const QPoint & position ) const
633 {
634 if ( positionAvailable() ) {
635 qreal x, y;
636 PositionTracking const * positionTracking = d->m_model.positionTracking();
637 map()->viewport()->screenCoordinates( positionTracking->currentLocation(), x, y );
638 return atan2( y-position.y(), x-position.x() ) * RAD2DEG;
639 }
640 return 0;
641 }
642
643 Placemark * MarbleQuickItem::currentPosition() const
644 {
645 return &d->m_currentPosition;
646 }
647
648 QPointF MarbleQuickItem::screenCoordinatesFromCoordinate(Coordinate * coordinate) const
649 {
650 qreal x, y;
651 bool globeHidesPoint;
652 bool const valid = d->m_map.viewport()->screenCoordinates(coordinate->coordinates(), x, y, globeHidesPoint);
653 bool isVisible = valid && !globeHidesPoint;
654 return isVisible ? QPointF(x, y) : QPointF();
655 }
656
657 QPointF MarbleQuickItem::screenCoordinatesFromGeoDataCoordinates(const GeoDataCoordinates & coordinates) const
658 {
659 qreal x, y;
660 bool globeHidesPoint;
661 d->m_map.viewport()->screenCoordinates(coordinates, x, y, globeHidesPoint);
662 return !globeHidesPoint ? QPointF(x, y) : QPointF();
663 }
664
665 bool MarbleQuickItem::screenCoordinatesFromGeoDataLineString(const GeoDataLineString &lineString, QVector<QPolygonF *> &polygons) const
666 {
667 return d->m_map.viewport()->screenCoordinates(lineString, polygons);
668 }
669
670 bool MarbleQuickItem::screenCoordinatesToCoordinate(const QPoint & point, Coordinate * coordinate)
671 {
672 GeoDataCoordinates geoDataCoordinates;
673 bool success = screenCoordinatesToGeoDataCoordinates(point, geoDataCoordinates);
674 if (!qobject_cast<Coordinate*>(coordinate)){
675 Coordinate * tmp(coordinate);
676 coordinate = new Coordinate(geoDataCoordinates.longitude(), geoDataCoordinates.latitude(), 0, nullptr);
678 delete tmp;
679 }
680 else {
681 coordinate->setLongitude(geoDataCoordinates.longitude());
682 coordinate->setLatitude(geoDataCoordinates.latitude());
683 }
684
685 return success;
686 }
687
688 bool MarbleQuickItem::screenCoordinatesToGeoDataCoordinates(const QPoint & point, GeoDataCoordinates & coordinates)
689 {
690 qreal lon = 0.0 , lat = 0.0;
691 bool const valid = d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat);
692 coordinates.setLongitude(lon);
693 coordinates.setLatitude(lat);
694 return valid;
695 }
696
697 void MarbleQuickItem::setRadius(int radius)
698 {
699 d->m_map.setRadius(radius);
700 }
701
702 void MarbleQuickItem::setHeading(qreal heading)
703 {
704 if (qFuzzyCompare(d->m_heading, heading))
705 return;
706
707 d->m_map.setHeading(heading);
708 d->m_heading = heading;
709
710 emit headingChanged(d->m_heading);
711 }
712
713 void MarbleQuickItem::setHoverEnabled(bool hoverEnabled)
714 {
715 if (d->m_hoverEnabled == hoverEnabled)
716 return;
717
718 d->m_hoverEnabled = hoverEnabled;
719
720 setAcceptHoverEvents(hoverEnabled);
721 setFlag(ItemAcceptsInputMethod, hoverEnabled);
722
723 emit hoverEnabledChanged(d->m_hoverEnabled);
724 }
725
726 void MarbleQuickItem::setZoom(int newZoom, FlyToMode mode)
727 {
728 d->m_presenter.setZoom(newZoom, mode);
729 }
730
731 void MarbleQuickItem::setZoomToMaximumLevel()
732 {
733 d->m_presenter.setZoom(d->m_map.maximumZoom());
734 }
735
736 void MarbleQuickItem::centerOn(const GeoDataPlacemark& placemark, bool animated)
737 {
738 d->m_presenter.centerOn(placemark, animated);
739 }
740
741 void MarbleQuickItem::centerOn(const GeoDataLatLonBox& box, bool animated)
742 {
743 d->m_presenter.centerOn(box, animated);
744 }
745
746 void MarbleQuickItem::centerOn(const GeoDataCoordinates &coordinate)
747 {
748 GeoDataLookAt target = d->m_presenter.lookAt();
749 target.setCoordinates(coordinate);
750 d->m_presenter.flyTo(target, Automatic);
751 }
752
753 void MarbleQuickItem::centerOn(qreal longitude, qreal latitude)
754 {
755 d->m_presenter.centerOn(longitude, latitude);
756 }
757
758 void MarbleQuickItem::centerOnCoordinates(qreal longitude, qreal latitude) {
759 centerOn(longitude, latitude);
760 }
761
762 void MarbleQuickItem::centerOnCurrentPosition()
763 {
764 GeoDataCoordinates coordinates = d->m_model.positionTracking()->currentLocation();
765 if ( coordinates == GeoDataCoordinates() ) {
766 return;
767 }
768
769 d->m_presenter.centerOn(coordinates, true);
770 if (d->m_presenter.zoom() < 3000) {
771 d->m_presenter.setZoom(3500);
772 }
773 }
774
775 void MarbleQuickItem::selectPlacemarkAt(int x, int y)
776 {
777 auto features = d->m_map.whichFeatureAt(QPoint(x, y));
779 for(auto feature: features) {
780 if (const auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
781 placemarks << placemark;
782 }
783 }
784
785 for(auto placemark: placemarks) {
786 if (d->m_placemark && placemark->coordinate() == d->m_placemark->placemark().coordinate()) {
787 d->m_placemark->deleteLater();
788 d->m_placemark = nullptr;
789 } else {
790 if (d->m_placemark) {
791 d->m_placemark->deleteLater();
792 }
793 d->m_placemark = new Placemark(this);
794 d->m_placemark->setGeoDataPlacemark(*placemark);
795 }
796 delete d->m_placemarkItem;
797 d->m_placemarkItem = nullptr;
798 updatePlacemarks();
799 return;
800 }
801
802 if (d->m_placemark) {
803 d->m_placemark->deleteLater();
804 d->m_placemark = nullptr;
805 delete d->m_placemarkItem;
806 d->m_placemarkItem = nullptr;
807 updatePlacemarks();
808 }
809 }
810
811 void MarbleQuickItem::goHome()
812 {
813 d->m_presenter.goHome();
814 }
815
816 void MarbleQuickItem::zoomIn(FlyToMode mode)
817 {
818 d->m_presenter.zoomIn(mode);
819 }
820
821 void MarbleQuickItem::zoomOut(FlyToMode mode)
822 {
823 d->m_presenter.zoomOut(mode);
824 }
825
826 void MarbleQuickItem::handlePinchStarted(const QPointF &point)
827 {
828 pinch(point, 1, Qt::GestureStarted);
829 }
830
831 void MarbleQuickItem::handlePinchFinished(const QPointF &point)
832 {
833 pinch(point, 1, Qt::GestureFinished);
834 }
835
836 void MarbleQuickItem::handlePinchUpdated(const QPointF &point, qreal scale)
837 {
838 scale = sqrt(sqrt(scale));
839 scale = qBound(static_cast<qreal>(0.5), scale, static_cast<qreal>(2.0));
840 pinch(point, scale, Qt::GestureUpdated);
841 }
842
843 void MarbleQuickItem::setMapWidth(int mapWidth)
844 {
845 if (d->m_map.width() == mapWidth) {
846 return;
847 }
848
849 d->m_map.setSize(mapWidth, mapHeight());
850 emit mapWidthChanged(mapWidth);
851 }
852
853 void MarbleQuickItem::setMapHeight(int mapHeight)
854 {
855 if (this->mapHeight() == mapHeight) {
856 return;
857 }
858
859 d->m_map.setSize(mapWidth(), mapHeight);
860 emit mapHeightChanged(mapHeight);
861 }
862
863 void MarbleQuickItem::setShowFrameRate(bool showFrameRate)
864 {
865 if (this->showFrameRate() == showFrameRate) {
866 return;
867 }
868
869 d->m_map.setShowFrameRate(showFrameRate);
870 emit showFrameRateChanged(showFrameRate);
871 }
872
873 void MarbleQuickItem::setProjection(Projection projection)
874 {
875 if (this->projection() == projection) {
876 return;
877 }
878
879 d->m_map.setProjection(Marble::Projection(projection));
880 emit projectionChanged(projection);
881 }
882
883 void MarbleQuickItem::setMapThemeId(const QString& mapThemeId)
884 {
885 if (this->mapThemeId() == mapThemeId) {
886 return;
887 }
888
889 bool invertColor = invertColorEnabled();
890
891 bool const showCompass = d->m_map.showCompass();
892 bool const showOverviewMap = d->m_map.showOverviewMap();
893 bool const showOtherPlaces = d->m_map.showOtherPlaces();
894 bool const showGrid = d->m_map.showGrid();
895
896 d->m_map.setMapThemeId(mapThemeId);
897
898 // Map themes are allowed to change properties. Enforce ours.
899 d->m_map.setShowCompass(showCompass);
900 d->m_map.setShowOverviewMap(showOverviewMap);
901 d->m_map.setShowOtherPlaces(showOtherPlaces);
902 d->m_map.setShowGrid(showGrid);
903 d->m_map.setShowScaleBar(d->m_showScaleBar);
904
905 emit mapThemeIdChanged(mapThemeId);
906
907 setInvertColorEnabled(invertColor);
908 }
909
910 void MarbleQuickItem::setShowAtmosphere(bool showAtmosphere)
911 {
912 if (this->showAtmosphere() == showAtmosphere) {
913 return;
914 }
915
916 d->m_map.setShowAtmosphere(showAtmosphere);
917 emit showAtmosphereChanged(showAtmosphere);
918 }
919
920 void MarbleQuickItem::setShowCompass(bool showCompass)
921 {
922 if (this->showCompass() == showCompass) {
923 return;
924 }
925
926 d->m_map.setShowCompass(showCompass);
927 emit showCompassChanged(showCompass);
928 }
929
930 void MarbleQuickItem::setShowClouds(bool showClouds)
931 {
932 if (this->showClouds() == showClouds) {
933 return;
934 }
935
936 d->m_map.setShowClouds(showClouds);
937 emit showCloudsChanged(showClouds);
938 }
939
940 void MarbleQuickItem::setShowCrosshairs(bool showCrosshairs)
941 {
942 if (this->showCrosshairs() == showCrosshairs) {
943 return;
944 }
945
946 d->m_map.setShowCrosshairs(showCrosshairs);
947 emit showCrosshairsChanged(showCrosshairs);
948 }
949
950 void MarbleQuickItem::setShowGrid(bool showGrid)
951 {
952 if (this->showGrid() == showGrid) {
953 return;
954 }
955
956 d->m_map.setShowGrid(showGrid);
957 emit showGridChanged(showGrid);
958 }
959
960 void MarbleQuickItem::setShowOverviewMap(bool showOverviewMap)
961 {
962 if (this->showOverviewMap() == showOverviewMap) {
963 return;
964 }
965
966 d->m_map.setShowOverviewMap(showOverviewMap);
967 emit showOverviewMapChanged(showOverviewMap);
968 }
969
970 void MarbleQuickItem::setShowOtherPlaces(bool showOtherPlaces)
971 {
972 if (this->showOtherPlaces() == showOtherPlaces) {
973 return;
974 }
975
976 d->m_map.setShowOtherPlaces(showOtherPlaces);
977 emit showOtherPlacesChanged(showOtherPlaces);
978 }
979
980 void MarbleQuickItem::setShowScaleBar(bool showScaleBar)
981 {
982 if (d->m_showScaleBar == showScaleBar) {
983 return;
984 }
985
986 d->m_showScaleBar = showScaleBar;
987 d->m_map.setShowScaleBar(d->m_showScaleBar);
988 emit showScaleBarChanged(showScaleBar);
989 }
990
991 void MarbleQuickItem::setShowBackground(bool showBackground)
992 {
993 if (this->showBackground() == showBackground) {
994 return;
995 }
996
997 d->m_map.setShowBackground(showBackground);
998 emit showBackgroundChanged(showBackground);
999 }
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;
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"
This file contains the headers for MarbleMap.
This file contains the headers for MarbleModel.
This file contains the headers for ViewportParams.
Represents a coordinate with the properties of a name and coordinates.
Definition Coordinate.h:19
void setLatitude(qreal lat)
Change the latitude of the coordinate.
void setLongitude(qreal lon)
Change the longitude of the coordinate.
Marble::GeoDataCoordinates coordinates() const
Change the altitude of the coordinate.
Q_SCRIPTABLE CaptureState status()
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void update(Part *part, const QByteArray &data, qint64 dataSize)
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
QWidget * window(QObject *job)
VehicleSection::Features features(QStringView coachNumber, QStringView coachClassification)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
const QList< QKeySequence > & end()
QString name(StandardShortcut id)
Binds a QML item to a specific geodetic location in screen coordinates.
@ Linear
Linear interpolation of lon, lat and distance to ground.
@ Still
still image
@ Animation
animated view (e.g. while rotating the globe)
Projection
This enum is used to choose the projection shown in the view.
qreal distanceSphere(qreal lon1, qreal lat1, qreal lon2, qreal lat2)
This method calculates the shortest distance between two points on a sphere.
Definition MarbleMath.h:46
void setObjectOwnership(QObject *object, ObjectOwnership ownership)
T value(qsizetype i) const const
const_iterator cbegin() const const
const_iterator cend() const const
Key key(const T &value, const Key &defaultKey) const const
Q_SLOTSQ_SLOTS
virtual bool event(QEvent *e)
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
bool begin(QPaintDevice *device)
QPaintDevice * device() const const
bool end()
int x() const const
int y() const const
virtual void hoverMoveEvent(QHoverEvent *event)
void setCursor(const QCursor &cursor)
void beginGroup(QAnyStringView prefix)
void endGroup()
void setValue(QAnyStringView key, const QVariant &value)
QVariant value(QAnyStringView key) const const
bool isEmpty() const const
GestureState
NoModifier
LeftButton
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
QStringList toStringList() const const
QScreen * screen() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.