TFRs toggle, pounds fix, photo override fix

-TFRS toggle
-Pounds fix
-Photo override fix
- Airport code on image fix
-TFR above/below addition
This commit is contained in:
Jack Sweeney 2022-06-09 18:15:54 -04:00
parent 823d280965
commit d39b404f62
5 changed files with 138 additions and 124 deletions

View File

@ -40,6 +40,7 @@ URL = webhookurl
[TFRS] [TFRS]
URL = http://127.0.0.1:5000/detailed_all URL = http://127.0.0.1:5000/detailed_all
ENABLE = False
[TWITTER] [TWITTER]
#GLOBAL TWITTER CONSUMER KEY AND CONSUMERS SECRET ONLY NEED TO BE HERE NOW #GLOBAL TWITTER CONSUMER KEY AND CONSUMERS SECRET ONLY NEED TO BE HERE NOW

View File

@ -80,16 +80,20 @@ def get_adsbx_screenshot(file_path, url_params, enable_labels=False, enable_trac
photo_box = browser.find_element_by_id("airplanePhoto") photo_box = browser.find_element_by_id("airplanePhoto")
finally: finally:
import requests, json import requests, json
photo_list = json.loads(requests.get("https://raw.githubusercontent.com/Jxck-S/aircraft-photos/main/photo-list.json").text) photo_list = json.loads(requests.get("https://raw.githubusercontent.com/Jxck-S/aircraft-photos/main/photo-list.json", timeout=20).text)
if reg in photo_list.keys(): if reg in photo_list.keys():
browser.execute_script("arguments[0].id = 'airplanePhoto';", photo_box) browser.execute_script("arguments[0].id = 'airplanePhoto';", photo_box)
browser.execute_script("arguments[0].removeAttribute('width')", photo_box) browser.execute_script("arguments[0].removeAttribute('width')", photo_box)
browser.execute_script("arguments[0].style.width = 'inherit';", photo_box) browser.execute_script("arguments[0].style.width = '200px';", photo_box)
browser.execute_script("arguments[0].style.float = 'left';", photo_box) browser.execute_script("arguments[0].style.float = 'left';", photo_box)
browser.execute_script(f"arguments[0].src = 'https://raw.githubusercontent.com/Jxck-S/aircraft-photos/main/images/{reg}.jpg';", photo_box) browser.execute_script(f"arguments[0].src = 'https://raw.githubusercontent.com/Jxck-S/aircraft-photos/main/images/{reg}.jpg';", photo_box)
image_copy_right = browser.find_element_by_id("copyrightInfo") image_copy_right = browser.find_element_by_id("copyrightInfo")
browser.execute_cdp_cmd('Emulation.setScriptExecutionDisabled', {'value': True}) browser.execute_cdp_cmd('Emulation.setScriptExecutionDisabled', {'value': True})
browser.execute_script(f"arguments[0].appendChild(document.createTextNode('Image © {photo_list[reg]['photographer']}'))", image_copy_right) copy_right_children = image_copy_right.find_elements(By.XPATH, "*")
if len(copy_right_children) > 0:
browser.execute_script(f"arguments[0].innerText = 'Image © {photo_list[reg]['photographer']}'", copy_right_children[0])
else:
browser.execute_script(f"arguments[0].appendChild(document.createTextNode('Image © {photo_list[reg]['photographer']}'))", image_copy_right)
except Exception as e: except Exception as e:
print("Error on changing photo", e) print("Error on changing photo", e)
if 'type' in overrides.keys(): if 'type' in overrides.keys():

View File

@ -31,7 +31,7 @@ def fuel_calculation(aircraft_icao_type, minutes):
fuel_flight_info['fuel_used_kg'] = round(fuel_used_kg) fuel_flight_info['fuel_used_kg'] = round(fuel_used_kg)
fuel_flight_info["fuel_used_gal"] = round(fuel_used_gal) fuel_flight_info["fuel_used_gal"] = round(fuel_used_gal)
fuel_flight_info['fuel_used_lters'] = round(fuel_used_gal*3.78541) fuel_flight_info['fuel_used_lters'] = round(fuel_used_gal*3.78541)
fuel_flight_info["fuel_used_pds"] = round(fuel_used_kg * 2.20462) fuel_flight_info["fuel_used_lbs"] = round(fuel_used_kg * 2.20462)
fuel_flight_info["c02_tons"] = c02_tons fuel_flight_info["c02_tons"] = c02_tons
print ("Fuel info", fuel_flight_info) print ("Fuel info", fuel_flight_info)
return fuel_flight_info return fuel_flight_info
@ -43,10 +43,10 @@ def fuel_message(fuel_info):
cost = "{:,}".format(fuel_info['fuel_price']) cost = "{:,}".format(fuel_info['fuel_price'])
gallons = "{:,}".format(fuel_info['fuel_used_gal']) gallons = "{:,}".format(fuel_info['fuel_used_gal'])
lters = "{:,}".format(fuel_info['fuel_used_lters']) lters = "{:,}".format(fuel_info['fuel_used_lters'])
pds = "{:,}".format(fuel_info['fuel_used_pds']) lbs = "{:, }".format(fuel_info['fuel_used_lbs'])
kgs = "{:,}".format(fuel_info['fuel_used_kg']) kgs = "{:,}".format(fuel_info['fuel_used_kg'])
fuel_message = f"~ {gallons} gallons ({lters} liters). \n~ {pds} pds ({kgs} kg) of jet fuel used. \n~ ${cost} cost of fuel. \n~ {fuel_info['c02_tons']} tons of CO2 emissions." fuel_message = f"~ {gallons} gallons ({lters} liters). \n~ {lbs} lbs ({kgs} kg) of jet fuel used. \n~ ${cost} cost of fuel. \n~ {fuel_info['c02_tons']} tons of CO2 emissions."
print(fuel_message) print(fuel_message)
return fuel_message return fuel_message
#fuel_info = fuel_calculation("B738", 180) #fuel_info = fuel_calculation("GLF6", 548.1)
#fuel_message(fuel_info) #fuel_message(fuel_info)

View File

@ -44,8 +44,13 @@ def append_airport(filename, airport, text_credit=None):
draw.text((x, y), text, fill=white, font=head_font) draw.text((x, y), text, fill=white, font=head_font)
#ICAO | IATA #ICAO | IATA
(x, y) = (330, 765) (x, y) = (330, 765)
text = iata + " / " + icao if airport['iata_code'] != '' and airport['icao'] != '':
draw.text((x, y), text, fill=black, font=font) airport_codes = airport['iata_code'] + " / " + airport['icao']
elif airport['icao'] != '':
airport_codes = airport['icao']
else:
airport_codes = airport['ident']
draw.text((x, y), airport_codes, fill=black, font=font)
#Distance #Distance
(x, y) = (460, 765) (x, y) = (460, 765)
text = str(round(distance_mi, 2)) + "mi / " + str(round(distance_km, 2)) + "km away" text = str(round(distance_mi, 2)) + "mi / " + str(round(distance_km, 2)) + "km away"

View File

@ -485,7 +485,7 @@ class Plane:
to_coord = (known_to_airport['latitude_deg'], known_to_airport['longitude_deg']) to_coord = (known_to_airport['latitude_deg'], known_to_airport['longitude_deg'])
distance_mi = float(geodesic(from_coord, to_coord).mi) distance_mi = float(geodesic(from_coord, to_coord).mi)
distance_nm = distance_mi / 1.150779448 distance_nm = distance_mi / 1.150779448
distance_message = f"{'{:,}'.format(round(distance_mi))} mile ({'{:,}'.format(round(distance_nm))} NM) flight from {nearest_from_airport['iata_code']} to {nearest_airport_dict['iata_code']}\n" distance_message = f"{'{:,}'.format(round(distance_mi))} mile ({'{:,}'.format(round(distance_nm))} NM) flight from {nearest_from_airport['iata_code'] if nearest_from_airport['iata_code'] != '' else nearest_from_airport['ident']} to {nearest_airport_dict['iata_code'] if nearest_airport_dict['iata_code'] != '' else nearest_airport_dict['ident']}\n"
else: else:
distance_message = "" distance_message = ""
if landed_time is not None and self.type is not None: if landed_time is not None and self.type is not None:
@ -644,121 +644,124 @@ class Plane:
from shapely.geometry.polygon import Polygon from shapely.geometry.polygon import Polygon
from shapely.geometry import Point from shapely.geometry import Point
import requests, json import requests, json
tfr_url = Plane.main_config.get("TFRS", "URL")
response = requests.get(tfr_url, timeout=30)
tfrs = json.loads(response.text)
closest_tfr = None closest_tfr = None
in_tfr = None in_tfr = None
for tfr in tfrs: if Plane.main_config.getboolean("TFRS", "ENABLE"):
if in_tfr is not None: tfr_url = Plane.main_config.get("TFRS", "URL")
break response = requests.get(tfr_url, timeout=30)
elif tfr['details'] is not None and 'shapes' in tfr['details'].keys(): tfrs = json.loads(response.text)
for index, shape in enumerate(tfr['details']['shapes']): for tfr in tfrs:
if 'txtName' not in shape.keys(): if in_tfr is not None:
shape['txtName'] = 'shape_'+str(index)
polygon = None
if shape['type'] == "poly":
points = shape['points']
elif shape['type'] == "circle":
from functools import partial
import pyproj
from shapely.ops import transform
from shapely.geometry import Point
proj_wgs84 = pyproj.Proj('+proj=longlat +datum=WGS84')
def geodesic_point_buffer(lat, lon, km):
# Azimuthal equidistant projection
aeqd_proj = '+proj=aeqd +lat_0={lat} +lon_0={lon} +x_0=0 +y_0=0'
project = partial(
pyproj.transform,
pyproj.Proj(aeqd_proj.format(lat=lat, lon=lon)),
proj_wgs84)
buf = Point(0, 0).buffer(km * 1000) # distance in metres
return transform(project, buf).exterior.coords[:]
radius_km = float(shape['radius']) * 1.852
b = geodesic_point_buffer(shape['lat'], shape['lon'], radius_km)
points = []
for coordinate in b:
points.append([coordinate[1], coordinate[0]])
elif shape['type'] in ["polyarc", "polyexclude"]:
points = shape['all_points']
aircraft_location = Point(self.latitude, self.longitude)
if polygon is None:
polygon = Polygon(points)
if polygon.contains(aircraft_location):
in_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName']}
break
else:
point_dists = []
for point in points:
from geopy.distance import geodesic
point = tuple(point)
point_dists.append(float((geodesic((self.latitude, self.longitude), point).mi)))
distance = min(point_dists)
if closest_tfr is None:
closest_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName'], 'distance' : round(distance)}
elif distance < closest_tfr['distance']:
closest_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName'], 'distance' : round(distance)}
if in_tfr is not None:
for shape in in_tfr['info']['details']['shapes']:
if shape['txtName'] == in_tfr['closest_shape_name']:
valDistVerUpper, valDistVerLower = int(shape['valDistVerUpper']), int(shape['valDistVerLower'])
print("In TFR based off location checking alt next", in_tfr)
break break
if not (self.alt_ft >= valDistVerLower and self.alt_ft <= valDistVerUpper): elif tfr['details'] is not None and 'shapes' in tfr['details'].keys():
print("But not in alt of TFR") for index, shape in enumerate(tfr['details']['shapes']):
closest_tfr = in_tfr if 'txtName' not in shape.keys():
closest_tfr['distance'] = 0 shape['txtName'] = 'shape_'+str(index)
in_tfr = None polygon = None
if in_tfr is None: if shape['type'] == "poly":
print("Closest TFR", closest_tfr) points = shape['points']
#Generate Map elif shape['type'] == "circle":
import staticmaps from functools import partial
context = staticmaps.Context() import pyproj
context.set_tile_provider(staticmaps.tile_provider_OSM) from shapely.ops import transform
if in_tfr is not None: from shapely.geometry import Point
shapes = in_tfr['info']['details']['shapes'] proj_wgs84 = pyproj.Proj('+proj=longlat +datum=WGS84')
else: def geodesic_point_buffer(lat, lon, km):
shapes = closest_tfr['info']['details']['shapes'] # Azimuthal equidistant projection
def draw_poly(context, pairs): aeqd_proj = '+proj=aeqd +lat_0={lat} +lon_0={lon} +x_0=0 +y_0=0'
pairs.append(pairs[0]) project = partial(
context.add_object( pyproj.transform,
staticmaps.Area( pyproj.Proj(aeqd_proj.format(lat=lat, lon=lon)),
[staticmaps.create_latlng(lat, lng) for lat, lng in pairs], proj_wgs84)
fill_color=staticmaps.parse_color("#FF000033"), buf = Point(0, 0).buffer(km * 1000) # distance in metres
width=2, return transform(project, buf).exterior.coords[:]
color=staticmaps.parse_color("#8B0000"), radius_km = float(shape['radius']) * 1.852
b = geodesic_point_buffer(shape['lat'], shape['lon'], radius_km)
points = []
for coordinate in b:
points.append([coordinate[1], coordinate[0]])
elif shape['type'] in ["polyarc", "polyexclude"]:
points = shape['all_points']
aircraft_location = Point(self.latitude, self.longitude)
if polygon is None:
polygon = Polygon(points)
if polygon.contains(aircraft_location):
in_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName']}
break
else:
point_dists = []
for point in points:
from geopy.distance import geodesic
point = tuple(point)
point_dists.append(float((geodesic((self.latitude, self.longitude), point).mi)))
distance = min(point_dists)
if closest_tfr is None:
closest_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName'], 'distance' : round(distance)}
elif distance < closest_tfr['distance']:
closest_tfr = {'info': tfr, 'closest_shape_name' : shape['txtName'], 'distance' : round(distance)}
if in_tfr is not None:
for shape in in_tfr['info']['details']['shapes']:
if shape['txtName'] == in_tfr['closest_shape_name']:
valDistVerUpper, valDistVerLower = int(shape['valDistVerUpper']), int(shape['valDistVerLower'])
print("In TFR based off location checking alt next", in_tfr)
break
if not (self.alt_ft >= valDistVerLower and self.alt_ft <= valDistVerUpper):
if self.alt_ft > valDistVerUpper:
in_tfr['context'] = "above"
elif self.alt_ft < valDistVerLower:
in_tfr['context'] = "below"
print("But not in alt of TFR", in_tfr['context'])
if in_tfr is None:
print("Closest TFR", closest_tfr)
#Generate Map
import staticmaps
context = staticmaps.Context()
context.set_tile_provider(staticmaps.tile_provider_OSM)
if in_tfr is not None:
shapes = in_tfr['info']['details']['shapes']
else:
shapes = closest_tfr['info']['details']['shapes']
def draw_poly(context, pairs):
pairs.append(pairs[0])
context.add_object(
staticmaps.Area(
[staticmaps.create_latlng(lat, lng) for lat, lng in pairs],
fill_color=staticmaps.parse_color("#FF000033"),
width=2,
color=staticmaps.parse_color("#8B0000"),
)
) )
) return context
return context for shape in shapes:
for shape in shapes: if shape['type'] == "poly":
if shape['type'] == "poly": pairs = shape['points']
pairs = shape['points'] context = draw_poly(context, pairs)
context = draw_poly(context, pairs) elif shape['type'] == "polyarc" or shape['type'] == "polyexclude":
elif shape['type'] == "polyarc" or shape['type'] == "polyexclude": pairs = shape['all_points']
pairs = shape['all_points'] context = draw_poly(context, pairs)
context = draw_poly(context, pairs) elif shape['type'] =="circle":
elif shape['type'] =="circle": center = [shape['lat'], shape['lon']]
center = [shape['lat'], shape['lon']] center1 = staticmaps.create_latlng(center[0], center[1])
center1 = staticmaps.create_latlng(center[0], center[1]) context.add_object(staticmaps.Circle(center1, (float(shape['radius']) * 1.852), fill_color=staticmaps.parse_color("#FF000033"), color=staticmaps.parse_color("#8B0000"), width=2))
context.add_object(staticmaps.Circle(center1, (float(shape['radius']) * 1.852), fill_color=staticmaps.parse_color("#FF000033"), color=staticmaps.parse_color("#8B0000"), width=2)) context.add_object(staticmaps.Marker(center1, color=staticmaps.RED))
context.add_object(staticmaps.Marker(center1, color=staticmaps.RED)) def tfr_image(context, aircraft_coords):
def tfr_image(context, aircraft_coords): from PIL import Image
from PIL import Image heading = self.track
heading = self.track heading *= -1
heading *= -1 im = Image.open('./dependencies/ac.png')
im = Image.open('./dependencies/ac.png') im_rotate = im.rotate(heading, resample=Image.BICUBIC)
im_rotate = im.rotate(heading, resample=Image.BICUBIC) import tempfile
import tempfile rotated_file = f"{tempfile.gettempdir()}/rotated_ac.png"
rotated_file = f"{tempfile.gettempdir()}/rotated_ac.png" im_rotate.save(rotated_file)
im_rotate.save(rotated_file) pos = staticmaps.create_latlng(aircraft_coords[0], aircraft_coords[1])
pos = staticmaps.create_latlng(aircraft_coords[0], aircraft_coords[1]) marker = staticmaps.ImageMarker(pos, rotated_file, origin_x=35, origin_y=35)
marker = staticmaps.ImageMarker(pos, rotated_file, origin_x=35, origin_y=35) context.add_object(marker)
context.add_object(marker) image = context.render_cairo(1000, 1000)
image = context.render_cairo(1000, 1000) os.remove(rotated_file)
os.remove(rotated_file) tfr_map_filename = f"{tempfile.gettempdir()}/{self.icao}_TFR_.png"
tfr_map_filename = f"{tempfile.gettempdir()}/{self.icao}_TFR_.png" image.write_to_png(tfr_map_filename)
image.write_to_png(tfr_map_filename) return tfr_map_filename
return tfr_map_filename
from defSS import get_adsbx_screenshot from defSS import get_adsbx_screenshot
@ -773,12 +776,13 @@ class Plane:
message = f"Circling {round(nearest_airport_dict['distance_mi'], 2)}mi {cardinal} of {nearest_airport_dict['icao']}, {nearest_airport_dict['name']} at {self.alt_ft}ft. " message = f"Circling {round(nearest_airport_dict['distance_mi'], 2)}mi {cardinal} of {nearest_airport_dict['icao']}, {nearest_airport_dict['name']} at {self.alt_ft}ft. "
tfr_map_filename = None tfr_map_filename = None
if in_tfr is not None: if in_tfr is not None:
message += f" Inside TFR {in_tfr['info']['NOTAM']}, a TFR for {in_tfr['info']['Type'].title()}" context = "Inside" if 'context' not in in_tfr.keys() else "Above" if in_tfr['context'] == 'above' else "Below"
message += f" {context} TFR {in_tfr['info']['NOTAM']}, a TFR for {in_tfr['info']['Type'].title()}"
tfr_map_filename = tfr_image(context, (self.latitude, self.longitude)) tfr_map_filename = tfr_image(context, (self.latitude, self.longitude))
elif in_tfr is None and "distance" in closest_tfr.keys() and closest_tfr["distance"] <= 20: elif in_tfr is None and closest_tfr is not None and "distance" in closest_tfr.keys() and closest_tfr["distance"] <= 20:
message += f" {closest_tfr['distance']} miles from TFR {closest_tfr['info']['NOTAM']}, a TFR for {closest_tfr['info']['Type']}" message += f" {closest_tfr['distance']} miles from TFR {closest_tfr['info']['NOTAM']}, a TFR for {closest_tfr['info']['Type']}"
tfr_map_filename = tfr_image(context, (self.latitude, self.longitude)) tfr_map_filename = tfr_image(context, (self.latitude, self.longitude))
elif in_tfr is None and "distance" not in closest_tfr.keys(): elif in_tfr is None and closest_tfr is not None and "distance" not in closest_tfr.keys():
message += f" near TFR {closest_tfr['info']['NOTAM']}, a TFR for {closest_tfr['info']['Type']}" message += f" near TFR {closest_tfr['info']['NOTAM']}, a TFR for {closest_tfr['info']['Type']}"
raise Exception(message) raise Exception(message)