import json import math import re def calculate_distance(point1: dict, point2: dict) -> float: """ Calculate the distance in meters between two geographic points with altitude. :param point1: A dictionary with 'latitude', 'longitude', and optional 'altitude'. :param point2: A dictionary with 'latitude', 'longitude', and optional 'altitude'. :return: Distance in meters as a float. """ try: # Extract latitude, longitude, and altitude lat1, lon1, alt1 = ( point1["latitude"], point1["longitude"], point1.get("altitude", 0), ) lat2, lon2, alt2 = ( point2["latitude"], point2["longitude"], point2.get("altitude", 0), ) except KeyError: return "Points were not properly set" # Convert latitude and longitude from degrees to radians lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2]) # Radius of the Earth in meters R = 6369500 # Compute deltas delta_lat = lat2 - lat1 delta_lon = lon2 - lon1 # Haversine formula for horizontal distance a = ( math.sin(delta_lat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(delta_lon / 2) ** 2 ) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) horizontal_distance = R * c # Altitude difference delta_alt = alt2 - alt1 # Total 3D distance distance = math.sqrt(horizontal_distance**2 + delta_alt**2) return distance # Split string by commas, if there are commas def comma_split(string: str): if "," in string: return string.split(",") else: return string # Extract stats from strings def extract_numbers(string): pattern = r"-?\d+\.\d+|-?\d+" numbers = re.findall(pattern, string) numbers = [float(num) if "." in num else int(num) for num in numbers] return numbers # Parse the latitude or longitude from the NMEA format def parse_lat_lon(value: str, direction: str) -> float: """ Parses latitude or longitude from NMEA format. Args: value (str): The raw NMEA latitude or longitude value. direction (str): Direction indicator ('N', 'S', 'E', 'W'). Returns: float: The parsed latitude or longitude as a decimal degree. """ if not value or not direction: return None degrees = int(value[:2]) minutes = float(value[2:]) decimal = degrees + minutes / 60 if direction in ["S", "W"]: decimal = -decimal return decimal # Convert RSSI to DBM def rssi_to_dbm(rssi): if rssi == 99: return "Unknown" else: # Convert RSSI to dBm return -113 + 2 * rssi # Save data to JSON file def save_data_to_json(data, filename): try: # Load existing data try: with open(filename, "r") as file: existing_data = json.load(file) except FileNotFoundError: # If file doesn't exist, start with an empty list existing_data = [] # Append new data existing_data.append(data) # Save updated data back to the file with open(filename, "w") as file: json.dump(existing_data, file, indent=4) except Exception as e: print(f"Error saving data to JSON: {e}")