KOSMIndoorMap

view.h
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
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
20namespace 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 */
39class 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(QRectF viewport READ viewport NOTIFY transformationChanged)
48 Q_PROPERTY(double zoomLevel READ zoomLevel NOTIFY transformationChanged)
49 Q_PROPERTY(QDateTime beginTime READ beginTime WRITE setBeginTime NOTIFY timeChanged)
50 Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY timeChanged)
51public:
52 explicit View(QObject *parent = nullptr);
53 ~View();
54
55 /** Map a geographic coordinate to a scene coordinate, ie. apply the mercator projection. */
56 [[nodiscard]] static QPointF mapGeoToScene(OSM::Coordinate coord);
57 [[nodiscard]] static QRectF mapGeoToScene(OSM::BoundingBox box);
58 /** Map a scene coordinate to a geographic one, ie. apply the inverse mercator projection. */
59 [[nodiscard]] static OSM::Coordinate mapSceneToGeo(QPointF p);
60 Q_INVOKABLE [[nodiscard]] static OSM::BoundingBox mapSceneToGeo(const QRectF &box);
61
62 /** Screen-space sizes, ie the size of the on-screen area used for displaying. */
63 int screenWidth() const;
64 int screenHeight() const;
65 void setScreenSize(QSize size);
66
67 /** The transformation to apply to scene coordinate to get to the view on screen. */
68 QTransform sceneToScreenTransform() const;
69
70 /** The (floor) level to display.
71 * @see MapLevel.
72 */
73 int level() const;
74 void setLevel(int level);
75
76 /** OSM-compatible zoom level, ie. the 2^level-th subdivision of the scene space. */
77 double zoomLevel() const;
78 /** Set the zoom level to @p zoom, and adjusting it around center position @p center. */
79 Q_INVOKABLE void setZoomLevel(double zoom, QPointF screenCenter);
80
81 /** The sub-rect of the scene bounding box currently displayed.
82 * Specified in scene coordinates.
83 */
84 [[nodiscard]] QRectF viewport() const;
85 void setViewport(const QRectF &viewport);
86
87 /** Computes the viewport for the given @p zoom level and @p screenCenter.
88 * This does not apply the zoom change to the view itself though.
89 */
90 [[nodiscard]] QRectF viewportForZoom(double zoom, QPointF screenCenter) const;
91
92 /** The bounding box of the scene.
93 * The viewport cannot exceed this area.
94 */
95 QRectF sceneBoundingBox() const;
96 void setSceneBoundingBox(OSM::BoundingBox bbox);
97 void setSceneBoundingBox(const QRectF &bbox);
98
99 /** Converts a point in scene coordinates to screen coordinates. */
100 QPointF mapSceneToScreen(QPointF scenePos) const;
101 /** Converts a rectangle in scene coordinates to screen coordinates. */
102 QRectF mapSceneToScreen(const QRectF &sceneRect) const;
103 /** Converts a point in screen coordinates to scene coordinates. */
104 Q_INVOKABLE [[nodiscard]] QPointF mapScreenToScene(QPointF screenPos) const;
105 /** Converts a distance in screen coordinates to a distance in scene coordinates. */
106 double mapScreenDistanceToSceneDistance(double distance) const;
107
108 /** Returns how many units in scene coordinate represent the distance of @p meters in the current view transformation. */
109 double mapMetersToScene(double meters) const;
110 /** Returns how many pixels on screen represent the distance of @p meters with the current view transformation. */
111 Q_INVOKABLE double mapMetersToScreen(double meters) const;
112 /** Returns how many meters are represented by @p pixels with the current view transformation. */
113 Q_INVOKABLE double mapScreenToMeters(int pixels) const;
114
115 void panScreenSpace(QPoint offset);
116 /** Increase zoom level by one/scale up by 2x around the screen position @p center. */
117 Q_INVOKABLE void zoomIn(QPointF screenCenter);
118 /** Decrease zoom level by one/scale down by 2x around the screen position @p center. */
119 Q_INVOKABLE void zoomOut(QPointF screenCenter);
120
121 /** Position of the viewport in pan coordinates. */
122 double panX() const;
123 double panY() const;
124 /** Size of the pan-able area in screen coordinates. */
125 double panWidth() const;
126 double panHeight() const;
127
128 /** Move the viewport to the pan coordinates @p x and @p y. */
129 Q_INVOKABLE void panTopLeft(double x, double y);
130
131 /** Device tranformation for manual high DPI scaling. */
132 QTransform deviceTransform() const;
133 void setDeviceTransform(const QTransform &t);
134
135 /** Center the view on the given geo-coordinate. */
136 Q_INVOKABLE void centerOnGeoCoordinate(QPointF geoCoord);
137
138 /** Time range that is displayed.
139 * This matters for example when opening hours are considered for styling.
140 */
141 QDateTime beginTime() const;
142 void setBeginTime(const QDateTime &beginTime);
143 QDateTime endTime() const;
144 void setEndTime(const QDateTime &endTime);
145
146Q_SIGNALS:
147 void transformationChanged();
148 void floorLevelChanged();
149 void timeChanged();
150
151protected:
152 /** QML only API due to lack of OSM::Coordinate support there. */
153 Q_INVOKABLE [[nodiscard]] static QPointF mapSceneToGeoPoint(QPointF p);
154
155private:
156 /** Ensure we stay within the bounding box with the viewport, call after viewport modification. */
157 void constrainViewToScene();
158 [[nodiscard]] QRectF constrainedViewport(QRectF viewport) const;
159
160 /** Needs to be called for any update to the viewport to updates internal caches
161 * and emits change signals.
162 */
163 void updateViewport();
164
165 QRectF m_bbox;
166 QRectF m_viewport;
167 QSize m_screenSize;
168 QTransform m_deviceTransform = {};
169 int m_level = 0;
170
171 // cached values
172 double m_screenWidthInMeters = 1.0;
173 QTransform m_sceneToScreenTransform;
174 QTransform m_screenToSceneTransform;
175
176 QDateTime m_beginTime;
177 QDateTime m_endTime;
178};
179
180}
181
182#endif // KOSMINDOORMAP_VIEW_H
View transformations and transformation manipulation.
Definition view.h:40
Bounding box, ie.
Definition datatypes.h:95
Coordinate, stored as 1e7 * degree to avoid floating point precision issues, and offset to unsigned v...
Definition datatypes.h:37
OSM-based multi-floor indoor maps for buildings.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:17:55 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.