fix(slope): Remove artificial high-frequency noise and calibrate gentle urban gradients
This commit is contained in:
@@ -311,14 +311,12 @@ export class MapsService {
|
|||||||
const startIdx = Math.min(interval[0], coords.length - 1);
|
const startIdx = Math.min(interval[0], coords.length - 1);
|
||||||
const endIdx = Math.min(interval[1], coords.length - 1);
|
const endIdx = Math.min(interval[1], coords.length - 1);
|
||||||
|
|
||||||
// 1. Localize text into 100% fluent Arabic (Translate "Continue onto", "toward", "Keep right", etc.)
|
// 1. Localize text into 100% fluent Arabic
|
||||||
const localizedBaseText = this.localizeInstructionToArabic(inst.text);
|
const localizedBaseText = this.localizeInstructionToArabic(inst.text);
|
||||||
|
|
||||||
if (startIdx < endIdx) {
|
if (startIdx < endIdx) {
|
||||||
let stepAscent = 0;
|
let stepAscent = 0;
|
||||||
let stepDescent = 0;
|
let stepDescent = 0;
|
||||||
let stepMaxIncline = 0;
|
|
||||||
let stepMaxDecline = 0;
|
|
||||||
|
|
||||||
for (let i = startIdx; i < endIdx; i++) {
|
for (let i = startIdx; i < endIdx; i++) {
|
||||||
const c1 = coords[i];
|
const c1 = coords[i];
|
||||||
@@ -326,38 +324,37 @@ export class MapsService {
|
|||||||
const e1 = this.estimateElevation(c1[1], c1[0]);
|
const e1 = this.estimateElevation(c1[1], c1[0]);
|
||||||
const e2 = this.estimateElevation(c2[1], c2[0]);
|
const e2 = this.estimateElevation(c2[1], c2[0]);
|
||||||
const dDiff = e2 - e1;
|
const dDiff = e2 - e1;
|
||||||
const segDist = Math.max(15, this.haversineDistance(c1[1], c1[0], c2[1], c2[0]));
|
|
||||||
|
|
||||||
if (dDiff > 0) stepAscent += dDiff;
|
if (dDiff > 0) stepAscent += dDiff;
|
||||||
else stepDescent += Math.abs(dDiff);
|
else stepDescent += Math.abs(dDiff);
|
||||||
|
|
||||||
const segSlope = Math.max(-16, Math.min(16, Math.round((dDiff / segDist) * 100)));
|
|
||||||
if (segSlope > stepMaxIncline) stepMaxIncline = segSlope;
|
|
||||||
if (segSlope < stepMaxDecline) stepMaxDecline = segSlope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
totalAscent += stepAscent;
|
totalAscent += stepAscent;
|
||||||
totalDescent += stepDescent;
|
totalDescent += stepDescent;
|
||||||
|
|
||||||
if (stepMaxIncline > maxInclinePercent) maxInclinePercent = stepMaxIncline;
|
const dist = Math.max(40, inst.distance || 1);
|
||||||
if (stepMaxDecline < maxDeclinePercent) maxDeclinePercent = stepMaxDecline;
|
|
||||||
|
|
||||||
// Representative slope for the step
|
|
||||||
const netStepDiff = stepAscent - stepDescent;
|
const netStepDiff = stepAscent - stepDescent;
|
||||||
const dominantSlope = Math.abs(stepMaxIncline) >= Math.abs(stepMaxDecline) ? stepMaxIncline : stepMaxDecline;
|
|
||||||
|
|
||||||
|
// Realistic slope calculation calibrated for highway/urban gradients
|
||||||
|
const calculatedSlope = Math.round((netStepDiff / dist) * 100);
|
||||||
|
const slopePercent = Math.max(-14, Math.min(14, calculatedSlope));
|
||||||
|
|
||||||
|
if (slopePercent > maxInclinePercent) maxInclinePercent = slopePercent;
|
||||||
|
if (slopePercent < maxDeclinePercent) maxDeclinePercent = slopePercent;
|
||||||
|
|
||||||
|
// Warning only for truly steep inclines/declines (10% or higher)
|
||||||
let warning_ar: string | null = null;
|
let warning_ar: string | null = null;
|
||||||
if (dominantSlope >= 8) {
|
if (slopePercent >= 10) {
|
||||||
warning_ar = `⚠️ تنبيه: صعود حاد (+${dominantSlope}%)`;
|
warning_ar = `⚠️ تنبيه: صعود حاد (+${slopePercent}%)`;
|
||||||
steepWarnings.push({ text: localizedBaseText, slopePercent: dominantSlope, type: 'incline', street: inst.street_name });
|
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'incline', street: inst.street_name });
|
||||||
} else if (dominantSlope <= -8) {
|
} else if (slopePercent <= -10) {
|
||||||
warning_ar = `⚠️ تنبيه: منحدر شديد (${dominantSlope}%) - خفف السرعة`;
|
warning_ar = `⚠️ تنبيه: منحدر شديد (${slopePercent}%) - خفف السرعة`;
|
||||||
steepWarnings.push({ text: localizedBaseText, slopePercent: dominantSlope, type: 'decline', street: inst.street_name });
|
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'decline', street: inst.street_name });
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...inst,
|
...inst,
|
||||||
slopePercent: dominantSlope,
|
slopePercent,
|
||||||
elevationChangeMeters: Math.round(netStepDiff),
|
elevationChangeMeters: Math.round(netStepDiff),
|
||||||
slopeWarning: warning_ar || undefined,
|
slopeWarning: warning_ar || undefined,
|
||||||
text: warning_ar ? `${localizedBaseText} (${warning_ar})` : localizedBaseText
|
text: warning_ar ? `${localizedBaseText} (${warning_ar})` : localizedBaseText
|
||||||
@@ -657,10 +654,7 @@ export class MapsService {
|
|||||||
baseElev = 640 + (lng - 36.25) * 20 - (lat - 32.0) * 30;
|
baseElev = 640 + (lng - 36.25) * 20 - (lat - 32.0) * 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. High-Frequency Micro-Topographic Relief (Simulating realistic urban street grades and slopes)
|
return Math.round(baseElev);
|
||||||
const microRelief = Math.sin(lat * 380.0 + lng * 220.0) * 22.0 + Math.cos(lat * 260.0 - lng * 410.0) * 18.0;
|
|
||||||
|
|
||||||
return Math.round(baseElev + microRelief);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private haversineDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
|
private haversineDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
|
||||||
|
|||||||
Reference in New Issue
Block a user