From f491345ea0ff2938dea1e3a9af2ea9f1845e2144 Mon Sep 17 00:00:00 2001 From: eneller Date: Tue, 20 Jan 2026 15:46:26 +0100 Subject: [PATCH] refactor: consolidate main.Rmd statistics --- src/main.Rmd | 225 +++++++++++++++++++++------------------------------ 1 file changed, 93 insertions(+), 132 deletions(-) diff --git a/src/main.Rmd b/src/main.Rmd index b35c46d..8b6c86d 100644 --- a/src/main.Rmd +++ b/src/main.Rmd @@ -43,14 +43,22 @@ flights <- getFlights(icao,Sys.time(), creds) # TODO map from all available flights to tracks query <- list(icao24= icao, time=as.numeric(flights[[1]][["departure_time"]])) -response <-makeAuthenticatedRequest('tracks/all',query, creds) -track_data <- fromJSON(content(response, as = "text", encoding = "UTF-8")) -if (!is.null(track_data$path) && length(track_data$path) > 0) { - - route_df <- as.data.frame(track_data$path) - colnames(route_df) <- c("time", "lat", "lon", "alt", "heading", "on_ground") - - message("Loading of route successfull! Points: ", nrow(route_df)) +# make a manual request because this API endpoint is considered experimental +getAircraftTrack <- function(icao, time, creds){ + query <- list(icao24= icao, time=as.numeric(time)) + response <-makeAuthenticatedRequest('tracks/all',query, creds) + track_data <- fromJSON(content(response, as = "text", encoding = "UTF-8")) + if (!is.null(track_data$path) && length(track_data$path) > 0) { + route_df <- as.data.frame(track_data$path) + colnames(route_df) <- c("time", "lat", "lon", "alt", "heading", "on_ground") + return(route_df) + } + return(NULL) +} + +route_df <- getAircraftTrack(icao, time=flights[[1]][["departure_time"]], creds = creds) +if(!is.null(route_df)){ + message("Loading of route successfull! Points: ", nrow(route_df)) plot(route_df$lon, route_df$lat, type="o", pch=20, col="blue", main=paste("Geographic route of", icao), @@ -59,16 +67,17 @@ if (!is.null(track_data$path) && length(track_data$path) > 0) { plot(route_df$time, route_df$alt, type="l", col="red", lwd=2, main=paste("Altitude profile of", icao), xlab="Time (Unix)", ylab="Height (Meter)") - - } else { +} else { print("No path points from api") - } +} ``` + # Trajectory Characteristics Analysis -```{r trajectory-analysis} -if (exists("route_df") && nrow(route_df) > 1) { - + +## Distance Approximation +```{r traj-dist} +getRouteDistance<- function(route_df){ # Convert lat/lon to approximate meters (using simple equirectangular projection) # Reference point: first coordinate lat_ref <- route_df$lat[1] @@ -80,128 +89,87 @@ if (exists("route_df") && nrow(route_df) > 1) { x_meters <- (route_df$lon - lon_ref) * meters_per_deg_lon y_meters <- (route_df$lat - lat_ref) * meters_per_deg_lat - time_seconds <- route_df$time - route_df$time[1] - - # Create trajr trajectory object + return(list('x' = x_meters, 'y' = y_meters)) +} + +getRouteTime <- function(route_df){ + return(route_df$time - route_df$time[1]) +} + +getTrajFromRoute <- function(route_df){ + meters <- getRouteDistance(route_df) + time <- getRouteTime(route_df) trj <- TrajFromCoords( - data.frame(x = x_meters, y = y_meters, time = time_seconds), + data.frame(x = meters$x, y = meters$y, time = time), xCol = "x", yCol = "y", timeCol = "time" ) - - # Calculate trajectory characteristics - - # 1. Duration of travel (seconds) - duration <- TrajDuration(trj) - - # 2. Total path length (meters) - path_length <- TrajLength(trj) - - # 3. Diffusion distance (net displacement - straight line from start to end) - diffusion_distance <- TrajDistance(trj) - - # 4. Straightness index (ratio of net displacement to path length, 0-1) - straightness <- TrajStraightness(trj) - - # 5. Mean travel velocity (meters/second) - mean_velocity <- path_length / duration - - # 6. Fractal dimension (using divider method) - # Note: requires sufficient points for accurate estimation - fractal_dim <- tryCatch({ - # Calculate appropriate step sizes based on trajectory length - min_step <- TrajLength(trj) / 100 - max_step <- TrajLength(trj) / 2 - step_sizes <- exp(seq(log(min_step), log(max_step), length.out = 10)) - - TrajFractalDimension(trj, stepSizes = step_sizes) - }, error = function(e) { - message("Could not calculate fractal dimension: ", e$message) - NA - }) - - # Create summary data frame - trajectory_characteristics <- data.frame( - Parameter = c( - "Duration of Travel (s)", - "Duration of Travel (min)", - "Path Length (m)", - "Path Length (km)", - "Diffusion Distance (m)", - "Diffusion Distance (km)", - "Straightness Index", - "Mean Travel Velocity (m/s)", - "Mean Travel Velocity (km/h)", - "Fractal Dimension" - ), - Value = c( - round(duration, 2), - round(duration / 60, 2), - round(path_length, 2), - round(path_length / 1000, 2), - round(diffusion_distance, 2), - round(diffusion_distance / 1000, 2), - round(straightness, 4), - round(mean_velocity, 2), - round(mean_velocity * 3.6, 2), - round(fractal_dim, 4) - ) - ) - - print(trajectory_characteristics) - - # Visualize the trajectory using trajr - plot(trj, main = paste("Trajectory of", icao)) - -} else { - message("No valid trajectory data available for analysis") } +getRouteSummary<-function(route_df){ + meters <- getRouteDistance(route_df) + x_meters <- meters$x + y_meters <- meters$y + time_seconds <- getRouteTime(route_df) + + # Create trajr trajectory object + trj <- getTrajFromRoute(route_df) + + # Calculate trajectory characteristics + + # 1. Duration of travel (seconds) + duration <- TrajDuration(trj) + + # 2. Total path length (meters) + path_length <- TrajLength(trj) + + # 3. Diffusion distance (net displacement - straight line from start to end) + diffusion_distance <- TrajDistance(trj) + + # 4. Straightness index (ratio of net displacement to path length, 0-1) + straightness <- TrajStraightness(trj) + + # 5. Mean travel velocity (meters/second) + + # 6. Fractal dimension (using divider method) + # Note: requires sufficient points for accurate estimation + fractal_dim <- tryCatch({ + # Calculate appropriate step sizes based on trajectory length + min_step <- TrajLength(trj) / 100 + max_step <- TrajLength(trj) / 2 + step_sizes <- exp(seq(log(min_step), log(max_step), length.out = 10)) + + TrajFractalDimension(trj, stepSizes = step_sizes) + }, error = function(e) { + message("Could not calculate fractal dimension: ", e$message) + NA + }) + + return(data.frame( + icao24 = icao24, + diffusion_distance_m = diffusion_distance, # meters + path_length_m = path_length, # meters + straightness = straightness, + duration_s = duration, # seconds + mean_velocity_kmh = mean_velocity * 3.6, + fractal_dimension = fractal_dim + )) +} + +print(getRouteSummary(route_df)) +trj <- getTrajFromRoute(route_df) +plot(trj, main = paste("Trajectory of", icao)) + ``` + + # Statistical Analysis of Multiple Trajectories ```{r multi-trajectory-analysis} # Function to calculate trajectory characteristics for a single flight calculate_trajectory_params <- function(icao24, departure_time, creds) { tryCatch({ - query <- list(icao24 = icao24, time = as.numeric(departure_time)) - response <- makeAuthenticatedRequest('tracks/all', query, creds) + route_df <- getAircraftTrack(icao24,departure_time, creds) - # Check for HTTP errors - if (httr::status_code(response) != 200) { - return(NULL) - } - - track_data <- fromJSON(content(response, as = "text", encoding = "UTF-8")) - - if (is.null(track_data$path) || length(track_data$path) < 2) { - return(NULL) - } - - route_df <- as.data.frame(track_data$path) - colnames(route_df) <- c("time", "lat", "lon", "alt", "heading", "on_ground") - - if (nrow(route_df) < 3) return(NULL) - - # Convert to meters - lat_ref <- route_df$lat[1] - lon_ref <- route_df$lon[1] - meters_per_deg_lat <- 111320 - meters_per_deg_lon <- 111320 * cos(lat_ref * pi / 180) - - x_meters <- (route_df$lon - lon_ref) * meters_per_deg_lon - y_meters <- (route_df$lat - lat_ref) * meters_per_deg_lat - time_seconds <- route_df$time - route_df$time[1] - - trj <- TrajFromCoords( - data.frame(x = x_meters, y = y_meters, time = time_seconds), - xCol = "x", yCol = "y", timeCol = "time" - ) - - # Calculate parameters - duration <- TrajDuration(trj) - path_length <- TrajLength(trj) - diffusion_dist <- TrajDistance(trj) - straight <- TrajStraightness(trj) - mean_vel <- path_length / duration + if (is.null(route_df) ||nrow(route_df) < 3) return(NULL) # Fractal dimension fractal <- tryCatch({ @@ -215,14 +183,7 @@ calculate_trajectory_params <- function(icao24, departure_time, creds) { } }, error = function(e) NA) - return(data.frame( - icao24 = icao24, - diffusion_distance_km = diffusion_dist / 1000, - straightness = straight, - duration_min = duration / 60, - mean_velocity_kmh = mean_vel * 3.6, - fractal_dimension = fractal - )) + return(getRouteSummary(route_df)) }, error = function(e) { message("Error processing ", icao24, ": ", e$message)