Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++ #ifndef QLOCATIONUTILS_P_H
++ #define QLOCATIONUTILS_P_H
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists purely as an
++ // implementation detail. This header file may change from version to
++ // version without notice, or even be removed.
++ //
++ // We mean it.
++ //
++
++ #include <QtCore/QtGlobal>
++ #include <math.h> // needed for non-std:: versions of functions
++ #include <qmath.h>
++ #include <QtPositioning/QGeoCoordinate>
++ #include <QtPositioning/QNmeaSatelliteInfoSource>
++ #include <QtPositioning/private/qpositioningglobal_p.h>
++
++ static const double offsetEpsilon = 1e-12; // = 0.000000000001
++ static const double leftOffset = -180.0 + offsetEpsilon;
++ static const double rightOffset = 180.0 - offsetEpsilon;
++
++ QT_BEGIN_NAMESPACE
++ class QTime;
++ class QByteArray;
++
++ class QGeoPositionInfo;
++ class QGeoSatelliteInfo;
++ class Q_POSITIONING_EXPORT QLocationUtils
++ {
++ public:
++ enum CardinalDirection {
++ CardinalN,
++ CardinalE,
++ CardinalS,
++ CardinalW,
++ CardinalNE,
++ CardinalSE,
++ CardinalSW,
++ CardinalNW,
++ CardinalNNE,
++ CardinalENE,
++ CardinalESE,
++ CardinalSSE,
++ CardinalSSW,
++ CardinalWSW,
++ CardinalWNW,
++ CardinalNNW
++ };
++
++ enum NmeaSentence {
++ NmeaSentenceInvalid,
++ NmeaSentenceGGA, // Fix information
++ NmeaSentenceGSA, // Overall Satellite data, such as HDOP and VDOP
++ NmeaSentenceGLL, // Lat/Lon data
++ NmeaSentenceRMC, // Recommended minimum data for gps
++ NmeaSentenceVTG, // Vector track an Speed over the Ground
++ NmeaSentenceZDA, // Date and Time
++ NmeaSentenceGSV // Per-Satellite Info
++ };
++
++ inline static bool isValidLat(double lat) {
++ return lat >= -90.0 && lat <= 90.0;
++ }
++ inline static bool isValidLong(double lng) {
++ return lng >= -180.0 && lng <= 180.0;
++ }
++
++ inline static double clipLat(double lat, double clipValue = 90.0) {
++ if (lat > clipValue)
++ lat = clipValue;
++ else if (lat < -clipValue)
++ lat = -clipValue;
++ return lat;
++ }
++
++ inline static double wrapLong(double lng) {
++ if (lng > 180.0)
++ lng -= 360.0;
++ else if (lng < -180.0)
++ lng += 360.0;
++ return lng;
++ }
++
++ inline static CardinalDirection azimuthToCardinalDirection4(double azimuth)
++ {
++ azimuth = fmod(azimuth, 360.0);
++ if (azimuth < 45.0 || azimuth > 315.0 )
++ return CardinalN;
++ else if (azimuth < 135.0)
++ return CardinalE;
++ else if (azimuth < 225.0)
++ return CardinalS;
++ else
++ return CardinalW;
++ }
++
++ inline static CardinalDirection azimuthToCardinalDirection8(double azimuth)
++ {
++ azimuth = fmod(azimuth, 360.0);
++ if (azimuth < 22.5 || azimuth > 337.5 )
++ return CardinalN;
++ else if (azimuth < 67.5)
++ return CardinalNE;
++ else if (azimuth < 112.5)
++ return CardinalE;
++ else if (azimuth < 157.5)
++ return CardinalSE;
++ else if (azimuth < 202.5)
++ return CardinalS;
++
++ else if (azimuth < 247.5)
++ return CardinalSW;
++ else if (azimuth < 292.5)
++ return CardinalW;
++ else
++ return CardinalNW;
++ }
++
++ inline static CardinalDirection azimuthToCardinalDirection16(double azimuth)
++ {
++ azimuth = fmod(azimuth, 360.0);
++ if (azimuth < 11.5 || azimuth > 348.75 )
++ return CardinalN;
++ else if (azimuth < 33.75)
++ return CardinalNNE;
++ else if (azimuth < 56.25)
++ return CardinalNE;
++ else if (azimuth < 78.75)
++ return CardinalENE;
++ else if (azimuth < 101.25)
++ return CardinalE;
++ else if (azimuth < 123.75)
++ return CardinalESE;
++ else if (azimuth < 146.25)
++ return CardinalSE;
++ else if (azimuth < 168.75)
++ return CardinalSSE;
++ else if (azimuth < 191.25)
++ return CardinalS;
++
++ else if (azimuth < 213.75)
++ return CardinalSSW;
++ else if (azimuth < 236.25)
++ return CardinalSW;
++ else if (azimuth < 258.75)
++ return CardinalWSW;
++ else if (azimuth < 281.25)
++ return CardinalW;
++ else if (azimuth < 303.75)
++ return CardinalWNW;
++ else if (azimuth < 326.25)
++ return CardinalNW;
++ else
++ return CardinalNNW;
++ }
++
++ // For values exceeding +- 720.0
++ inline static double wrapLongExt(double lng) {
++ double remainder = fmod(lng + 180.0, 360.0);
++ return fmod(remainder + 360.0, 360.0) - 180.0;
++ }
++
++ // Mirrors the azimuth against the X axis. Azimuth assumed to be in [0,360[
++ inline static double mirrorAzimuthX(double azimuth) {
++ if (azimuth <= 90.0)
++ return 180.0 - azimuth;
++ else
++ return 180.0 + (360.0 - azimuth);
++ }
++
++ // Mirrors the azimuth against the Y axis. Azimuth assumed to be in [0,360[
++ inline static double mirrorAzimuthY(double azimuth) {
++ if (azimuth == 0.0)
++ return 0.0;
++ return 360.0 - azimuth;
++ }
++
++ inline static double radians(double degrees)
++ {
++ return qDegreesToRadians(degrees);
++ }
++
++ inline static double degrees(double radians)
++ {
++ return qRadiansToDegrees(radians);
++ }
++
++ inline static double earthMeanRadius()
++ {
++ return 6371007.2;
++ }
++
++ inline static double earthMeanCircumference()
++ {
++ return earthMeanRadius() * 2.0 * M_PI;
++ }
++
++ inline static double mercatorMaxLatitude()
++ {
++ return 85.05113;
++ }
++
++ inline static QGeoCoordinate antipodalPoint(const QGeoCoordinate &p)
++ {
++ return QGeoCoordinate(-p.latitude(), wrapLong(p.longitude() + 180.0));
++ }
++
++ // Leftmost longitude before wrapping kicks in
++ inline static double mapLeftLongitude(double centerLongitude)
++ {
++ return wrapLong(centerLongitude + leftOffset);
++ }
++
++ // Rightmost longitude before wrapping kicks in
++ inline static double mapRightLongitude(double centerLongitude)
++ {
++ return wrapLong(centerLongitude - leftOffset);
++ }
++
++ inline static void split_double(double input, float *hipart, float *lopart)
++ {
++ *hipart = (float) input;
++ double delta = input - ((double) *hipart);
++ *lopart = (float) delta;
++ }
++
++ static qreal metersPerPixel(qreal zoomLevel, const QGeoCoordinate &coordinate)
++ {
++ const qreal metersPerTile = earthMeanCircumference() * std::cos(radians(coordinate.latitude())) / std::pow(2, zoomLevel);
++ return metersPerTile / 256.0;
++ }
++
++ /*
++ returns the NMEA sentence type.
++ */
++ static NmeaSentence getNmeaSentenceType(QByteArrayView bv);
++
++ /*
++ Returns the satellite system type based on the message type.
++ */
++ static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystem(QByteArrayView bv);
++
++ /*
++ Returns the satellite system type based on the satellite id.
++ */
++ static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystemBySatelliteId(int satId);
++
++ /*
++ Creates a QGeoPositionInfo from a GGA, GLL, RMC, VTG or ZDA sentence.
++
++ Note:
++ - GGA and GLL sentences have time but not date so the update's
++ QDateTime object will have an invalid date.
++ - RMC reports date with a two-digit year so in this case the year
++ is assumed to be after the year 2000.
++ */
++ static bool getPosInfoFromNmea(QByteArrayView bv,
++ QGeoPositionInfo *info, double uere,
++ bool *hasFix = nullptr);
++
++ /*
++ Retruns a list of QGeoSatelliteInfo in the view.
++
++ Note: this function has to be called repeatedly until it returns
++ QNmeaSatelliteInfoSource::FullyParsed.
++ Reason being that GSV sentences can be split into multiple samples, so
++ getting the full data requires parsing multiple sentences.
++ */
++ static QNmeaSatelliteInfoSource::SatelliteInfoParseStatus
++ getSatInfoFromNmea(QByteArrayView bv, QList<QGeoSatelliteInfo> &infos, QGeoSatelliteInfo::SatelliteSystem &system);
++
++ /*
++ Parses GSA for satellites in use.
++
++ Returns satellite system type or QGeoSatelliteInfo::Undefined if parsing
++ failed
++ */
++ static QGeoSatelliteInfo::SatelliteSystem getSatInUseFromNmea(QByteArrayView bv,
++ QList<int> &pnrsInUse);
++
++ /*
++ Returns true if the given NMEA sentence has a valid checksum.
++ */
++ static bool hasValidNmeaChecksum(QByteArrayView bv);
++
++ /*
++ Returns time from a string in hhmmss or hhmmss.z+ format.
++ */
++ static bool getNmeaTime(const QByteArray &bytes, QTime *time);
++
++ /*
++ Accepts for example ("2734.7964", 'S', "15306.0124", 'E') and returns the
++ lat-long values. Fails if lat or long fail isValidLat() or isValidLong().
++ */
++ static bool getNmeaLatLong(const QByteArray &latString,
++ char latDirection,
++ const QByteArray &lngString,
++ char lngDirection,
++ double *lat,
++ double *lon);
++ };
++
++ QT_END_NAMESPACE
++
++ #endif