1 #pragma once
2 
3 #include <mbgl/map/mode.hpp>
4 #include <mbgl/util/geo.hpp>
5 #include <mbgl/util/geometry.hpp>
6 #include <mbgl/util/constants.hpp>
7 #include <mbgl/util/optional.hpp>
8 #include <mbgl/util/projection.hpp>
9 #include <mbgl/util/mat4.hpp>
10 #include <mbgl/util/size.hpp>
11 
12 #include <cstdint>
13 #include <array>
14 #include <limits>
15 
16 namespace mbgl {
17 
18 class UnwrappedTileID;
19 
20 class TransformState {
21     friend class Transform;
22 
23 public:
24     TransformState(ConstrainMode = ConstrainMode::HeightOnly, ViewportMode = ViewportMode::Default);
25 
26     // Matrix
27     void matrixFor(mat4&, const UnwrappedTileID&) const;
28     void getProjMatrix(mat4& matrix, uint16_t nearZ = 1, bool aligned = false) const;
29 
30     // Dimensions
31     Size getSize() const;
32 
33     // North Orientation
34     NorthOrientation getNorthOrientation() const;
35     double getNorthOrientationAngle() const;
36 
37     // Constrain mode
38     ConstrainMode getConstrainMode() const;
39 
40     // Viewport mode
41     ViewportMode getViewportMode() const;
42 
43     // Position
44     LatLng getLatLng(LatLng::WrapMode = LatLng::Unwrapped) const;
45     double pixel_x() const;
46     double pixel_y() const;
47 
48     // Zoom
49     double getZoom() const;
50     uint8_t getIntegerZoom() const;
51     double getZoomFraction() const;
52 
53     // Bounds
54     void setLatLngBounds(optional<LatLngBounds>);
55     optional<LatLngBounds> getLatLngBounds() const;
56     void setMinZoom(double);
57     double getMinZoom() const;
58     void setMaxZoom(double);
59     double getMaxZoom() const;
60     void setMinPitch(double);
61     double getMinPitch() const;
62     void setMaxPitch(double);
63     double getMaxPitch() const;
64 
65     // Rotation
66     float getAngle() const;
67     float getFieldOfView() const;
68     float getCameraToCenterDistance() const;
69     float getPitch() const;
70 
71     // State
72     bool isChanging() const;
73     bool isRotating() const;
74     bool isScaling() const;
75     bool isPanning() const;
76     bool isGestureInProgress() const;
77 
78     // Conversion
79     ScreenCoordinate latLngToScreenCoordinate(const LatLng&) const;
80     LatLng screenCoordinateToLatLng(const ScreenCoordinate&, LatLng::WrapMode = LatLng::Unwrapped) const;
81 
82     double zoomScale(double zoom) const;
83     double scaleZoom(double scale) const;
84 
valid() const85     bool valid() const {
86         return !size.isEmpty() && (scale >= min_scale && scale <= max_scale);
87     }
88 
89     float getCameraToTileDistance(const UnwrappedTileID&) const;
90     float maxPitchScaleFactor() const;
91 
92 private:
93     bool rotatedNorth() const;
94     void constrain(double& scale, double& x, double& y) const;
95 
96     optional<LatLngBounds> bounds;
97 
98     // Limit the amount of zooming possible on the map.
99     double min_scale = std::pow(2, 0);
100     double max_scale = std::pow(2, util::DEFAULT_MAX_ZOOM);
101     double min_pitch = 0.0;
102     double max_pitch = util::PITCH_MAX;
103 
104     NorthOrientation orientation = NorthOrientation::Upwards;
105 
106     // logical dimensions
107     Size size;
108 
109     mat4 coordinatePointMatrix(double z) const;
110     mat4 getPixelMatrix() const;
111 
112     /** Recenter the map so that the given coordinate is located at the given
113         point on screen. */
114     void moveLatLng(const LatLng&, const ScreenCoordinate&);
115     void setLatLngZoom(const LatLng &latLng, double zoom);
116     void setScalePoint(const double scale, const ScreenCoordinate& point);
117 
118 private:
119     ConstrainMode constrainMode;
120     ViewportMode viewportMode;
121 
122     // animation state
123     bool rotating = false;
124     bool scaling = false;
125     bool panning = false;
126     bool gestureInProgress = false;
127 
128     // map position
129     double x = 0, y = 0;
130     double angle = 0;
131     double scale = 1;
132     // This fov value is somewhat arbitrary. The altitude of the camera used
133     // to be defined as 1.5 screen heights above the ground, which was an
134     // arbitrary choice. This is the fov equivalent to that value calculated with:
135     // `fov = 2 * arctan((height / 2) / (height * 1.5))`
136     double fov = 0.6435011087932844;
137     double pitch = 0.0;
138     double xSkew = 0.0;
139     double ySkew = 1.0;
140     bool axonometric = false;
141 
142     // cache values for spherical mercator math
143     double Bc = Projection::worldSize(scale) / util::DEGREES_MAX;
144     double Cc = Projection::worldSize(scale) / util::M2PI;
145 };
146 
147 } // namespace mbgl
148