KOSMIndoorMap

view.h
1 /*
2  SPDX-FileCopyrightText: 2020 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef KOSMINDOORMAP_VIEW_H
8 #define KOSMINDOORMAP_VIEW_H
9 
10 #include "kosmindoormap_export.h"
11 
12 #include <KOSM/Datatypes>
13 
14 #include <QDateTime>
15 #include <QObject>
16 #include <QRectF>
17 #include <QSize>
18 #include <QTransform>
19 
20 namespace KOSMIndoorMap {
21 
22 /** View transformations and transformation manipulation.
23  * There are three different coordinate systems involved here:
24  * - The geographic world coordinates of the OSM input data.
25  * This uses OSM::Coordinate.
26  * - The scene coordinates which have a the Web Mercator projection applied (see https://en.wikipedia.org/wiki/Mercator_projection).
27  * This uses QPointF ranging from 0x0 to 256x256
28  * - The screen coordinates (ie. visible pixels on screen).
29  * This uses QPoint.
30  * Further, there's also three slight variations of those in use here:
31  * - "HUD" coordinates: elements that follow the scene coordinates for their positioning,
32  * but the screen coordinates regarding scaling and rotation. This is used for map labels.
33  * - Geographic distances. This is needed to display things in a fixed width in meters in the scene,
34  * or to compute the map scale. Note that this only works due to the relatively high zoom levels,
35  * so that earth curvature or map projection effects are negligible.
36  * - "pan space": same transform as screen space, but with the origin at the origin of the scene bounding box
37  * This is useful for implementing scene-wide panning and showing scroll bars.
38  */
39 class KOSMINDOORMAP_EXPORT View : public QObject
40 {
41  Q_OBJECT
42  Q_PROPERTY(double panX READ panX NOTIFY transformationChanged)
43  Q_PROPERTY(double panY READ panY NOTIFY transformationChanged)
44  Q_PROPERTY(double panWidth READ panWidth NOTIFY transformationChanged)
45  Q_PROPERTY(double panHeight READ panHeight NOTIFY transformationChanged)
46  Q_PROPERTY(int floorLevel READ level WRITE setLevel NOTIFY floorLevelChanged)
47  Q_PROPERTY(double zoomLevel READ zoomLevel NOTIFY transformationChanged)
48  Q_PROPERTY(QDateTime beginTime READ beginTime WRITE setBeginTime NOTIFY timeChanged)
49  Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY timeChanged)
50 public:
51  explicit View(QObject *parent = nullptr);
52  ~View();
53 
54  /** Map a geographic coordinate to a scene coordinate, ie. apply the mercator projection. */
55  QPointF mapGeoToScene(OSM::Coordinate coord) const;
56  QRectF mapGeoToScene(OSM::BoundingBox box) const;
57  /** Map a scene coordinate to a geographic one, ie. apply the inverse mercator projection. */
58  OSM::Coordinate mapSceneToGeo(QPointF p) const;
59  OSM::BoundingBox mapSceneToGeo(const QRectF &box) const;
60 
61  /** Screen-space sizes, ie the size of the on-screen area used for displaying. */
62  int screenWidth() const;
63  int screenHeight() const;
64  void setScreenSize(QSize size);
65 
66  /** The transformation to apply to scene coordinate to get to the view on screen. */
67  QTransform sceneToScreenTransform() const;
68 
69  /** The (floor) level to display.
70  * @see MapLevel.
71  */
72  int level() const;
73  void setLevel(int level);
74 
75  /** OSM-compatible zoom level, ie. the 2^level-th subdivision of the scene space. */
76  double zoomLevel() const;
77  /** Set the zoom level to @p zoom, and adjusting it around center position @p center. */
78  Q_INVOKABLE void setZoomLevel(double zoom, QPointF screenCenter);
79 
80  /** The sub-rect of the scene bounding box currently displayed.
81  * Specified in scene coordinates.
82  */
83  QRectF viewport() const;
84  void setViewport(const QRectF &viewport);
85 
86  /** The bounding box of the scene.
87  * The viewport cannot exceed this area.
88  */
89  QRectF sceneBoundingBox() const;
90  void setSceneBoundingBox(OSM::BoundingBox bbox);
91  void setSceneBoundingBox(const QRectF &bbox);
92 
93  /** Converts a point in scene coordinates to screen coordinates. */
94  QPointF mapSceneToScreen(QPointF scenePos) const;
95  /** Converts a rectanble in scene coordinates to screen coordinates. */
96  QRectF mapSceneToScreen(const QRectF &sceneRect) const;
97  /** Converts a point in screen coordinates to scene coordinates. */
98  QPointF mapScreenToScene(QPointF screenPos) const;
99  /** Converts a distance in screen coordinates to a distance in scene coordinates. */
100  double mapScreenDistanceToSceneDistance(double distance) const;
101 
102  /** Returns how many units in scene coordinate represent the distance of @p meters in the current view transformation. */
103  double mapMetersToScene(double meters) const;
104  /** Returns how many pixels on screen represent the distance of @p meters with the current view transformation. */
105  Q_INVOKABLE double mapMetersToScreen(double meters) const;
106  /** Returns how many meters are represented by @p pixels with the current view transformation. */
107  Q_INVOKABLE double mapScreenToMeters(int pixels) const;
108 
109  void panScreenSpace(QPoint offset);
110  /** Increase zoom level by one/scale up by 2x around the screen position @p center. */
111  Q_INVOKABLE void zoomIn(QPointF screenCenter);
112  /** Decrease zoom level by one/scale down by 2x around the screen position @p center. */
113  Q_INVOKABLE void zoomOut(QPointF screenCenter);
114 
115  /** Position of the viewport in pan coordinates. */
116  double panX() const;
117  double panY() const;
118  /** Size of the pan-able area in screen coordinates. */
119  double panWidth() const;
120  double panHeight() const;
121 
122  /** Move the viewport to the pan coordinates @p x and @p y. */
123  Q_INVOKABLE void panTopLeft(double x, double y);
124 
125  /** Device tranformation for manual high DPI scaling. */
126  QTransform deviceTransform() const;
127  void setDeviceTransform(const QTransform &t);
128 
129  /** Center the view on the given geo-coordinate. */
130  Q_INVOKABLE void centerOnGeoCoordinate(QPointF geoCoord);
131 
132  /** Time range that is displayed.
133  * This matters for example when opening hours are considered for styling.
134  */
135  QDateTime beginTime() const;
136  void setBeginTime(const QDateTime &beginTime);
137  QDateTime endTime() const;
138  void setEndTime(const QDateTime &endTime);
139 
140 Q_SIGNALS:
141  void transformationChanged();
142  void floorLevelChanged();
143  void timeChanged();
144 
145 private:
146  /** Ensure we stay within the bounding box with the viewport, call after viewport modification. */
147  void constrainViewToScene();
148 
149  QRectF m_bbox;
150  QRectF m_viewport;
151  QSize m_screenSize;
152  QTransform m_deviceTransform = {};
153  int m_level = 0;
154 
155  QDateTime m_beginTime;
156  QDateTime m_endTime;
157 };
158 
159 }
160 
161 #endif // KOSMINDOORMAP_VIEW_H
OSM-based multi-floor indoor maps for buildings.
View transformations and transformation manipulation.
Definition: view.h:39
Coordinate, stored as 1e7 * degree to avoid floating point precision issues, and offset to unsigned v...
Definition: datatypes.h:37
Bounding box, ie.
Definition: datatypes.h:95
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:03:46 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.