diff --git a/blueprints/weather_bp.py b/blueprints/weather_bp.py index 3f0be11..58eb662 100644 --- a/blueprints/weather_bp.py +++ b/blueprints/weather_bp.py @@ -4,7 +4,9 @@ import requests from lxml import etree -from flask import Blueprint, jsonify +from flask import Blueprint, jsonify, request +from shapely.geometry import shape, Point, Polygon +import json weather_blueprint = Blueprint('weather', __name__) @@ -36,28 +38,39 @@ def _metar(airport): metar_text = response.content.decode('utf-8') return jsonify([metar_text]) - @weather_blueprint.route('/sigmets') def _get_sigmets(): + artcc_id = request.args.get('artcc') response = requests.get( - 'https://aviationweather.gov/api/data/airsigmet?format=xml') - sigmet_list = [] - tree = etree.fromstring(response.content) - for entry in tree.iter('AIRSIGMET'): - try: - sigmet_entry = { - 'text': entry.find('raw_text').text, - 'hazard': dict(entry.find('hazard').attrib), - 'area': [[p.find('longitude').text, p.find('latitude').text] for p in entry.find('area').iter('point')], - 'altitude': dict(entry.find('altitude').attrib), - 'airsigmet_type': entry.find('airsigmet_type').text, - } - sigmet_list.append(sigmet_entry) - except Exception as e: - pass - # logging.Logger(str(e)) - return jsonify(sigmet_list) + 'https://aviationweather.gov/api/data/airsigmet?format=json').json() + + if artcc_id: + # Load ARTCC boundary polygon + with open('resources/ArtccBoundaries.geojson') as f: + geojson = json.load(f) + artcc_poly = None + for feature in geojson['features']: + if feature['properties']['id'].upper() == artcc_id.upper(): + artcc_poly = shape(feature['geometry']) + break + if not artcc_poly: + return jsonify([]) # or handle error + + filtered_sigmets = [] + for sigmet in response: + coords = sigmet.get('coords', []) + for coord in coords: + pt = Point(coord['lon'], coord['lat']) + if artcc_poly.contains(pt): + filtered_sigmets.append(sigmet) + break + # Check distance to polygon boundary + if artcc_poly.exterior.distance(pt) * 60 <= 150: # degrees to nm approx + filtered_sigmets.append(sigmet) + break + return jsonify(filtered_sigmets) + return jsonify(response) @weather_blueprint.route('/datis/airport/') def _get_datis(airport): diff --git a/libs/helpers.py b/libs/helpers.py index 34eeeb2..2ae1e4b 100644 --- a/libs/helpers.py +++ b/libs/helpers.py @@ -1,5 +1,5 @@ import re - +from math import radians, sin, cos, sqrt, atan2 def matches_airway_format(s: str) -> bool: return bool(re.match(r'^[A-Z]{1,2}\d+$', s)) diff --git a/requirements.txt b/requirements.txt index b2147a8..6118923 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,10 @@ itsdangerous==2.2.0 Jinja2==3.1.6 lxml==5.3.2 MarkupSafe==3.0.2 +numpy==2.3.2 pymongo==4.11.3 +python-dotenv==1.1.1 requests==2.32.3 +shapely==2.1.1 urllib3==2.3.0 Werkzeug==3.1.3