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]}, } )