#include #include #include VANETZA_ASN1_SECURITY_HEADER(Latitude.h) #include VANETZA_ASN1_SECURITY_HEADER(Longitude.h) #include VANETZA_ASN1_SECURITY_HEADER(TwoDLocation.h) #include #include namespace vanetza { namespace security { namespace v3 { units::Length distance(const PositionFix& one, const asn1::TwoDLocation& other) { static const auto earth_radius = 6371000.0 * units::si::meter; const auto other_lat = convert_latitude(other.latitude); const auto other_lon = convert_longitude(other.longitude); const units::Angle delta_phi { one.latitude - other_lat }; const units::Angle delta_lambda { one.longitude - other_lon }; const auto sin_delta_phi = sin(delta_phi / 2.0); const auto sin_delta_lambda = sin(delta_lambda / 2.0); const auto a = sin_delta_phi * sin_delta_phi + cos(one.latitude) * cos(other_lat) * sin_delta_lambda * sin_delta_lambda; const auto c = 2.0 * atan2(sqrt(a), sqrt(1 - a)); return earth_radius * c; } units::GeoAngle convert_latitude(const asn1::Latitude& in) { static constexpr long latitude_scale = Vanetza_Security_NinetyDegreeInt_max; if (in >= Vanetza_Security_NinetyDegreeInt_min && in <= Vanetza_Security_NinetyDegreeInt_max) { return in * 90.0 / latitude_scale * units::degree; } else { return units::GeoAngle::from_value(std::numeric_limits::quiet_NaN()); } } units::GeoAngle convert_longitude(const asn1::Longitude& in) { static constexpr long longitude_scale = Vanetza_Security_OneEightyDegreeInt_max; if (in >= Vanetza_Security_OneEightyDegreeInt_min && in <= Vanetza_Security_OneEightyDegreeInt_max) { return in * 180.0 / longitude_scale * units::degree; } else { return units::GeoAngle::from_value(std::numeric_limits::quiet_NaN()); } } } // namespace v3 } // namespace security } // namespace vanetza