Python-based analysis of radio-frequency propagation over real terrain, combining geospatial data, elevation profiles and multiple propagation models to study signal attenuation around a broadcasting transmitter.
The project was originally developed for a Telecommunications Projects course. The study case uses a Record TV broadcasting transmitter in São Paulo, Brazil, with terrain profiles generated around the transmitting site and evaluated using different RF propagation models.
The visualization compares terrain elevation and predicted received signal power for all implemented propagation models using a common dBm scale.
It also displays:
- terrain elevation;
- obstructed propagation points;
- transmitter position;
- distance rings;
- spatial variation of predicted signal strength.
The objective of the project was to investigate how terrain elevation and obstructions affect radio signal propagation around a real broadcasting transmitter.
The geographic study area was initially prepared with QGIS.
A set of radial paths was generated around the transmitter, covering directions from approximately:
1° → 360°
Each radial extended approximately:
70 km
with terrain samples taken approximately every:
30 m
The geographic coordinates were then enriched with elevation information and processed into terrain profiles used by the propagation models.
QGIS
│
├── Study area definition
└── Radial path generation
│
▼
Geographic coordinates
│
▼
Elevation data
│
▼
GPX / TXT data
│
▼
Profile normalization
│
▼
Terrain elevation profiles
│
▼
Line-of-sight / obstruction analysis
│
▼
RF propagation models
│
├── Free Space
├── Lee
├── Okumura-Hata
├── Walfisch-Ikegami
└── Analytical model
│
▼
Received power estimation
│
▼
Spatial comparison and visualization
- Python
- NumPy
- pandas
- Matplotlib
- Google Maps API
- QGIS
- GIS / geospatial processing
- RF propagation modeling
- terrain elevation analysis
Five propagation approaches are implemented.
Represents an ideal propagation environment without terrain or structural obstacles.
It provides a useful baseline for comparison with models that account for more realistic propagation conditions.
Empirical propagation model used to estimate received signal levels in urban environments.
The implementation includes configurable reference parameters stored with the study configuration.
Empirical model commonly used for terrestrial radio propagation studies in urban environments.
The implementation evaluates signal attenuation according to transmitter height, receiver height, frequency and propagation distance.
Model intended for urban propagation scenarios involving buildings and diffraction.
Important: for the parameters used in this study, the current scenario falls outside the recommended validity range of the Walfisch-Ikegami model. It is retained for comparative and experimental purposes rather than treated as a validated prediction for this specific case.
A custom analytical implementation used as an additional comparison against the empirical propagation models.
The main study parameters are centralized in:
scripts/models/study_parameters.py
Current values include:
| Parameter | Value |
|---|---|
| Antenna height | 155.98 m |
| Transmitter ground elevation | 825.8 m |
| Receiver height | 9.1 m |
| Transmitter power | 15,000 W |
| Frequency | 509 MHz |
| Receiver gain | 2.15 dBi |
| Transmitter gain | 9.29 dBd |
| Maximum profile distance | 69,960 m |
| Profile sampling interval | 30 m |
Keeping these parameters separate from the propagation algorithms makes it easier to reuse the processing pipeline for another transmitter or study area.
Terrain elevation is not treated only as visualization data.
The processing pipeline evaluates the geometry between transmitter and receiver points and identifies terrain that interferes with the expected propagation path.
The corrected implementation:
- treats the transmitter as
distance_m = 0; - uses the maximum profile distance at the receiver;
- uses the receiver height defined in the shared study parameters;
- evaluates terrain obstruction using the maximum terrain angle between transmitter and receiver;
- normalizes profile headers before consolidating results.
The propagation models calculate predicted received power using parameters such as:
- transmitter power;
- transmitter antenna gain;
- receiver gain;
- frequency;
- distance;
- propagation-model path loss;
- terrain-related conditions.
Transmitter gain specified in dBd is converted to dBi using the standard offset used by the implementation.
rf-propagation-terrain-analysis/
├── data/
│ ├── raw/
│ ├── intermediate/
│ ├── processed/
│ ├── selected/
│ └── auxiliary/
│
├── docs/
│ └── project_inventory.md
│
├── results/
│
├── scripts/
│ ├── models/
│ │ ├── modelo_analitico.py
│ │ ├── modelo_espaco_livre.py
│ │ ├── modelo_hata.py
│ │ ├── modelo_lee.py
│ │ ├── modelo_walfish_ikegami.py
│ │ └── study_parameters.py
│ │
│ ├── processing/
│ │ ├── process_txt_profiles.py
│ │ └── recalculate_obstructions.py
│ │
│ ├── results/
│ │ └── coverage_comparison.png
│ │
│ ├── visualize_coverage.py
│ └── README.md
│
├── .env.example
├── .gitignore
├── requirements.txt
└── README.md
Clone the repository:
git clone https://github.com/DanielMartinez2/rf-propagation-terrain-analysis.git
cd rf-propagation-terrain-analysisCreate a virtual environment:
python -m venv .venvActivate it.
.\.venv\Scripts\Activate.ps1source .venv/bin/activateInstall the dependencies:
pip install -r requirements.txtThe project currently depends on:
pandas
numpy
googlemaps
matplotlib
Some data-selection workflows can request elevation information using the Google Maps API.
The API key is not stored in the source code.
Set:
GOOGLE_MAPS_API_KEY
before running the corresponding script.
$env:GOOGLE_MAPS_API_KEY="your_api_key"set GOOGLE_MAPS_API_KEY=your_api_keyThe repository includes:
.env.example
as a reference for environment configuration.
The active processing pipeline is located inside scripts/.
From that directory, run the profile processing:
python processing/process_txt_profiles.pyRecalculate terrain obstructions:
python processing/recalculate_obstructions.pyThen execute the propagation models:
python models/modelo_espaco_livre.py
python models/modelo_lee.py
python models/modelo_hata.py
python models/modelo_walfish_ikegami.py
python models/modelo_analitico.pyFinally, generate the spatial comparison:
python visualize_coverage.pyThe visualization is generated as:
scripts/results/coverage_comparison.png
visualize_coverage.py consolidates the outputs produced by the five propagation models.
It:
- loads each model result with pandas;
- identifies the transmitter location;
- limits data to the study area;
- optionally downsamples the dataset for visualization;
- displays terrain elevation;
- identifies obstructed locations;
- draws distance rings;
- plots predicted received power;
- applies the same dBm scale across all five models;
- exports the complete comparison to PNG.
The sampling density can be changed with:
python visualize_coverage.py --stride 6A custom output path can also be provided:
python visualize_coverage.py --output results/my_comparison.pngThe GPX-to-text conversion stage used in this project eventually evolved into a separate reusable tool:
That repository isolates and modernizes the GPX/XML parsing stage, while this project focuses on the complete telecommunications analysis workflow.
The original academic implementation was later reviewed and reorganized for reproducibility and clearer separation of responsibilities.
Improvements include:
- centralized study parameters;
- corrected transmitter-to-receiver distance handling;
- consistent receiver height across processing stages;
- improved terrain-obstruction calculation;
- consistent transmitter and receiver gain handling;
- explicit dBd-to-dBi conversion;
- normalized dataset headers;
- separation of processing and propagation models;
- environment-based API-key handling;
- reproducible result generation;
- comparative spatial visualization.
This project demonstrates practical experience with:
- Python scientific programming;
- telecommunications engineering;
- RF propagation;
- mathematical and empirical propagation models;
- geospatial data processing;
- QGIS-based GIS workflows;
- elevation-profile processing;
- terrain obstruction analysis;
- signal path-loss calculations;
- pandas and NumPy;
- Matplotlib data visualization;
- API integration;
- structured data pipelines;
- reproducible engineering analysis.
Future development could include:
- interactive coverage maps;
- GeoJSON or GIS-layer export;
- automatic QGIS layer generation;
- comparison with measured field-strength data;
- statistical error analysis between models;
- Fresnel-zone visualization;
- additional propagation models;
- automatic transmitter configuration files;
- command-line execution of the complete pipeline;
- automated tests for propagation calculations;
- Jupyter notebooks for exploratory analysis;
- a web interface for comparing coverage models.
This project originated as an academic telecommunications study in which each student selected a broadcasting installation and analyzed radio propagation around it.
The selected case was a Record TV transmitter in São Paulo, Brazil.
The project combined GIS preparation, terrain elevation data, Python processing and RF propagation theory to evaluate how distance and terrain characteristics influence predicted received signal levels.
Daniel Martínez Alencar Freitas
GitHub: DanielMartinez2
