@smartnet360/svelte-components 0.0.102 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apps/antenna-pattern/index.d.ts +1 -0
- package/dist/apps/antenna-pattern/index.js +1 -0
- package/dist/apps/antenna-pattern/utils/load-static-antennas.d.ts +17 -0
- package/dist/apps/antenna-pattern/utils/load-static-antennas.js +83 -0
- package/dist/apps/site-check/SiteCheck.svelte +13 -81
- package/dist/apps/site-check/SiteCheckControls.svelte +0 -7
- package/dist/apps/site-check/helper.js +0 -33
- package/dist/apps/site-check/transforms.js +15 -65
- package/dist/core/CellTable/CellTable.svelte +456 -0
- package/dist/core/CellTable/CellTable.svelte.d.ts +27 -0
- package/dist/core/CellTable/CellTablePanel.svelte +211 -0
- package/dist/core/CellTable/CellTablePanel.svelte.d.ts +49 -0
- package/dist/core/CellTable/CellTableToolbar.svelte +218 -0
- package/dist/core/CellTable/CellTableToolbar.svelte.d.ts +32 -0
- package/dist/core/CellTable/column-config.d.ts +63 -0
- package/dist/core/CellTable/column-config.js +465 -0
- package/dist/core/CellTable/index.d.ts +10 -0
- package/dist/core/CellTable/index.js +11 -0
- package/dist/core/CellTable/types.d.ts +166 -0
- package/dist/core/CellTable/types.js +6 -0
- package/dist/core/Charts/ChartCard.svelte +118 -31
- package/dist/core/Charts/ChartCard.svelte.d.ts +2 -0
- package/dist/core/Charts/ChartComponent.svelte +8 -31
- package/dist/core/Charts/data-processor.js +1 -19
- package/dist/core/CoverageMap/ai/AITools.d.ts +117 -0
- package/dist/core/CoverageMap/ai/AITools.js +380 -0
- package/dist/core/CoverageMap/core/CoverageCalculator.d.ts +138 -0
- package/dist/core/CoverageMap/core/CoverageCalculator.js +375 -0
- package/dist/core/CoverageMap/core/GridCalculator.d.ts +115 -0
- package/dist/core/CoverageMap/core/GridCalculator.js +484 -0
- package/dist/core/CoverageMap/core/PathLossModels.d.ts +253 -0
- package/dist/core/CoverageMap/core/PathLossModels.js +380 -0
- package/dist/core/CoverageMap/core/SignalProcessor.d.ts +288 -0
- package/dist/core/CoverageMap/core/SignalProcessor.js +424 -0
- package/dist/core/CoverageMap/data/AntennaStore.d.ts +165 -0
- package/dist/core/CoverageMap/data/AntennaStore.js +327 -0
- package/dist/core/CoverageMap/data/SiteStore.d.ts +155 -0
- package/dist/core/CoverageMap/data/SiteStore.js +355 -0
- package/dist/core/CoverageMap/index.d.ts +74 -0
- package/dist/core/CoverageMap/index.js +103 -0
- package/dist/core/CoverageMap/types.d.ts +252 -0
- package/dist/core/CoverageMap/types.js +7 -0
- package/dist/core/CoverageMap/utils/geoUtils.d.ts +223 -0
- package/dist/core/CoverageMap/utils/geoUtils.js +374 -0
- package/dist/core/CoverageMap/utils/rfUtils.d.ts +329 -0
- package/dist/core/CoverageMap/utils/rfUtils.js +434 -0
- package/dist/core/CoverageMap/visualization/ColorSchemes.d.ts +149 -0
- package/dist/core/CoverageMap/visualization/ColorSchemes.js +377 -0
- package/dist/core/TreeView/index.d.ts +4 -4
- package/dist/core/TreeView/index.js +5 -5
- package/dist/core/TreeView/tree-utils.d.ts +12 -0
- package/dist/core/TreeView/tree-utils.js +115 -6
- package/dist/core/TreeView/tree.store.svelte.d.ts +94 -0
- package/dist/core/TreeView/tree.store.svelte.js +274 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +2 -0
- package/dist/map-v2/features/cells/controls/CellFilterControl.svelte +16 -27
- package/dist/map-v2/features/repeaters/controls/RepeaterFilterControl.svelte +33 -42
- package/dist/map-v2/features/sites/controls/SiteFilterControl.svelte +12 -19
- package/dist/map-v3/core/components/Map.svelte +4 -0
- package/dist/map-v3/core/stores/map.store.svelte.js +2 -0
- package/dist/map-v3/features/cells/components/CellFilterControl.svelte +24 -30
- package/dist/map-v3/features/coverage/index.d.ts +12 -0
- package/dist/map-v3/features/coverage/index.js +16 -0
- package/dist/map-v3/features/coverage/layers/CoverageLayer.svelte +198 -0
- package/dist/map-v3/features/coverage/layers/CoverageLayer.svelte.d.ts +10 -0
- package/dist/map-v3/features/coverage/logic/coloring.d.ts +28 -0
- package/dist/map-v3/features/coverage/logic/coloring.js +77 -0
- package/dist/map-v3/features/coverage/logic/geometry.d.ts +33 -0
- package/dist/map-v3/features/coverage/logic/geometry.js +112 -0
- package/dist/map-v3/features/coverage/stores/coverage.data.svelte.d.ts +46 -0
- package/dist/map-v3/features/coverage/stores/coverage.data.svelte.js +95 -0
- package/dist/map-v3/features/coverage/stores/coverage.display.svelte.d.ts +33 -0
- package/dist/map-v3/features/coverage/stores/coverage.display.svelte.js +90 -0
- package/dist/map-v3/features/coverage/types.d.ts +52 -0
- package/dist/map-v3/features/coverage/types.js +7 -0
- package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte +14 -20
- package/dist/map-v3/features/sites/components/SiteFilterControl.svelte +23 -33
- package/dist/map-v3/index.d.ts +4 -0
- package/dist/map-v3/index.js +5 -0
- package/package.json +4 -3
- package/dist/apps/site-check/transforms-old.d.ts +0 -56
- package/dist/apps/site-check/transforms-old.js +0 -273
- package/dist/core/TreeView/tree.store.d.ts +0 -10
- package/dist/core/TreeView/tree.store.js +0 -320
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage Map System - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* This file contains all TypeScript interfaces and types for the coverage calculation system.
|
|
5
|
+
* Designed to be AI-ready with structured outputs for future ChatGPT integration.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 2D Geographic position (latitude, longitude)
|
|
9
|
+
*/
|
|
10
|
+
export interface Position2D {
|
|
11
|
+
lat: number;
|
|
12
|
+
lng: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 3D Position with height above ground
|
|
16
|
+
*/
|
|
17
|
+
export interface Position3D extends Position2D {
|
|
18
|
+
height: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Geographic bounds (bounding box)
|
|
22
|
+
*/
|
|
23
|
+
export interface GeoBounds {
|
|
24
|
+
north: number;
|
|
25
|
+
south: number;
|
|
26
|
+
east: number;
|
|
27
|
+
west: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Antenna radiation pattern data
|
|
31
|
+
* Pattern arrays contain 360 values (one per degree, 0-359)
|
|
32
|
+
* Values represent attenuation in dB (0 = max gain, higher = more attenuation)
|
|
33
|
+
*/
|
|
34
|
+
export interface AntennaPattern {
|
|
35
|
+
name: string;
|
|
36
|
+
model: string;
|
|
37
|
+
frequency: number;
|
|
38
|
+
gain_dBd: number;
|
|
39
|
+
gain_dBi: number;
|
|
40
|
+
pattern: number[];
|
|
41
|
+
vertical_pattern: number[];
|
|
42
|
+
availableTilts: string[];
|
|
43
|
+
beamwidth_horizontal?: number;
|
|
44
|
+
beamwidth_vertical?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* RF Parameters for a single antenna/sector
|
|
48
|
+
*/
|
|
49
|
+
export interface RFParameters {
|
|
50
|
+
position: Position3D;
|
|
51
|
+
azimuth: number;
|
|
52
|
+
mechanicalTilt: number;
|
|
53
|
+
electricalTilt: number;
|
|
54
|
+
txPower: number;
|
|
55
|
+
frequency: number;
|
|
56
|
+
antennaPattern: AntennaPattern;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sector configuration (extends RFParameters with metadata)
|
|
60
|
+
*/
|
|
61
|
+
export interface SectorConfig extends RFParameters {
|
|
62
|
+
sectorId: string;
|
|
63
|
+
sectorName: string;
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
color: string;
|
|
66
|
+
technology?: string;
|
|
67
|
+
band?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Site configuration (collection of sectors)
|
|
71
|
+
*/
|
|
72
|
+
export interface SiteConfiguration {
|
|
73
|
+
siteId: string;
|
|
74
|
+
siteName: string;
|
|
75
|
+
position: Position2D;
|
|
76
|
+
sectors: SectorConfig[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Path loss model types
|
|
80
|
+
*/
|
|
81
|
+
export type PathLossModel = 'free-space' | 'hata-urban' | 'hata-suburban' | 'cost231';
|
|
82
|
+
/**
|
|
83
|
+
* Grid calculation settings
|
|
84
|
+
*/
|
|
85
|
+
export interface GridSettings {
|
|
86
|
+
centerPosition: Position2D;
|
|
87
|
+
cellSizeMeters: number;
|
|
88
|
+
maxRadiusKm: number;
|
|
89
|
+
pathLossModel: PathLossModel;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Signal strength thresholds for coverage zones
|
|
93
|
+
*/
|
|
94
|
+
export interface SignalThresholds {
|
|
95
|
+
excellent: number;
|
|
96
|
+
good: number;
|
|
97
|
+
fair: number;
|
|
98
|
+
edge: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Coverage calculation configuration
|
|
102
|
+
*/
|
|
103
|
+
export interface CoverageConfig {
|
|
104
|
+
site: SiteConfiguration;
|
|
105
|
+
gridSettings: GridSettings;
|
|
106
|
+
signalThresholds: SignalThresholds;
|
|
107
|
+
calculateInterference: boolean;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Signal quality level
|
|
111
|
+
*/
|
|
112
|
+
export type SignalQuality = 'excellent' | 'good' | 'fair' | 'poor' | 'no-signal';
|
|
113
|
+
/**
|
|
114
|
+
* Single grid cell result
|
|
115
|
+
*/
|
|
116
|
+
export interface GridCell {
|
|
117
|
+
position: Position2D;
|
|
118
|
+
signalStrength: number;
|
|
119
|
+
quality: SignalQuality;
|
|
120
|
+
dominantSector?: string;
|
|
121
|
+
sectors: {
|
|
122
|
+
[sectorId: string]: number;
|
|
123
|
+
};
|
|
124
|
+
color: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Complete coverage grid
|
|
128
|
+
*/
|
|
129
|
+
export interface CoverageGrid {
|
|
130
|
+
centerPosition: Position2D;
|
|
131
|
+
cellSizeMeters: number;
|
|
132
|
+
bounds: GeoBounds;
|
|
133
|
+
rows: number;
|
|
134
|
+
cols: number;
|
|
135
|
+
cells: GridCell[][];
|
|
136
|
+
stats: CoverageStats;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Coverage statistics and metrics
|
|
140
|
+
*/
|
|
141
|
+
export interface CoverageStats {
|
|
142
|
+
totalAreaKm2: number;
|
|
143
|
+
coveredAreaKm2: number;
|
|
144
|
+
coveragePercentage: number;
|
|
145
|
+
excellentAreaKm2: number;
|
|
146
|
+
goodAreaKm2: number;
|
|
147
|
+
fairAreaKm2: number;
|
|
148
|
+
poorAreaKm2: number;
|
|
149
|
+
sectorStats: {
|
|
150
|
+
[sectorId: string]: {
|
|
151
|
+
maxRangeKm: number;
|
|
152
|
+
avgSignalDbm: number;
|
|
153
|
+
coverageAreaKm2: number;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
overlapAreas?: {
|
|
157
|
+
sectors: string[];
|
|
158
|
+
areaKm2: number;
|
|
159
|
+
avgSignalDifference: number;
|
|
160
|
+
}[];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Coverage calculation result (AI-ready format)
|
|
164
|
+
*/
|
|
165
|
+
export interface CoverageResult {
|
|
166
|
+
config: CoverageConfig;
|
|
167
|
+
grid: CoverageGrid;
|
|
168
|
+
timestamp: Date;
|
|
169
|
+
calculationTimeMs: number;
|
|
170
|
+
summary: {
|
|
171
|
+
description: string;
|
|
172
|
+
issues: string[];
|
|
173
|
+
metrics: Record<string, number>;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Calculation progress callback
|
|
178
|
+
*/
|
|
179
|
+
export interface CalculationProgress {
|
|
180
|
+
stage: 'initializing' | 'calculating' | 'analyzing' | 'complete';
|
|
181
|
+
progress: number;
|
|
182
|
+
message: string;
|
|
183
|
+
cellsProcessed?: number;
|
|
184
|
+
totalCells?: number;
|
|
185
|
+
}
|
|
186
|
+
export type ProgressCallback = (progress: CalculationProgress) => void;
|
|
187
|
+
/**
|
|
188
|
+
* AI analysis request
|
|
189
|
+
*/
|
|
190
|
+
export interface AIAnalysisRequest {
|
|
191
|
+
coverageResult: CoverageResult;
|
|
192
|
+
analysisType: 'coverage-quality' | 'optimization' | 'anomaly' | 'comparison' | 'report';
|
|
193
|
+
context?: Record<string, any>;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* AI analysis response
|
|
197
|
+
*/
|
|
198
|
+
export interface AIAnalysisResponse {
|
|
199
|
+
type: string;
|
|
200
|
+
summary: string;
|
|
201
|
+
recommendations: AIRecommendation[];
|
|
202
|
+
insights: string[];
|
|
203
|
+
confidence: number;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* AI recommendation
|
|
207
|
+
*/
|
|
208
|
+
export interface AIRecommendation {
|
|
209
|
+
sectorId: string;
|
|
210
|
+
parameter: 'azimuth' | 'tilt' | 'power' | 'height';
|
|
211
|
+
currentValue: number;
|
|
212
|
+
suggestedValue: number;
|
|
213
|
+
reasoning: string;
|
|
214
|
+
expectedImprovement: string;
|
|
215
|
+
priority: 'high' | 'medium' | 'low';
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* AI tool-callable function signature
|
|
219
|
+
* These functions will be exposed to ChatGPT for AI integration
|
|
220
|
+
*/
|
|
221
|
+
export interface AIToolFunction {
|
|
222
|
+
name: string;
|
|
223
|
+
description: string;
|
|
224
|
+
parameters: Record<string, any>;
|
|
225
|
+
execute: (params: any) => Promise<any>;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Color scheme for heatmap
|
|
229
|
+
*/
|
|
230
|
+
export type ColorScheme = 'heatmap' | 'categorical' | 'single-color';
|
|
231
|
+
/**
|
|
232
|
+
* Visualization options
|
|
233
|
+
*/
|
|
234
|
+
export interface VisualizationOptions {
|
|
235
|
+
colorScheme: ColorScheme;
|
|
236
|
+
opacity: number;
|
|
237
|
+
showAntennaMarker: boolean;
|
|
238
|
+
showBeamDirection: boolean;
|
|
239
|
+
showDistanceRings: boolean;
|
|
240
|
+
showAzimuthLabels: boolean;
|
|
241
|
+
showSignalValues: boolean;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Map integration interface
|
|
245
|
+
* Allows component to work with or without a map instance
|
|
246
|
+
*/
|
|
247
|
+
export interface MapIntegration {
|
|
248
|
+
mapInstance?: any;
|
|
249
|
+
addLayer: (layer: any) => void;
|
|
250
|
+
removeLayer: (layer: any) => void;
|
|
251
|
+
fitBounds: (bounds: GeoBounds) => void;
|
|
252
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Geographic Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides heavily commented geographic calculations:
|
|
5
|
+
* - Distance calculations (Haversine formula)
|
|
6
|
+
* - Bearing calculations (initial and final bearings)
|
|
7
|
+
* - Destination point calculations (given distance and bearing)
|
|
8
|
+
* - Coordinate conversions
|
|
9
|
+
*
|
|
10
|
+
* All calculations assume:
|
|
11
|
+
* - Earth is a sphere (acceptable for ranges < 100km)
|
|
12
|
+
* - Radius = 6371 km (mean Earth radius)
|
|
13
|
+
* - Angles in degrees for input/output, radians for calculations
|
|
14
|
+
*/
|
|
15
|
+
import type { Position2D, Position3D, GeoBounds } from '../types';
|
|
16
|
+
/**
|
|
17
|
+
* Calculate distance between two points using Haversine formula
|
|
18
|
+
*
|
|
19
|
+
* The Haversine formula calculates the great-circle distance between two points
|
|
20
|
+
* on a sphere given their longitudes and latitudes.
|
|
21
|
+
*
|
|
22
|
+
* Formula:
|
|
23
|
+
* a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlon/2)
|
|
24
|
+
* c = 2 × atan2(√a, √(1−a))
|
|
25
|
+
* d = R × c
|
|
26
|
+
*
|
|
27
|
+
* Where:
|
|
28
|
+
* - Δlat = lat2 - lat1 (difference in latitude)
|
|
29
|
+
* - Δlon = lon2 - lon1 (difference in longitude)
|
|
30
|
+
* - R = Earth's radius (6371 km)
|
|
31
|
+
* - All angles in radians for calculation
|
|
32
|
+
*
|
|
33
|
+
* Accuracy:
|
|
34
|
+
* - Very accurate for distances < 100 km
|
|
35
|
+
* - Error < 0.5% for distances up to 1000 km
|
|
36
|
+
* - Assumes spherical Earth (good enough for RF planning)
|
|
37
|
+
*
|
|
38
|
+
* @param point1 - First position (lat, lng in degrees)
|
|
39
|
+
* @param point2 - Second position (lat, lng in degrees)
|
|
40
|
+
* @returns Distance in kilometers
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const distance = calculateDistance(
|
|
44
|
+
* { lat: 40.7128, lng: -74.0060 }, // New York
|
|
45
|
+
* { lat: 51.5074, lng: -0.1278 } // London
|
|
46
|
+
* );
|
|
47
|
+
* // Returns: ~5570 km
|
|
48
|
+
*/
|
|
49
|
+
export declare function calculateDistance(point1: Position2D, point2: Position2D): number;
|
|
50
|
+
/**
|
|
51
|
+
* Calculate 3D distance including height difference
|
|
52
|
+
*
|
|
53
|
+
* For RF calculations, we often need to account for antenna height and
|
|
54
|
+
* target height (e.g., mobile at 1.5m). This uses Pythagoras in 3D:
|
|
55
|
+
*
|
|
56
|
+
* Formula:
|
|
57
|
+
* d_3d = √(d_horizontal² + Δh²)
|
|
58
|
+
*
|
|
59
|
+
* Where:
|
|
60
|
+
* - d_horizontal = Haversine distance (horizontal plane)
|
|
61
|
+
* - Δh = height difference in km (h2 - h1)
|
|
62
|
+
*
|
|
63
|
+
* Note: For typical cellular ranges (< 10km) and heights (< 100m),
|
|
64
|
+
* the height component is usually negligible (< 0.1% error if ignored)
|
|
65
|
+
*
|
|
66
|
+
* @param point1 - First position with height
|
|
67
|
+
* @param point2 - Second position (height defaults to 1.5m if not provided)
|
|
68
|
+
* @returns 3D distance in kilometers
|
|
69
|
+
*/
|
|
70
|
+
export declare function calculate3DDistance(point1: Position3D, point2: Position2D): number;
|
|
71
|
+
/**
|
|
72
|
+
* Calculate initial bearing from point1 to point2
|
|
73
|
+
*
|
|
74
|
+
* Bearing (or azimuth) is the compass direction from one point to another.
|
|
75
|
+
* This calculates the INITIAL bearing - the direction you would initially
|
|
76
|
+
* travel on a great circle route.
|
|
77
|
+
*
|
|
78
|
+
* Formula:
|
|
79
|
+
* θ = atan2(sin(Δlon) × cos(lat2),
|
|
80
|
+
* cos(lat1) × sin(lat2) - sin(lat1) × cos(lat2) × cos(Δlon))
|
|
81
|
+
*
|
|
82
|
+
* Important notes:
|
|
83
|
+
* - Bearing changes along a great circle path (Earth is curved!)
|
|
84
|
+
* - For short distances (< 100 km), this is effectively constant
|
|
85
|
+
* - Result is in degrees: 0° = North, 90° = East, 180° = South, 270° = West
|
|
86
|
+
*
|
|
87
|
+
* RF Planning Usage:
|
|
88
|
+
* Use this to determine the relative angle between antenna and target.
|
|
89
|
+
* Subtract antenna azimuth to get the angle relative to main beam direction.
|
|
90
|
+
*
|
|
91
|
+
* @param from - Starting position (lat, lng in degrees)
|
|
92
|
+
* @param to - Destination position (lat, lng in degrees)
|
|
93
|
+
* @returns Bearing in degrees (0-360), where 0 = North
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* const bearing = calculateBearing(
|
|
97
|
+
* { lat: 40.7128, lng: -74.0060 }, // From New York
|
|
98
|
+
* { lat: 51.5074, lng: -0.1278 } // To London
|
|
99
|
+
* );
|
|
100
|
+
* // Returns: ~51° (northeast)
|
|
101
|
+
*/
|
|
102
|
+
export declare function calculateBearing(from: Position2D, to: Position2D): number;
|
|
103
|
+
/**
|
|
104
|
+
* Calculate destination point given start point, distance, and bearing
|
|
105
|
+
*
|
|
106
|
+
* This is the inverse of the bearing calculation. Given a starting point,
|
|
107
|
+
* a distance, and a direction, it calculates where you would end up.
|
|
108
|
+
*
|
|
109
|
+
* Formula (spherical Earth):
|
|
110
|
+
* lat2 = asin(sin(lat1) × cos(d/R) + cos(lat1) × sin(d/R) × cos(θ))
|
|
111
|
+
* lon2 = lon1 + atan2(sin(θ) × sin(d/R) × cos(lat1),
|
|
112
|
+
* cos(d/R) - sin(lat1) × sin(lat2))
|
|
113
|
+
*
|
|
114
|
+
* Where:
|
|
115
|
+
* - d/R = angular distance (distance / Earth radius)
|
|
116
|
+
* - θ = bearing in radians
|
|
117
|
+
*
|
|
118
|
+
* RF Planning Usage:
|
|
119
|
+
* This is used to project antenna coverage patterns onto the map.
|
|
120
|
+
* For each angle around the antenna, calculate signal range, then
|
|
121
|
+
* use this function to get the geographic coordinate at that range.
|
|
122
|
+
*
|
|
123
|
+
* @param start - Starting position (lat, lng in degrees)
|
|
124
|
+
* @param distanceKm - Distance to travel in kilometers
|
|
125
|
+
* @param bearingDeg - Direction to travel in degrees (0 = North, 90 = East)
|
|
126
|
+
* @returns Destination position (lat, lng in degrees)
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* const destination = calculateDestinationPoint(
|
|
130
|
+
* { lat: 40.7128, lng: -74.0060 }, // New York
|
|
131
|
+
* 100, // 100 km
|
|
132
|
+
* 45 // Northeast
|
|
133
|
+
* );
|
|
134
|
+
* // Returns position ~100km northeast of New York
|
|
135
|
+
*/
|
|
136
|
+
export declare function calculateDestinationPoint(start: Position2D, distanceKm: number, bearingDeg: number): Position2D;
|
|
137
|
+
/**
|
|
138
|
+
* Calculate elevation angle from antenna to target
|
|
139
|
+
*
|
|
140
|
+
* Elevation angle is the vertical angle from horizontal plane to target.
|
|
141
|
+
* This is critical for RF calculations because:
|
|
142
|
+
* 1. Antenna vertical pattern varies with elevation angle
|
|
143
|
+
* 2. Mechanical/electrical tilt affects this relationship
|
|
144
|
+
*
|
|
145
|
+
* Formula:
|
|
146
|
+
* elevation = atan((h_antenna - h_target) / d_horizontal)
|
|
147
|
+
*
|
|
148
|
+
* Sign convention:
|
|
149
|
+
* - Positive angle = target above antenna (upward tilt needed)
|
|
150
|
+
* - Negative angle = target below antenna (downward tilt, typical case)
|
|
151
|
+
* - Zero angle = target at same height as antenna
|
|
152
|
+
*
|
|
153
|
+
* Typical Values (cellular networks):
|
|
154
|
+
* - Antenna at 30m, mobile at 1.5m, distance 1km → elevation ≈ -1.6°
|
|
155
|
+
* - Antenna at 30m, mobile at 1.5m, distance 5km → elevation ≈ -0.3°
|
|
156
|
+
* - Most cellular targets are within ±10° elevation
|
|
157
|
+
*
|
|
158
|
+
* @param antennaPos - Antenna position with height (meters above ground)
|
|
159
|
+
* @param targetPos - Target position (lat, lng)
|
|
160
|
+
* @param targetHeight - Target height in meters (default: 1.5m for mobile)
|
|
161
|
+
* @returns Elevation angle in degrees (negative = below horizon)
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* const elevation = calculateElevationAngle(
|
|
165
|
+
* { lat: 40.7128, lng: -74.0060, height: 30 }, // 30m antenna
|
|
166
|
+
* { lat: 40.7150, lng: -74.0070 }, // Target location
|
|
167
|
+
* 1.5 // 1.5m mobile height
|
|
168
|
+
* );
|
|
169
|
+
* // Returns: ~-1.5° (target below antenna)
|
|
170
|
+
*/
|
|
171
|
+
export declare function calculateElevationAngle(antennaPos: Position3D, targetPos: Position2D, targetHeight?: number): number;
|
|
172
|
+
/**
|
|
173
|
+
* Calculate bounding box for a square grid around a center point
|
|
174
|
+
*
|
|
175
|
+
* Given a center point and a radius, calculates the geographic bounds
|
|
176
|
+
* (north, south, east, west) that fully contain a square grid.
|
|
177
|
+
*
|
|
178
|
+
* This is used to:
|
|
179
|
+
* 1. Determine grid extents for coverage calculations
|
|
180
|
+
* 2. Set map viewport to show entire coverage area
|
|
181
|
+
* 3. Optimize calculations (skip points outside bounds)
|
|
182
|
+
*
|
|
183
|
+
* Note: Creates a square box, not a circle, for simplicity
|
|
184
|
+
*
|
|
185
|
+
* @param center - Center position (lat, lng)
|
|
186
|
+
* @param radiusKm - Radius from center in kilometers
|
|
187
|
+
* @returns Bounding box (north, south, east, west in degrees)
|
|
188
|
+
*/
|
|
189
|
+
export declare function calculateBounds(center: Position2D, radiusKm: number): GeoBounds;
|
|
190
|
+
/**
|
|
191
|
+
* Calculate the area of a geographic bounding box
|
|
192
|
+
*
|
|
193
|
+
* Approximates area using spherical geometry.
|
|
194
|
+
* For small areas (< 100 km²), treats as rectangle on flat surface.
|
|
195
|
+
*
|
|
196
|
+
* @param bounds - Geographic bounds
|
|
197
|
+
* @returns Area in square kilometers
|
|
198
|
+
*/
|
|
199
|
+
export declare function calculateBoundsArea(bounds: GeoBounds): number;
|
|
200
|
+
/**
|
|
201
|
+
* Normalize angle to 0-360 range
|
|
202
|
+
*
|
|
203
|
+
* @param angle - Angle in degrees (any value)
|
|
204
|
+
* @returns Normalized angle (0-360)
|
|
205
|
+
*/
|
|
206
|
+
export declare function normalizeAngle(angle: number): number;
|
|
207
|
+
/**
|
|
208
|
+
* Calculate angular difference between two bearings
|
|
209
|
+
* Always returns the smallest angle between them (0-180)
|
|
210
|
+
*
|
|
211
|
+
* @param bearing1 - First bearing in degrees
|
|
212
|
+
* @param bearing2 - Second bearing in degrees
|
|
213
|
+
* @returns Angular difference in degrees (0-180)
|
|
214
|
+
*/
|
|
215
|
+
export declare function angleDifference(bearing1: number, bearing2: number): number;
|
|
216
|
+
/**
|
|
217
|
+
* Check if a point is within a bounding box
|
|
218
|
+
*
|
|
219
|
+
* @param point - Position to check
|
|
220
|
+
* @param bounds - Bounding box
|
|
221
|
+
* @returns true if point is inside bounds
|
|
222
|
+
*/
|
|
223
|
+
export declare function isPointInBounds(point: Position2D, bounds: GeoBounds): boolean;
|