import gradio as gr import folium from folium import plugins import requests import pandas as pd from datetime import datetime import time import branca.colormap as cm import numpy as np import io from PIL import Image import plotly.graph_objects as go from plotly.subplots import make_subplots import threading # OpenSky API URL BASE_URL = "https://opensky-network.org/api" # Aircraft photos API (예시 - 실제 구현시에는 적절한 API로 대체 필요) AIRCRAFT_PHOTOS_API = "https://api.planespotters.net/pub/photos/hex/{icao24}" def get_aircraft_photo(icao24): """Get aircraft photo from Planespotters API""" try: response = requests.get(AIRCRAFT_PHOTOS_API.format(icao24=icao24)) data = response.json() if data.get('photos'): return data['photos'][0]['thumbnail_large']['src'] except: # 기본 항공기 이미지 URL 반환 return "https://example.com/default-aircraft.jpg" def get_states(bounds=None): """Get current aircraft states from OpenSky Network""" params = {} if bounds: params.update({ 'lamin': bounds[0], 'lomin': bounds[1], 'lamax': bounds[2], 'lomax': bounds[3] }) try: response = requests.get(f"{BASE_URL}/states/all", params=params) data = response.json() return data except Exception as e: print(f"Error fetching data: {e}") return None def create_monitoring_dashboard(data): """Create monitoring dashboard using Plotly""" if not data or 'states' not in data: return None states = data['states'] # Create subplots fig = make_subplots( rows=2, cols=2, subplot_titles=('Altitude Distribution', 'Speed Distribution', 'Aircraft by Country', 'Aircraft Categories') ) # Altitude distribution altitudes = [state[7] for state in states if state[7]] fig.add_trace( go.Histogram(x=altitudes, name="Altitude"), row=1, col=1 ) # Speed distribution speeds = [state[9] for state in states if state[9]] fig.add_trace( go.Histogram(x=speeds, name="Speed"), row=1, col=2 ) # Aircraft by country countries = pd.Series([state[2] for state in states if state[2]]).value_counts() fig.add_trace( go.Bar(x=countries.index[:10], y=countries.values[:10], name="Countries"), row=2, col=1 ) # Aircraft categories categories = pd.Series([state[17] for state in states if state[17]]).value_counts() fig.add_trace( go.Pie(labels=categories.index, values=categories.values, name="Categories"), row=2, col=2 ) fig.update_layout( height=800, showlegend=False, template="plotly_dark", paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)' ) return fig def create_map(region="world"): """Create aircraft tracking map""" bounds = { "world": None, "europe": [35.0, -15.0, 60.0, 40.0], "north_america": [25.0, -130.0, 50.0, -60.0], "asia": [10.0, 60.0, 50.0, 150.0] } data = get_states(bounds.get(region)) if not data or 'states' not in data: return None, None, "Failed to fetch aircraft data" m = folium.Map( location=[30, 0], zoom_start=3, tiles='CartoDB dark_matter' ) heat_data = [] # Add aircraft markers for state in data['states']: if state[6] and state[5]: lat, lon = state[6], state[5] callsign = state[1] if state[1] else 'N/A' altitude = state[7] if state[7] else 'N/A' velocity = state[9] if state[9] else 'N/A' icao24 = state[0] heat_data.append([lat, lon, 1]) # Get aircraft photo photo_url = get_aircraft_photo(icao24) popup_content = f"""
Callsign: {callsign}
ICAO24: {icao24}
Altitude: {altitude}m
Velocity: {velocity}m/s
Origin: {state[2]}
Status: {'On Ground' if state[8] else 'In Air'}