diff --git a/plugins/channelrx/demodvor/vordemodgui.cpp b/plugins/channelrx/demodvor/vordemodgui.cpp index 0bd14eff3..c512b82d3 100644 --- a/plugins/channelrx/demodvor/vordemodgui.cpp +++ b/plugins/channelrx/demodvor/vordemodgui.cpp @@ -384,8 +384,8 @@ static bool calcIntersectionPoint(float lat1, float lon1, float bearing1, float double lat3Rad = asin(sinLat1*cos(delta13)+cosLat1*sin(delta13)*cos(theta13)); double lon3Rad = lon1Rad + atan2(sin(theta13)*sin(delta13)*cosLat1, cos(delta13)-sinLat1*sin(lat3Rad)); - intersectLat = Units::radiansToDegress(lat3Rad); - intersectLon = Units::radiansToDegress(lon3Rad); + intersectLat = Units::radiansToDegrees(lat3Rad); + intersectLon = Units::radiansToDegrees(lon3Rad); return true; } diff --git a/plugins/channelrx/demodvor/vordemodsink.cpp b/plugins/channelrx/demodvor/vordemodsink.cpp index 272836971..0a2db5385 100644 --- a/plugins/channelrx/demodvor/vordemodsink.cpp +++ b/plugins/channelrx/demodvor/vordemodsink.cpp @@ -222,7 +222,7 @@ void VORDemodSink::processOneSample(Complex &ci) if (m_varGoertzel.size() == VORDEMOD_CHANNEL_SAMPLE_RATE - 1) { m_varGoertzel.goertzel(mag); - varPhase = Units::radiansToDegress(m_varGoertzel.phase()); + varPhase = Units::radiansToDegrees(m_varGoertzel.phase()); varMag = m_varGoertzel.mag(); m_varGoertzel.reset(); } @@ -245,7 +245,7 @@ void VORDemodSink::processOneSample(Complex &ci) if (m_refGoertzel.size() == VORDEMOD_CHANNEL_SAMPLE_RATE - 1) { m_refGoertzel.goertzel(phi); - float phaseDeg = Units::radiansToDegress(m_refGoertzel.phase()); + float phaseDeg = Units::radiansToDegrees(m_refGoertzel.phase()); double refMag = m_refGoertzel.mag(); int groupDelay = (301-1)/2; float filterPhaseShift = 360.0*30.0*groupDelay/VORDEMOD_CHANNEL_SAMPLE_RATE; diff --git a/plugins/channelrx/demodvorsc/vordemodscsink.cpp b/plugins/channelrx/demodvorsc/vordemodscsink.cpp index 5c31f63a2..46caad290 100644 --- a/plugins/channelrx/demodvorsc/vordemodscsink.cpp +++ b/plugins/channelrx/demodvorsc/vordemodscsink.cpp @@ -211,7 +211,7 @@ void VORDemodSCSink::processOneSample(Complex &ci) if (m_varGoertzel.size() == VORDemodSCSettings::VORDEMOD_CHANNEL_SAMPLE_RATE - 1) { m_varGoertzel.goertzel(mag); - varPhase = Units::radiansToDegress(m_varGoertzel.phase()); + varPhase = Units::radiansToDegrees(m_varGoertzel.phase()); varMag = m_varGoertzel.mag(); m_varGoertzel.reset(); } @@ -234,7 +234,7 @@ void VORDemodSCSink::processOneSample(Complex &ci) if (m_refGoertzel.size() == VORDemodSCSettings::VORDEMOD_CHANNEL_SAMPLE_RATE - 1) { m_refGoertzel.goertzel(phi); - float phaseDeg = Units::radiansToDegress(m_refGoertzel.phase()); + float phaseDeg = Units::radiansToDegrees(m_refGoertzel.phase()); double refMag = m_refGoertzel.mag(); int groupDelay = (301-1)/2; float filterPhaseShift = 360.0*30.0*groupDelay/VORDemodSCSettings::VORDEMOD_CHANNEL_SAMPLE_RATE; diff --git a/plugins/feature/vorlocalizer/vorlocalizergui.cpp b/plugins/feature/vorlocalizer/vorlocalizergui.cpp index c25048bbc..afe9792b4 100644 --- a/plugins/feature/vorlocalizer/vorlocalizergui.cpp +++ b/plugins/feature/vorlocalizer/vorlocalizergui.cpp @@ -376,8 +376,8 @@ static bool calcIntersectionPoint(float lat1, float lon1, float bearing1, float double lat3Rad = asin(sinLat1*cos(delta13)+cosLat1*sin(delta13)*cos(theta13)); double lon3Rad = lon1Rad + atan2(sin(theta13)*sin(delta13)*cosLat1, cos(delta13)-sinLat1*sin(lat3Rad)); - intersectLat = Units::radiansToDegress(lat3Rad); - intersectLon = Units::radiansToDegress(lon3Rad); + intersectLat = Units::radiansToDegrees(lat3Rad); + intersectLon = Units::radiansToDegrees(lon3Rad); return true; } diff --git a/sdrbase/util/units.h b/sdrbase/util/units.h index 4285f26e0..8faecc1fa 100644 --- a/sdrbase/util/units.h +++ b/sdrbase/util/units.h @@ -19,6 +19,10 @@ #define INCLUDE_UNITS_H #include +#include +#include +#include +#include #include "export.h" @@ -72,11 +76,143 @@ public: return degrees * ((float)M_PI) / 180.0f; } - static float radiansToDegress(float radians) + static float radiansToDegrees(float radians) { return radians * 180.0f / ((float)M_PI); } + static float fahrenheitToCelsius(float fahrenheit) + { + return (fahrenheit - 32.0f) * (5.0f/9.0f); + } + + static float celsiusToKelvin(float celsius) + { + return celsius + 273.15f; + } + + static float inchesToMilimetres(float inches) + { + return inches * 25.4f; + } + + static float milesToKilometres(float miles) + { + return miles * 1.60934f; + } + + static float degreesMinutesSecondsToDecimal(int degrees, int minutes, float seconds) + { + float dec = std::abs(degrees) + minutes * 1.0f/60.0f + seconds * 1.0f/(60.0f*60.0f); + if (degrees < 0) + return -dec; + else + return dec; + } + + static float hoursMinutesSecondsToDecimal(int hours, int minutes, float seconds) + { + return hours + minutes * 1.0f/60.0f + seconds * 1.0f/(60.0f*60.0f); + } + + static QString decimalDegreesToDegreeMinutesAndSeconds(float decimal, int secondsFieldWidth=5) + { + float v, d, m, s; + int neg; + + v = decimal; + neg = v < 0.0f; + v = fabs(v); + d = floor(v); + v -= d; + v *= 60.0; + m = floor(v); + v -= m; + v *= 60.0; + s = v; + return QString("%1%2%3%4'%5\"").arg(neg ? "-" : "").arg((int)d).arg(QChar(0xb0)).arg((int)m, 2, 10, QChar('0')).arg(s, secondsFieldWidth, 'f', 2, QChar('0')); + } + + static QString decimalDegreesToDegreesAndMinutes(float decimal) + { + float v, d, m; + int neg; + + v = decimal; + neg = v < 0.0f; + v = fabs(v); + d = floor(v); + v -= d; + v *= 60.0; + m = round(v); + return QString("%1%2%3%4'").arg(neg ? "-" : "").arg((int)d).arg(QChar(0xb0)).arg((int)m, 2, 10, QChar('0')); + } + + static QString decimalDegreesToDegrees(float decimal) + { + float v, d; + int neg; + + v = decimal; + neg = v < 0.0f; + v = fabs(v); + d = round(v); + return QString("%1%2%3").arg(neg ? "-" : "").arg((int)d).arg(QChar(0xb0)); + } + + static QString decimalHoursToHoursMinutesAndSeconds(float decimal, int precision=2) + { + float v, h, m, s; + + v = decimal; + v = fabs(v); + h = floor(v); + v -= h; + v *= 60.0; + m = floor(v); + v -= m; + v *= 60.0; + s = v; + return QString("%1h%2m%3s").arg((int)h).arg((int)m, 2, 10, QChar('0')).arg(s, 2, 'f', precision, QChar('0')); + } + + // Try to convert a string to latitude and longitude. Returns false if not recognised format. + // https://en.wikipedia.org/wiki/ISO_6709 specifies a standard syntax + // We support both decimal and DMS formats + static bool stringToLatitudeAndLongitude(const QString& string, float& latitude, float& longitude) + { + QRegExp decimal("(-?[0-9]+\\.[0-9]+) *,? *(-?[0-9]+\\.[0-9]+)"); + if (decimal.exactMatch(string)) + { + latitude = decimal.capturedTexts()[1].toFloat(); + longitude = decimal.capturedTexts()[2].toFloat(); + return true; + } + QRegExp dms(QString("([0-9]+)[%1d]([0-9]+)['m]([0-9]+(\\.[0-9]+)?)[\"s]([NS]) *,? *([0-9]+)[%1d]([0-9]+)['m]([0-9]+(\\.[0-9]+)?)[\"s]([EW])").arg(QChar(0xb0))); + if (dms.exactMatch(string)) + { + qDebug() << "Captured: " << dms.capturedTexts(); + float latD = dms.capturedTexts()[1].toFloat(); + float latM = dms.capturedTexts()[2].toFloat(); + float latS = dms.capturedTexts()[3].toFloat(); + bool north = dms.capturedTexts()[5] == "N"; + float lonD = dms.capturedTexts()[6].toFloat(); + float lonM = dms.capturedTexts()[7].toFloat(); + float lonS = dms.capturedTexts()[8].toFloat(); + bool east = dms.capturedTexts()[10] == "E"; + latitude = latD + latM/60.0 + latS/(60.0*60.0); + if (!north) + latitude = -latitude; + longitude = lonD + lonM/60.0 + lonS/(60.0*60.0); + if (!east) + longitude = -longitude; + qDebug() << "Lat " << latitude; + qDebug() << "Long " << longitude; + return true; + } + return false; + } + }; #endif // INCLUDE_UNITS_H