Marble

MarbleQuickItem.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2014 Adam Dabrowski <[email protected]> <[email protected]>
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 
47 namespace 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  {
243  setRenderTarget(QQuickPaintedItem::FramebufferObject);
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 
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 }
GestureState
VehicleSection::Features features(QStringView coachNumber, QStringView coachClassification)
QVariant fromValue(const T &value)
void beginGroup(const QString &prefix)
Q_SLOTSQ_SLOTS
virtual void release(quint64 objid)
@ Animation
animated view (e.g. while rotating the globe)
Definition: MarbleGlobal.h:68
QScreen * screen() const const
int x() const const
int y() const const
@ Still
still image
Definition: MarbleGlobal.h:67
LeftButton
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QMap::const_iterator cbegin() const const
bool begin(QPaintDevice *device)
double toDouble(bool *ok) const const
bool end()
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
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
void setValue(const QString &key, const QVariant &value)
QMap::const_iterator cend() const const
void visibleLatLonAltBoxChanged(const GeoDataLatLonAltBox &visibleLatLonAltBox)
This signal is emitted when the visible region of the map changes.
void installEventFilter(QObject *filterObj)
Marble::GeoDataCoordinates coordinates() const
Change the altitude of the coordinate.
Definition: Coordinate.cpp:61
bool isEmpty() const const
Q_SCRIPTABLE CaptureState status()
QVariant value(const QString &key, const QVariant &defaultValue) const const
int toInt(bool *ok) const const
void setObjectOwnership(QObject *object, QQmlEngine::ObjectOwnership ownership)
Binds a QML item to a specific geodetic location in screen coordinates.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
FlyToMode
Describes possible flight mode (interpolation between source and target camera positions)
Definition: MarbleGlobal.h:162
const Key key(const T &value, const Key &defaultKey) const const
@ Automatic
A sane value is chosen automatically depending on animation settings and the action.
Definition: MarbleGlobal.h:163
Projection
This enum is used to choose the projection shown in the view.
Definition: MarbleGlobal.h:41
void endGroup()
bool setProperty(const char *name, const QVariant &value)
@ NormalQuality
Normal quality.
Definition: MarbleGlobal.h:77
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
QPointF pos() const const
void setLongitude(qreal lon)
Change the longitude of the coordinate.
Definition: Coordinate.cpp:33
@ Linear
Linear interpolation of lon, lat and distance to ground.
Definition: MarbleGlobal.h:165
void update(Part *part, const QByteArray &data, qint64 dataSize)
const char * name(StandardAction id)
void setLatitude(qreal lat)
Change the latitude of the coordinate.
Definition: Coordinate.cpp:44
QPaintDevice * device() const const
virtual void hoverMoveEvent(QHoverEvent *event)
QStringList toStringList() const const
Represents a coordinate with the properties of a name and coordinates.
Definition: Coordinate.h:18
KJOBWIDGETS_EXPORT QWidget * window(KJob *job)
NoModifier
QFuture< void > map(Sequence &sequence, MapFunctor function)
QString tr(const char *sourceText, const char *disambiguation, int n)
T value(int i) const const
Q_INVOKABLE void setProjection(uint proj)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 04:12:27 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.