Files
RadioPropagationApi/api/app/services/antenna.py
T
2026-06-23 09:13:51 +03:00

64 lines
1.9 KiB
Python

from pyproj import Geod
from app.core.antenna import AntennaPattern, gain
from app.models.antenna import (
AntennaPatternSpec,
BeamRequest,
BeamResponse,
PatternResponse,
PatternSample,
)
_GEOD = Geod(ellps="WGS84")
def _to_core(spec: AntennaPatternSpec) -> AntennaPattern:
return AntennaPattern(
pattern=spec.pattern,
azimuth_deg=spec.azimuth_deg,
tilt_deg=spec.tilt_deg,
gain_dbi=spec.gain_dbi,
beamwidth_h=spec.beamwidth_h,
beamwidth_v=spec.beamwidth_v,
front_to_back_db=spec.front_to_back_db,
sidelobe_floor_db=spec.sidelobe_floor_db,
)
def normalize_pattern(spec: AntennaPatternSpec) -> PatternResponse:
pattern = _to_core(spec)
samples = [
PatternSample(azimuth_deg=az, elevation_deg=0, gain_dbi=gain(pattern, az, 0))
for az in range(0, 360, 5)
]
return PatternResponse(pattern=spec.pattern, samples=samples)
def beam_geometry(request: BeamRequest) -> BeamResponse:
antenna = request.antenna
half_width = (antenna.beamwidth_h or 360.0) / 2.0
if antenna.pattern == "omni":
azimuths = list(range(0, 361, 10))
else:
start = antenna.azimuth_deg - half_width
end = antenna.azimuth_deg + half_width
azimuths = [start + (end - start) * i / 32 for i in range(33)]
coords = [[request.origin.lon, request.origin.lat]]
for azimuth in azimuths:
lon, lat, _ = _GEOD.fwd(request.origin.lon, request.origin.lat, azimuth, request.radius_m)
coords.append([lon, lat])
coords.append([request.origin.lon, request.origin.lat])
return BeamResponse(
geojson={
"type": "Feature",
"properties": {
"pattern": antenna.pattern,
"azimuth_deg": antenna.azimuth_deg,
"radius_m": request.radius_m,
},
"geometry": {"type": "Polygon", "coordinates": [coords]},
}
)