refactor: consolidate main.Rmd statistics

This commit is contained in:
eneller
2026-01-20 15:46:26 +01:00
parent aacdc12638
commit f491345ea0

View File

@@ -43,13 +43,21 @@ flights <- getFlights(icao,Sys.time(), creds)
# TODO map from all available flights to tracks # TODO map from all available flights to tracks
query <- list(icao24= icao, time=as.numeric(flights[[1]][["departure_time"]])) query <- list(icao24= icao, time=as.numeric(flights[[1]][["departure_time"]]))
response <-makeAuthenticatedRequest('tracks/all',query, creds) # make a manual request because this API endpoint is considered experimental
track_data <- fromJSON(content(response, as = "text", encoding = "UTF-8")) getAircraftTrack <- function(icao, time, creds){
if (!is.null(track_data$path) && length(track_data$path) > 0) { 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) route_df <- as.data.frame(track_data$path)
colnames(route_df) <- c("time", "lat", "lon", "alt", "heading", "on_ground") 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)) message("Loading of route successfull! Points: ", nrow(route_df))
plot(route_df$lon, route_df$lat, type="o", pch=20, col="blue", plot(route_df$lon, route_df$lat, type="o", pch=20, col="blue",
@@ -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, plot(route_df$time, route_df$alt, type="l", col="red", lwd=2,
main=paste("Altitude profile of", icao), main=paste("Altitude profile of", icao),
xlab="Time (Unix)", ylab="Height (Meter)") xlab="Time (Unix)", ylab="Height (Meter)")
} else {
} else {
print("No path points from api") print("No path points from api")
} }
``` ```
# Trajectory Characteristics Analysis
```{r trajectory-analysis}
if (exists("route_df") && nrow(route_df) > 1) {
# Trajectory Characteristics Analysis
## Distance Approximation
```{r traj-dist}
getRouteDistance<- function(route_df){
# Convert lat/lon to approximate meters (using simple equirectangular projection) # Convert lat/lon to approximate meters (using simple equirectangular projection)
# Reference point: first coordinate # Reference point: first coordinate
lat_ref <- route_df$lat[1] lat_ref <- route_df$lat[1]
@@ -80,13 +89,29 @@ if (exists("route_df") && nrow(route_df) > 1) {
x_meters <- (route_df$lon - lon_ref) * meters_per_deg_lon x_meters <- (route_df$lon - lon_ref) * meters_per_deg_lon
y_meters <- (route_df$lat - lat_ref) * meters_per_deg_lat y_meters <- (route_df$lat - lat_ref) * meters_per_deg_lat
time_seconds <- route_df$time - route_df$time[1] return(list('x' = x_meters, 'y' = y_meters))
}
# Create trajr trajectory object 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( 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" xCol = "x", yCol = "y", timeCol = "time"
) )
}
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 # Calculate trajectory characteristics
@@ -103,7 +128,6 @@ if (exists("route_df") && nrow(route_df) > 1) {
straightness <- TrajStraightness(trj) straightness <- TrajStraightness(trj)
# 5. Mean travel velocity (meters/second) # 5. Mean travel velocity (meters/second)
mean_velocity <- path_length / duration
# 6. Fractal dimension (using divider method) # 6. Fractal dimension (using divider method)
# Note: requires sufficient points for accurate estimation # Note: requires sufficient points for accurate estimation
@@ -119,89 +143,33 @@ if (exists("route_df") && nrow(route_df) > 1) {
NA NA
}) })
# Create summary data frame return(data.frame(
trajectory_characteristics <- data.frame( icao24 = icao24,
Parameter = c( diffusion_distance_m = diffusion_distance, # meters
"Duration of Travel (s)", path_length_m = path_length, # meters
"Duration of Travel (min)", straightness = straightness,
"Path Length (m)", duration_s = duration, # seconds
"Path Length (km)", mean_velocity_kmh = mean_velocity * 3.6,
"Diffusion Distance (m)", fractal_dimension = fractal_dim
"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")
} }
print(getRouteSummary(route_df))
trj <- getTrajFromRoute(route_df)
plot(trj, main = paste("Trajectory of", icao))
``` ```
# Statistical Analysis of Multiple Trajectories # Statistical Analysis of Multiple Trajectories
```{r multi-trajectory-analysis} ```{r multi-trajectory-analysis}
# Function to calculate trajectory characteristics for a single flight # Function to calculate trajectory characteristics for a single flight
calculate_trajectory_params <- function(icao24, departure_time, creds) { calculate_trajectory_params <- function(icao24, departure_time, creds) {
tryCatch({ tryCatch({
query <- list(icao24 = icao24, time = as.numeric(departure_time)) route_df <- getAircraftTrack(icao24,departure_time, creds)
response <- makeAuthenticatedRequest('tracks/all', query, creds)
# Check for HTTP errors if (is.null(route_df) ||nrow(route_df) < 3) return(NULL)
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
# Fractal dimension # Fractal dimension
fractal <- tryCatch({ fractal <- tryCatch({
@@ -215,14 +183,7 @@ calculate_trajectory_params <- function(icao24, departure_time, creds) {
} }
}, error = function(e) NA) }, error = function(e) NA)
return(data.frame( return(getRouteSummary(route_df))
icao24 = icao24,
diffusion_distance_km = diffusion_dist / 1000,
straightness = straight,
duration_min = duration / 60,
mean_velocity_kmh = mean_vel * 3.6,
fractal_dimension = fractal
))
}, error = function(e) { }, error = function(e) {
message("Error processing ", icao24, ": ", e$message) message("Error processing ", icao24, ": ", e$message)