immunobiotech commited on
Commit
4546f60
·
verified ·
1 Parent(s): 4a0429b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -56
app.py CHANGED
@@ -1,76 +1,90 @@
1
  import gradio as gr
2
  import folium
3
  from folium import plugins
4
- import requests
5
  import pandas as pd
6
  from datetime import datetime
7
  import time
8
  import numpy as np
9
  import plotly.graph_objects as go
10
  from plotly.subplots import make_subplots
 
11
 
12
- # OpenSky API URL
13
- BASE_URL = "https://opensky-network.org/api"
 
 
14
 
15
- def get_states(bounds=None):
16
- """Get current aircraft states from OpenSky Network"""
17
- try:
18
- response = requests.get(f"{BASE_URL}/states/all",
19
- params=bounds if bounds else {},
20
- timeout=10) # 타임아웃 추가
21
- if response.status_code == 200:
22
- return response.json()
23
- else:
24
- print(f"API Error: {response.status_code}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  return None
26
- except Exception as e:
27
- print(f"Error fetching data: {e}")
28
- return None
29
 
30
  def create_monitoring_dashboard(states):
31
  """Create monitoring dashboard using Plotly"""
32
  if not states:
33
  return go.Figure()
34
 
35
- # Create subplots with specific types
 
 
 
 
 
36
  fig = make_subplots(
37
  rows=2, cols=2,
38
  subplot_titles=('Altitude Distribution', 'Speed Distribution',
39
  'Aircraft by Country', 'Aircraft Categories'),
40
  specs=[
41
  [{"type": "xy"}, {"type": "xy"}],
42
- [{"type": "xy"}, {"type": "domain"}] # pie chart를 위한 domain type
43
  ]
44
  )
45
 
46
- # Altitude distribution
47
- altitudes = [state[7] for state in states if state[7]]
48
  fig.add_trace(
49
- go.Histogram(
50
- x=altitudes,
51
- name="Altitude",
52
- marker_color='#4a90e2'
53
- ),
54
  row=1, col=1
55
  )
56
-
57
- # Speed distribution
58
- speeds = [state[9] for state in states if state[9]]
59
  fig.add_trace(
60
- go.Histogram(
61
- x=speeds,
62
- name="Speed",
63
- marker_color='#50C878'
64
- ),
65
  row=1, col=2
66
  )
67
-
68
- # Aircraft by country
69
- countries = pd.Series([state[2] for state in states if state[2]]).value_counts()
70
  fig.add_trace(
71
  go.Bar(
72
- x=countries.index[:10],
73
- y=countries.values[:10],
74
  name="Countries",
75
  marker_color='#FF6B6B'
76
  ),
@@ -82,7 +96,7 @@ def create_monitoring_dashboard(states):
82
  values = [40, 30, 20, 10] # Example distribution
83
  fig.add_trace(
84
  go.Pie(
85
- labels=categories,
86
  values=values,
87
  name="Categories",
88
  marker=dict(colors=['#4a90e2', '#50C878', '#FF6B6B', '#FFD700'])
@@ -106,11 +120,9 @@ def create_monitoring_dashboard(states):
106
  )
107
  )
108
 
109
- # Update axes
110
  fig.update_xaxes(gridcolor='rgba(255,255,255,0.1)', zeroline=False)
111
  fig.update_yaxes(gridcolor='rgba(255,255,255,0.1)', zeroline=False)
112
 
113
- # Update subplot titles
114
  for i in fig['layout']['annotations']:
115
  i['font'] = dict(size=12, color='white')
116
 
@@ -118,14 +130,12 @@ def create_monitoring_dashboard(states):
118
 
119
  def create_map(region="world"):
120
  """Create aircraft tracking map"""
121
- # 기본 맵 생성
122
  m = folium.Map(
123
  location=[30, 0],
124
  zoom_start=3,
125
  tiles='CartoDB dark_matter'
126
  )
127
 
128
- # 데이터 가져오기
129
  bounds = {
130
  "world": None,
131
  "europe": {"lamin": 35.0, "lomin": -15.0, "lamax": 60.0, "lomax": 40.0},
@@ -135,7 +145,7 @@ def create_map(region="world"):
135
 
136
  data = get_states(bounds.get(region))
137
 
138
- if not data or 'states' not in data or not data['states']:
139
  return (
140
  m._repr_html_(),
141
  create_monitoring_dashboard([]),
@@ -145,13 +155,12 @@ def create_map(region="world"):
145
  states = data['states']
146
  heat_data = []
147
 
148
- # Add aircraft markers
149
  for state in states:
150
- if state[6] and state[5]: # latitude and longitude check
151
- lat, lon = state[6], state[5]
152
- callsign = state[1] if state[1] else 'N/A'
153
- altitude = state[7] if state[7] else 'N/A'
154
- velocity = state[9] if state[9] else 'N/A'
155
 
156
  heat_data.append([lat, lon, 1])
157
 
@@ -161,7 +170,7 @@ def create_map(region="world"):
161
  <p><b>Callsign:</b> {callsign}</p>
162
  <p><b>Altitude:</b> {altitude}m</p>
163
  <p><b>Velocity:</b> {velocity}m/s</p>
164
- <p><b>Origin:</b> {state[2]}</p>
165
  </div>
166
  """
167
 
@@ -170,19 +179,17 @@ def create_map(region="world"):
170
  popup=folium.Popup(popup_content, max_width=300),
171
  icon=folium.DivIcon(
172
  html=f'''
173
- <div style="transform: rotate({state[10] if state[10] else 0}deg)">✈️</div>
174
  ''',
175
  icon_size=(20, 20)
176
  )
177
  ).add_to(m)
178
 
179
- # Add heatmap
180
  plugins.HeatMap(heat_data, radius=15).add_to(m)
181
 
182
- # Statistics
183
  total_aircraft = len(states)
184
- countries = len(set(state[2] for state in states if state[2]))
185
- avg_altitude = np.mean([state[7] for state in states if state[7]]) if states else 0
186
 
187
  stats = f"""
188
  📊 Real-time Statistics:
@@ -195,6 +202,8 @@ def create_map(region="world"):
195
 
196
  return m._repr_html_(), create_monitoring_dashboard(states), stats
197
 
 
 
198
  # Custom CSS
199
  custom_css = """
200
  .gradio-container {
 
1
  import gradio as gr
2
  import folium
3
  from folium import plugins
 
4
  import pandas as pd
5
  from datetime import datetime
6
  import time
7
  import numpy as np
8
  import plotly.graph_objects as go
9
  from plotly.subplots import make_subplots
10
+ from opensky_api import OpenSkyApi # OpenSky API 클래스 import
11
 
12
+ # OpenSky API 인증 정보
13
+ USERNAME = "seawolf2357"
14
+ PASSWORD = "Time2175!@"
15
+ api = OpenSkyApi(USERNAME, PASSWORD)
16
 
17
+ def get_states(bounds=None, max_retries=3):
18
+ """Get current aircraft states from OpenSky Network with retry logic"""
19
+ for attempt in range(max_retries):
20
+ try:
21
+ if bounds:
22
+ # bbox = (min latitude, max latitude, min longitude, max longitude)
23
+ states = api.get_states(bbox=(
24
+ bounds.get('lamin', None),
25
+ bounds.get('lamax', None),
26
+ bounds.get('lomin', None),
27
+ bounds.get('lomax', None)
28
+ ))
29
+ else:
30
+ states = api.get_states()
31
+
32
+ if states:
33
+ return {'states': states.states}
34
+ else:
35
+ if attempt < max_retries - 1:
36
+ wait_time = min(2 ** attempt, 60)
37
+ print(f"Retrying in {wait_time} seconds...")
38
+ time.sleep(wait_time)
39
+ continue
40
+ return None
41
+
42
+ except Exception as e:
43
+ print(f"Error fetching data: {e}")
44
+ if attempt < max_retries - 1:
45
+ time.sleep(5)
46
+ continue
47
  return None
48
+ return None
 
 
49
 
50
  def create_monitoring_dashboard(states):
51
  """Create monitoring dashboard using Plotly"""
52
  if not states:
53
  return go.Figure()
54
 
55
+ # StateVector 객체에서 데이터 추출
56
+ altitudes = [s.geo_altitude for s in states if s.geo_altitude is not None]
57
+ speeds = [s.velocity for s in states if s.velocity is not None]
58
+ countries = pd.Series([s.origin_country for s in states if s.origin_country])
59
+
60
+ # Create subplots
61
  fig = make_subplots(
62
  rows=2, cols=2,
63
  subplot_titles=('Altitude Distribution', 'Speed Distribution',
64
  'Aircraft by Country', 'Aircraft Categories'),
65
  specs=[
66
  [{"type": "xy"}, {"type": "xy"}],
67
+ [{"type": "xy"}, {"type": "domain"}]
68
  ]
69
  )
70
 
71
+ # Add traces
 
72
  fig.add_trace(
73
+ go.Histogram(x=altitudes, name="Altitude", marker_color='#4a90e2'),
 
 
 
 
74
  row=1, col=1
75
  )
76
+
 
 
77
  fig.add_trace(
78
+ go.Histogram(x=speeds, name="Speed", marker_color='#50C878'),
 
 
 
 
79
  row=1, col=2
80
  )
81
+
82
+ # Top 10 countries
83
+ top_countries = countries.value_counts().head(10)
84
  fig.add_trace(
85
  go.Bar(
86
+ x=top_countries.index,
87
+ y=top_countries.values,
88
  name="Countries",
89
  marker_color='#FF6B6B'
90
  ),
 
96
  values = [40, 30, 20, 10] # Example distribution
97
  fig.add_trace(
98
  go.Pie(
99
+ labels=categories,
100
  values=values,
101
  name="Categories",
102
  marker=dict(colors=['#4a90e2', '#50C878', '#FF6B6B', '#FFD700'])
 
120
  )
121
  )
122
 
 
123
  fig.update_xaxes(gridcolor='rgba(255,255,255,0.1)', zeroline=False)
124
  fig.update_yaxes(gridcolor='rgba(255,255,255,0.1)', zeroline=False)
125
 
 
126
  for i in fig['layout']['annotations']:
127
  i['font'] = dict(size=12, color='white')
128
 
 
130
 
131
  def create_map(region="world"):
132
  """Create aircraft tracking map"""
 
133
  m = folium.Map(
134
  location=[30, 0],
135
  zoom_start=3,
136
  tiles='CartoDB dark_matter'
137
  )
138
 
 
139
  bounds = {
140
  "world": None,
141
  "europe": {"lamin": 35.0, "lomin": -15.0, "lamax": 60.0, "lomax": 40.0},
 
145
 
146
  data = get_states(bounds.get(region))
147
 
148
+ if not data or not data['states']:
149
  return (
150
  m._repr_html_(),
151
  create_monitoring_dashboard([]),
 
155
  states = data['states']
156
  heat_data = []
157
 
 
158
  for state in states:
159
+ if state.latitude and state.longitude:
160
+ lat, lon = state.latitude, state.longitude
161
+ callsign = state.callsign if state.callsign else 'N/A'
162
+ altitude = state.geo_altitude if state.geo_altitude else 'N/A'
163
+ velocity = state.velocity if state.velocity else 'N/A'
164
 
165
  heat_data.append([lat, lon, 1])
166
 
 
170
  <p><b>Callsign:</b> {callsign}</p>
171
  <p><b>Altitude:</b> {altitude}m</p>
172
  <p><b>Velocity:</b> {velocity}m/s</p>
173
+ <p><b>Origin:</b> {state.origin_country}</p>
174
  </div>
175
  """
176
 
 
179
  popup=folium.Popup(popup_content, max_width=300),
180
  icon=folium.DivIcon(
181
  html=f'''
182
+ <div style="transform: rotate({state.true_track if state.true_track else 0}deg)">✈️</div>
183
  ''',
184
  icon_size=(20, 20)
185
  )
186
  ).add_to(m)
187
 
 
188
  plugins.HeatMap(heat_data, radius=15).add_to(m)
189
 
 
190
  total_aircraft = len(states)
191
+ countries = len(set(s.origin_country for s in states if s.origin_country))
192
+ avg_altitude = np.mean([s.geo_altitude for s in states if s.geo_altitude is not None]) if states else 0
193
 
194
  stats = f"""
195
  📊 Real-time Statistics:
 
202
 
203
  return m._repr_html_(), create_monitoring_dashboard(states), stats
204
 
205
+
206
+
207
  # Custom CSS
208
  custom_css = """
209
  .gradio-container {