@mytec: WebGL works

This commit is contained in:
2026-02-06 22:17:24 +02:00
parent 81e078e92a
commit acfd9b8f7b
31 changed files with 4427 additions and 156 deletions

View File

@@ -271,6 +271,51 @@ class ApiService {
const data = await response.json();
return data.profile ?? data;
}
// === Link Budget API ===
async calculateLinkBudget(request: LinkBudgetRequest): Promise<LinkBudgetResponse> {
const response = await fetch(`${API_BASE}/api/coverage/link-budget`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json().catch(() => ({ detail: 'Link budget calculation failed' }));
throw new Error(error.detail || 'Link budget calculation failed');
}
return response.json();
}
// === Fresnel Profile API ===
async getFresnelProfile(request: FresnelProfileRequest): Promise<FresnelProfileResponse> {
const response = await fetch(`${API_BASE}/api/coverage/fresnel-profile`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json().catch(() => ({ detail: 'Fresnel profile calculation failed' }));
throw new Error(error.detail || 'Fresnel profile calculation failed');
}
return response.json();
}
// === Interference API ===
async calculateInterference(request: CoverageRequest): Promise<InterferenceResponse> {
const response = await fetch(`${API_BASE}/api/coverage/interference`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json().catch(() => ({ detail: 'Interference calculation failed' }));
throw new Error(error.detail || 'Interference calculation failed');
}
return response.json();
}
}
// === Region types ===
@@ -328,4 +373,113 @@ export interface TerrainProfilePoint {
distance: number;
}
// === Link Budget types ===
export interface LinkBudgetRequest {
tx_lat: number;
tx_lon: number;
tx_power_dbm: number;
tx_gain_dbi: number;
tx_cable_loss_db: number;
tx_height_m: number;
rx_lat: number;
rx_lon: number;
rx_gain_dbi: number;
rx_cable_loss_db: number;
rx_sensitivity_dbm: number;
rx_height_m: number;
frequency_mhz: number;
}
export interface LinkBudgetResponse {
distance_km: number;
distance_m: number;
tx_elevation_m: number;
rx_elevation_m: number;
eirp_dbm: number;
fspl_db: number;
terrain_loss_db: number;
total_path_loss_db: number;
los_clear: boolean;
obstructions: { distance_m: number; height_above_los_m: number }[];
rx_power_dbm: number;
margin_db: number;
status: 'OK' | 'FAIL';
link_budget: {
tx_power_dbm: number;
tx_gain_dbi: number;
tx_cable_loss_db: number;
rx_gain_dbi: number;
rx_cable_loss_db: number;
rx_sensitivity_dbm: number;
};
}
// === Fresnel Profile types ===
export interface FresnelProfileRequest {
tx_lat: number;
tx_lon: number;
tx_height_m: number;
rx_lat: number;
rx_lon: number;
rx_height_m: number;
frequency_mhz: number;
num_points?: number;
}
export interface FresnelProfilePoint {
distance: number;
lat: number;
lon: number;
terrain_elevation: number;
los_height: number;
fresnel_top: number;
fresnel_bottom: number;
f1_radius: number;
clearance: number;
}
export interface FresnelProfileResponse {
profile: FresnelProfilePoint[];
total_distance_m: number;
tx_elevation: number;
rx_elevation: number;
frequency_mhz: number;
wavelength_m: number;
los_clear: boolean;
fresnel_clear: boolean;
fresnel_clear_pct: number;
worst_clearance_m: number;
estimated_loss_db: number;
recommendation: string;
}
// === Interference types ===
export interface InterferencePoint {
lat: number;
lon: number;
ci_ratio_db: number;
best_server_idx: number;
best_server_rsrp: number;
}
export interface InterferenceResponse {
points: InterferencePoint[];
count: number;
stats: {
min_ci_db: number;
max_ci_db: number;
avg_ci_db: number;
good_coverage_pct: number;
marginal_coverage_pct: number;
interference_dominant_pct: number;
};
computation_time: number;
sites: { name: string; frequency_mhz: number }[];
frequency_groups: Record<number, number>;
warning: string | null;
}
export const api = new ApiService();