feat(routing): enable elevation profile and steep slope/incline warnings in routing API and frontend

This commit is contained in:
Hamza-Ayed
2026-08-18 12:10:32 +03:00
parent 06543ee8e0
commit 57e3da7ea4
12 changed files with 599 additions and 100 deletions
+61 -22
View File
@@ -1,31 +1,70 @@
import { RedisService } from '../common/redis.service';
export interface ArtilleryMissionRequest {
gunLat: number;
gunLng: number;
targetLat: number;
targetLng: number;
gunElevationOffset?: number;
targetElevationOffset?: number;
chargeType?: string;
muzzleVelocity?: number;
caliber?: string;
}
export interface TacticalSymbol {
id: string;
type: 'friendly' | 'hostile' | 'neutral' | 'unknown' | 'radar' | 'artillery' | 'minefield' | 'checkpoint' | 'hlz' | 'op';
name: string;
name_ar: string;
import { ArtilleryMissionRequestDto, TacticalSymbolDto } from './dto/tactical.dto';
export interface LosPoint {
index: number;
distanceMeters: number;
lat: number;
lng: number;
elevation?: number;
notes?: string;
timeAdded: string;
groundElevationMeters: number;
earthCurvatureSagittaMeters: number;
apparentElevationMeters: number;
sightRayElevationMeters: number;
marginMeters: number;
isVisible: boolean;
isDeadGround: boolean;
horizonAngleMils: number;
}
export interface LineOfSightResponse {
isDirectlyVisible: boolean;
status: 'CLEAR_LINE_OF_SIGHT' | 'OBSTRUCTED';
statusAr: string;
summary: {
totalDistanceMeters: number;
totalDistanceKm: number;
azimuthDegrees: number;
verticalAngleDegrees: number;
verticalAngleMilsNato: number;
verticalAngleMilsSoviet: number;
observerGroundElevationMeters: number;
observerTotalElevationMeters: number;
targetGroundElevationMeters: number;
targetTotalElevationMeters: number;
minElevationMeters: number;
maxElevationMeters: number;
deadGroundPercentage: number;
samplePointsCount: number;
stepMeters?: number;
};
highestObstacle: {
distanceMeters: number;
lat: number;
lng: number;
elevationMeters: number;
sightRayElevationMeters: number;
penetrationMeters: number;
} | null;
observer: {
lat: number;
lng: number;
heightOffsetMeters: number;
groundElevationMeters: number;
totalElevationMeters: number;
};
target: {
lat: number;
lng: number;
heightOffsetMeters: number;
groundElevationMeters: number;
totalElevationMeters: number;
};
profile?: LosPoint[];
}
export declare class TacticalService {
private readonly redisService;
private readonly logger;
constructor(redisService: RedisService);
calculateArtilleryFireMission(dto: ArtilleryMissionRequest): Promise<{
computeLineOfSight(observerLat: number, observerLng: number, targetLat: number, targetLng: number, observerHeight?: number, targetHeight?: number, samplesCount?: number, stepMeters?: number, compact?: boolean): Promise<LineOfSightResponse>;
calculateArtilleryFireMission(dto: ArtilleryMissionRequestDto): Promise<{
fireMissionId: string;
caliber: string;
muzzleVelocityMs: number;
@@ -57,12 +96,12 @@ export declare class TacticalService {
suitableCount: number;
zones: any[];
}>;
saveScenario(name: string, symbols: TacticalSymbol[]): Promise<{
saveScenario(name: string, symbols: TacticalSymbolDto[]): Promise<{
success: boolean;
count: number;
name: string;
}>;
getScenario(name: string): Promise<TacticalSymbol[]>;
getScenario(name: string): Promise<TacticalSymbolDto[]>;
private haversineDistance;
private calculateBearing;
private estimateElevation;