A Streamlit application for visualizing runway geometry with UTM/WGS-84 georeferencing and KML export.
.
├── app.py # Streamlit UI — inputs, layout, orchestration
├── pista.py # Runway geometry: points, Surface class
├── visualizacao.py # Matplotlib figures (plan view + profile)
├── kml_export.py # GIS transformations + KML generation
└── requirements.txt
Defines runway geometry in a local Cartesian coordinate system (meters, origin at runway center).
Surface— a named polygon with up to 6 control points and a display color.build_pista(comprimento, azimute)— constructs the three key runway points:
rwy_end_1 → (-comprimento/2, 0, 0) # threshold 1
centro_pista → (0, 0, 0) # midpoint (origin)
rwy_end_2 → (+comprimento/2, 0, 0) # threshold 2
All coordinates live in a right-handed XYZ frame where:
- X runs along the runway axis (positive toward
rwy_end_2) - Y is lateral (perpendicular to runway)
- Z is altitude (relative, meters above origin)
Renders two views from the local coordinate system:
- Plan view (XY) — top-down, equal-aspect, with Surface polygons and labeled points
- Profile view (XZ) — longitudinal cross-section along Y = 0
No GIS logic here; this module only consumes the local (X, Y, Z) coordinates.
This is the core georeferencing module. It converts the local runway frame into real-world WGS-84 coordinates through a three-step pipeline.
(ref_lat, ref_lon) → (ref_E, ref_N)
Uses pyproj with the appropriate UTM EPSG code:
| Hemisphere | EPSG formula | Example (zone 22S) |
|---|---|---|
| South | 32700 + utm_zone |
EPSG:32722 |
| North | 32600 + utm_zone |
EPSG:32622 |
epsg = 32700 + utm_zone # south
proj_utm = Proj(f"epsg:{epsg}")
to_utm = Transformer.from_proj(proj_geo, proj_utm, always_xy=True)
ref_E, ref_N = to_utm.transform(ref_lon, ref_lat)UTM is a conformal projection, but grid north ≠ true north except on the central meridian. The angular difference is the meridian convergence (γ).
γ = Δλ · sin(φ)
Where:
φ= latitude of the reference point (radians)Δλ=ref_lon − lon_CM(longitude difference from the central meridian)lon_CM = −180 + (utm_zone − 1) × 6 + 3(central meridian of the UTM zone)
lon_cm = -180 + (utm_zone - 1) * 6 + 3
delta_lon = lon_deg - lon_cm
gamma = delta_lon * np.sin(np.radians(lat_deg)) # degreesThe user inputs a geographic azimuth (true north). To rotate correctly in the UTM grid, it is converted to a grid azimuth:
az_grid = azimute_geo − γ
This corrects for the angular skew introduced by the UTM projection.
With az_grid in hand, each local point (x, y) is transformed to UTM Easting/Northing via a 2D rigid rotation + translation:
E = ref_E + x·sin(az_grid) − y·cos(az_grid)
N = ref_N + x·cos(az_grid) + y·sin(az_grid)
This is a standard rotation matrix applied around the UTM origin:
| E | | sin θ -cos θ | | x | | ref_E |
| N | = | cos θ sin θ | · | y | + | ref_N |
where θ = az_grid in radians.
Finally, the UTM coordinates are projected back to WGS-84 geographic (lat/lon):
lon, lat = to_geo.transform(E, N)User Input
────────────────────────────────────────────────────────
ref_lat, ref_lon → WGS-84 geographic origin
azimute_geo (°) → true-north heading of runway
utm_zone, hemisphere → UTM zone definition
Step 1: Project origin to UTM
(ref_lat, ref_lon) ──pyproj──► (ref_E, ref_N)
Step 2: Compute meridian convergence
γ = Δλ · sin(φ)
az_grid = azimute_geo − γ
Step 3: For each local point (x, y, z):
E = ref_E + x·sin(az_grid) − y·cos(az_grid)
N = ref_N + x·cos(az_grid) + y·sin(az_grid)
(E, N) ──pyproj──► (lat, lon) [WGS-84]
Output: KML with <coordinates>lon,lat,0</coordinates>
The app exposes an Auditoria — Convergência Meridiana expander showing:
| Field | Description |
|---|---|
| Easting UTM | ref_E — UTM easting of the origin point |
| Northing UTM | ref_N — UTM northing of the origin point |
| Meridiano Central | lon_CM — central meridian of the UTM zone |
| Convergência γ | Angular deviation between grid and true north |
| Azimute Geográfico | Input true-north azimuth |
| Azimute Grid UTM | Corrected grid azimuth used in rotation |
Orchestrates the other three modules:
- Sidebar collects runway length and georef parameters
- Main area provides a dynamic surface editor (add/remove/edit polygons)
- Calls
build_pista→plot_vistas→generate_kmlin sequence - Displays the audit panel and a KML download button
Local frame (pista.py) UTM frame WGS-84
───────────────────── ────────────────── ──────────────
X → along runway Easting (E) Longitude (λ)
Y → lateral Northing (N) Latitude (φ)
Z → altitude (relative) — —
Origin: runway center Origin: UTM zone origin Ellipsoid: GRS-80
Units: meters Units: meters Units: degrees
| Package | Purpose |
|---|---|
streamlit |
Web UI |
numpy |
Numerical geometry (rotation, trig) |
matplotlib |
Plan and profile plots |
pyproj |
CRS definitions, UTM ↔ WGS-84 projection |
pip install -r requirements.txt
streamlit run app.py