QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
MapProvider.cpp
Go to the documentation of this file.
1#include "MapProvider.h"
3
4#include "QGCTileSet.h"
5
6#include <QtCore/QLocale>
7#include <QtCore/QUrl>
8#include <QtLocation/private/qgeomaptype_p.h>
9
10QGC_LOGGING_CATEGORY(MapProviderLog, "QtLocationPlugin.MapProvider")
11
12// MapProvider::MapStyle mirrors QGeoMapType::MapStyle to keep the public
13// header free of <QtLocation/private/qgeomaptype_p.h>. Catch drift at compile
14// time so the two enums never disagree.
15static_assert(static_cast<int>(MapProvider::NoMap) == static_cast<int>(QGeoMapType::NoMap));
16static_assert(static_cast<int>(MapProvider::StreetMap) == static_cast<int>(QGeoMapType::StreetMap));
17static_assert(static_cast<int>(MapProvider::SatelliteMapDay) == static_cast<int>(QGeoMapType::SatelliteMapDay));
18static_assert(static_cast<int>(MapProvider::SatelliteMapNight)== static_cast<int>(QGeoMapType::SatelliteMapNight));
19static_assert(static_cast<int>(MapProvider::TerrainMap) == static_cast<int>(QGeoMapType::TerrainMap));
20static_assert(static_cast<int>(MapProvider::HybridMap) == static_cast<int>(QGeoMapType::HybridMap));
21static_assert(static_cast<int>(MapProvider::TransitMap) == static_cast<int>(QGeoMapType::TransitMap));
22static_assert(static_cast<int>(MapProvider::GrayStreetMap) == static_cast<int>(QGeoMapType::GrayStreetMap));
23static_assert(static_cast<int>(MapProvider::PedestrianMap) == static_cast<int>(QGeoMapType::PedestrianMap));
24static_assert(static_cast<int>(MapProvider::CarNavigationMap) == static_cast<int>(QGeoMapType::CarNavigationMap));
25static_assert(static_cast<int>(MapProvider::CycleMap) == static_cast<int>(QGeoMapType::CycleMap));
26static_assert(static_cast<int>(MapProvider::CustomMap) == static_cast<int>(QGeoMapType::CustomMap));
27
28// QtLocation expects MapIds to start at 1 and be sequential.
29int MapProvider::_mapIdIndex = 1;
30
32 const QString &mapName,
33 const QString &referrer,
34 const QString &imageFormat,
35 quint32 averageSize,
36 MapStyle mapStyle)
37 : _mapName(mapName)
38 , _referrer(referrer)
39 , _imageFormat(imageFormat)
40 , _averageSize(averageSize)
41 , _mapStyle(mapStyle)
42 , _language(!QLocale::system().uiLanguages().isEmpty() ? QLocale::system().uiLanguages().constFirst() : "en")
43 , _mapId(_mapIdIndex++)
44{
45 // qCDebug(MapProviderLog) << Q_FUNC_INFO << this << _mapId;
46}
47
49{
50 // qCDebug(MapProviderLog) << Q_FUNC_INFO << this << _mapId;
51}
52
53QUrl MapProvider::getTileURL(int x, int y, int zoom) const
54{
55 return QUrl(_getURL(x, y, zoom));
56}
57
58QString MapProvider::getImageFormat(QByteArrayView image) const
59{
60 if (image.size() < 3) {
61 return QString();
62 }
63
64 static constexpr QByteArrayView pngSignature("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A");
65 if (image.startsWith(pngSignature)) {
66 return QStringLiteral("png");
67 }
68
69 static constexpr QByteArrayView jpegSignature("\xFF\xD8\xFF");
70 if (image.startsWith(jpegSignature)) {
71 return QStringLiteral("jpg");
72 }
73
74 static constexpr QByteArrayView gifSignature("\x47\x49\x46\x38");
75 if (image.startsWith(gifSignature)) {
76 return QStringLiteral("gif");
77 }
78
79 return _imageFormat;
80}
81
82QString MapProvider::_tileXYToQuadKey(int tileX, int tileY, int levelOfDetail) const
83{
84 QString quadKey;
85 for (int i = levelOfDetail; i > 0; i--) {
86 char digit = '0';
87 const int mask = 1 << (i - 1);
88
89 if ((tileX & mask) != 0) {
90 digit++;
91 }
92 if ((tileY & mask) != 0) {
93 digit += 2;
94 }
95
96 (void) quadKey.append(digit);
97 }
98
99 return quadKey;
100}
101
102int MapProvider::_getServerNum(int x, int y, int max) const
103{
104 return (x + 2 * y) % max;
105}
106
107int MapProvider::long2tileX(double lon, int z) const
108{
109 return static_cast<int>(floor((lon + 180.0) / 360.0 * pow(2.0, z)));
110}
111
112int MapProvider::lat2tileY(double lat, int z) const
113{
114 return static_cast<int>(floor((1.0 - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0 * pow(2.0, z)));
115}
116
117double MapProvider::tileX2long(int x, int z) const
118{
119 return x / std::pow(2.0, z) * 360.0 - 180.0;
120}
121
122double MapProvider::tileY2lat(int y, int z) const
123{
124 const double n = M_PI - 2.0 * M_PI * y / std::pow(2.0, z);
125 return qRadiansToDegrees(std::atan(std::sinh(n)));
126}
127
128QGCTileSet MapProvider::getTileCount(int zoom, double topleftLon,
129 double topleftLat, double bottomRightLon,
130 double bottomRightLat) const
131{
132 QGCTileSet set;
133 set.tileX0 = long2tileX(topleftLon, zoom);
134 set.tileY0 = lat2tileY(topleftLat, zoom);
135 set.tileX1 = long2tileX(bottomRightLon, zoom);
136 set.tileY1 = lat2tileY(bottomRightLat, zoom);
137
138 set.tileCount = (static_cast<quint64>(set.tileX1) -
139 static_cast<quint64>(set.tileX0) + 1) *
140 (static_cast<quint64>(set.tileY1) -
141 static_cast<quint64>(set.tileY0) + 1);
142
143 set.tileSize = getAverageSize() * set.tileCount;
144 return set;
145}
146
147// Resolution math: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale
#define QGC_LOGGING_CATEGORY(name, categoryStr)
int _getServerNum(int x, int y, int max) const
QString _tileXYToQuadKey(int tileX, int tileY, int levelOfDetail) const
const QString _imageFormat
Definition MapProvider.h:71
virtual double tileY2lat(int y, int z) const
virtual ~MapProvider()
virtual QGCTileSet getTileCount(int zoom, double topleftLon, double topleftLat, double bottomRightLon, double bottomRightLat) const
quint32 getAverageSize() const
Definition MapProvider.h:43
virtual int long2tileX(double lon, int z) const
QString getImageFormat(QByteArrayView image) const
virtual double tileX2long(int x, int z) const
QUrl getTileURL(int x, int y, int zoom) const
virtual int lat2tileY(double lat, int z) const
virtual QString _getURL(int x, int y, int zoom) const =0
quint64 tileCount
Definition QGCTileSet.h:29
quint64 tileSize
Definition QGCTileSet.h:30