[general]
name=Aerodrome Spatial Planner
qgisMinimumVersion=3.16
qgisMaximumVersion=4.99
description=ICAO-based aerodrome and runway planning suite: wind analysis, runway orientation and length, obstacle limitation surfaces, lighting, terminal layout and GeoPackage outputs.
version=1.2
author=Rahul Pandey
email=rahulpandey696@gmail.com
about=Aerodrome Spatial Planner is a QGIS plugin for airport runway planning and site feasibility analysis, built on design parameters published in ICAO Annex 14 and Doc 9157. It fetches historical weather data from the Open-Meteo API, performs wind coverage and crosswind analysis, determines optimum runway orientation and ICAO-compliant runway length with declared distances, derives obstacles from DSM/DTM rasters, generates Obstacle Limitation Surfaces, ICAO lighting layouts, terminal and utility layouts and flight plan routes, and writes everything to GeoPackage along with maps, charts and compliance reports. Disclaimer: This plugin implements algorithms based on ICAO Annex 14 and Doc 9157 design parameters. It does not include, reproduce or distribute any ICAO copyrighted documents. Users must obtain official ICAO publications independently for compliance verification. This plugin is for educational and planning assistance purposes only. It is not an official ICAO product and is not certified by any aviation authority. The ICAO standards referenced are based on publicly available information (Annex 14, Doc 9157) and the user is responsible for verifying all outputs with official aerodrome design requirements. The author does not claim ownership of ICAO intellectual property; all ICAO material used is for reference only under fair use for educational purposes.
tracker=https://github.com/rahulpandey696/Aerodrome-Spatial-Planner/issues
repository=https://github.com/rahulpandey696/Aerodrome-Spatial-Planner
homepage=https://github.com/rahulpandey696/Aerodrome-Spatial-Planner
tags=airport, runway, ICAO, aviation, planning, wind analysis, obstacle limitation, lighting, flight plan, OLS, aerodrome
icon=icon.png
category=Aviation
experimental=False
deprecated=False
hasProcessingProvider=yes

changelog=
    [1.2] - 2026-09-14

    SECURITY
    - Removed all insecure TLS fallbacks. Six request sites (Open-Meteo archive
      and forecast, NOAA WMM declination, Overpass airways, climate data, API
      connectivity test) retried with verify=False after an SSLError, silencing
      urllib3 warnings and exposing those calls to interception. Certificate
      verification is now always enforced and urllib3.disable_warnings() is gone.
    - Output folder is opened via QDesktopServices.openUrl() instead of
      os.startfile() and subprocess.Popen(['open'/'xdg-open', ...]), removing
      partial-executable-path resolution and process spawning entirely.
    - Removed the unused xml.etree.ElementTree import from the engine, which
      flagged as an untrusted-XML parsing risk despite never being called.
    - Replaced silent exception handlers. Four "except: pass" blocks (lighting
      swatch colouring, two AOI centroid derivations, graphics-view zoom anchors)
      and one bare "except: continue" in compute_runway_slope() now catch
      Exception explicitly and report through QgsMessageLog, so failures are
      diagnosable instead of invisible. Slope sampling additionally reports how
      many chainage points could not be reprojected to the DTM CRS.
    - Illustrative placeholder obstacles in the obstruction map now use a seeded
      numpy.random.default_rng(42) rather than the random module.

    FIXED
    - Magnetic variation was applied with the wrong sign. Runway magnetic bearings
      and designators were computed as TRUE + variation instead of TRUE - variation.
      At sites with East variation this produced a magnetic bearing greater than
      true (the opposite of correct), and designators off by the full variation
      doubled. Affected analyze_runway_orientations_icao(), get_runway_designation(),
      and both runway-designation-point writers. Reported by a user testing against
      CYET (Edson, AB) and a second North American site.
    - Runway designator rounding used banker's rounding. Python's round() rounds
      half-to-even, so a magnetic bearing of 345 deg yielded RWY 34 (correct: 35),
      145 deg yielded 14 (correct: 15), and 005 deg yielded 36 (correct: 01). Now
      uses arithmetic round-half-up per ICAO Annex 14 Sec. 5.2.2.
    - Magnetic annual change was double-counted. Declination fetched from the NOAA
      WMM API is already valid for the current epoch, but the secular variation was
      then applied again across (current_year - wind_data_mid_year), adding up to
      ~10 years of spurious drift on top. The variation's source epoch is now
      tracked and advanced only to an explicit target epoch.

    CHANGED
    - True/magnetic conversion consolidated into true_to_magnetic(),
      magnetic_to_true() and runway_number_from_magnetic() on the engine class,
      replacing four independent inline copies of the formula.
    - Compliance reports and the analysis log now state variation as "16.0 deg E"
      rather than a bare signed value, and print the conversion convention in use.
    - NOAA declination fetch records the epoch of the returned value.
    - Declination button tooltip documents the sign convention.

    NOTES
    - Sign convention throughout: variation positive = East, matching NOAA WMM and
      IGRF output directly. MAGNETIC = TRUE - variation.
    - Negative longitudes were never implicated - geodesic calculations and bearing
      normalisation handle the Western Hemisphere correctly.
    - Wind roses are built from Open-Meteo ERA5 reanalysis (~25 km grid), not ASOS
      or METAR observations. Differences against station archives such as Iowa
      State Mesonet are expected and are not a defect. Both sources are true-north
      referenced.

    [1.0] - 2025-11-09
    - Initial release.

[license]
name=GNU GPL v3+
file=LICENSE

[requirements]
os=windows,linux,osx
python_requires=3.7
pip_requires=numpy, pandas, requests, rasterio, geopandas, shapely, pyproj, geographiclib, matplotlib, scipy, openpyxl, reportlab
