feat(routing): pure Arabic localization for all navigation instructions (translate Continue onto, toward, keep right, etc.)
This commit is contained in:
@@ -241,6 +241,9 @@ export class MapsService {
|
||||
const startIdx = Math.min(interval[0], 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.)
|
||||
const localizedBaseText = this.localizeInstructionToArabic(inst.text);
|
||||
|
||||
if (startIdx < endIdx) {
|
||||
const startCoord = coords[startIdx]; // [lng, lat]
|
||||
const endCoord = coords[endIdx];
|
||||
@@ -262,10 +265,10 @@ export class MapsService {
|
||||
|
||||
if (slopePercent >= 9) {
|
||||
warning_ar = `⚠️ تنبيه: صعود حاد (+${slopePercent}%)`;
|
||||
steepWarnings.push({ text: inst.text, slopePercent, type: 'incline', street: inst.street_name });
|
||||
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'incline', street: inst.street_name });
|
||||
} else if (slopePercent <= -9) {
|
||||
warning_ar = `⚠️ تنبيه: منحدر شديد (${slopePercent}%) - خفف السرعة`;
|
||||
steepWarnings.push({ text: inst.text, slopePercent, type: 'decline', street: inst.street_name });
|
||||
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'decline', street: inst.street_name });
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -273,11 +276,14 @@ export class MapsService {
|
||||
slopePercent,
|
||||
elevationChangeMeters: Math.round(elevDiff),
|
||||
slopeWarning: warning_ar || undefined,
|
||||
text: warning_ar ? `${inst.text} (${warning_ar})` : inst.text
|
||||
text: warning_ar ? `${localizedBaseText} (${warning_ar})` : localizedBaseText
|
||||
};
|
||||
}
|
||||
|
||||
return inst;
|
||||
return {
|
||||
...inst,
|
||||
text: localizedBaseText
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -293,6 +299,109 @@ export class MapsService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates any English phrases from routing engines (GraphHopper) into natural, fluent Arabic.
|
||||
*/
|
||||
private localizeInstructionToArabic(rawText: string): string {
|
||||
if (!rawText) return '';
|
||||
|
||||
let text = rawText.trim();
|
||||
|
||||
// 1. English Directional & Maneuver Replacements
|
||||
const phrases: [RegExp, string][] = [
|
||||
// Continuations
|
||||
[/^Continue onto\s+/i, 'تابع السير في '],
|
||||
[/^Continue on\s+/i, 'تابع السير في '],
|
||||
[/^Continue straight\s+/i, 'تابع السير بشكل مستقيم في '],
|
||||
[/^Continue straight$/i, 'تابع السير للأمام مباشرة'],
|
||||
[/^Continue\s*$/i, 'تابع السير للأمام'],
|
||||
|
||||
// Roundabouts
|
||||
[/في الدوران\s*،\s*أتخذ مخرج\s+(\d+)\s+من خلال/i, 'عند الدوار، اسلك المخرج $1 عبر'],
|
||||
[/في الدوران\s*،\s*اتخذ مخرج\s+(\d+)\s+من خلال/i, 'عند الدوار، اسلك المخرج $1 عبر'],
|
||||
[/في الدوران\s*،\s*أتخذ مخرج\s+(\d+)/i, 'عند الدوار، اسلك المخرج $1'],
|
||||
[/في الدوران\s*،\s*اتخذ مخرج\s+(\d+)/i, 'عند الدوار، اسلك المخرج $1'],
|
||||
[/At roundabout, take exit\s+(\d+)\s+onto/i, 'عند الدوار، اسلك المخرج $1 عبر'],
|
||||
[/At roundabout, take exit\s+(\d+)/i, 'عند الدوار، اسلك المخرج $1'],
|
||||
[/In roundabout, take exit\s+(\d+)/i, 'عند الدوار، اسلك المخرج $1'],
|
||||
|
||||
// Turns
|
||||
[/^Turn sharp right onto\s+/i, 'انعطف يميناً بشكل حاد إلى '],
|
||||
[/^Turn slight right onto\s+/i, 'انعطف يميناً بشكل طفيف إلى '],
|
||||
[/^Turn right onto\s+/i, 'اتجه يميناً إلى '],
|
||||
[/^Turn sharp right/i, 'انعطف يميناً بشكل حاد'],
|
||||
[/^Turn slight right/i, 'انعطف يميناً بشكل طفيف'],
|
||||
[/^Turn right/i, 'اتجه يميناً'],
|
||||
|
||||
[/^Turn sharp left onto\s+/i, 'انعطف يساراً بشكل حاد إلى '],
|
||||
[/^Turn slight left onto\s+/i, 'انعطف يساراً بشكل طفيف إلى '],
|
||||
[/^Turn left onto\s+/i, 'اتجه يساراً إلى '],
|
||||
[/^Turn sharp left/i, 'انعطف يساراً بشكل حاد'],
|
||||
[/^Turn slight left/i, 'انعطف يساراً بشكل طفيف'],
|
||||
[/^Turn left/i, 'اتجه يساراً'],
|
||||
|
||||
// Keeps
|
||||
[/^Keep right toward\s+/i, 'الزم اليمين باتجاه '],
|
||||
[/^Keep right onto\s+/i, 'الزم اليمين في '],
|
||||
[/^Keep right/i, 'الزم اليمين'],
|
||||
[/^احفظ اليمين toward\s+/i, 'الزم اليمين باتجاه '],
|
||||
[/^احفظ اليمين خلال\s+/i, 'الزم اليمين عبر '],
|
||||
[/^احفظ اليمين/i, 'الزم اليمين'],
|
||||
|
||||
[/^Keep left toward\s+/i, 'الزم اليسار باتجاه '],
|
||||
[/^Keep left onto\s+/i, 'الزم اليسار في '],
|
||||
[/^Keep left/i, 'الزم اليسار'],
|
||||
[/^احفظ الشمال toward\s+/i, 'الزم اليسار باتجاه '],
|
||||
[/^احفظ الشمال خلال\s+/i, 'الزم اليسار عبر '],
|
||||
[/^احفظ الشمال/i, 'الزم اليسار'],
|
||||
|
||||
// U-Turns
|
||||
[/^Make a U-turn\s+/i, 'قم بالدوران للخلف (U-turn) عند '],
|
||||
[/^Make a U-turn/i, 'قم بالدوران للخلف'],
|
||||
[/^U-turn/i, 'دوران للخلف'],
|
||||
|
||||
// Head / Bearings
|
||||
[/^Head north onto\s+/i, 'اتجه شمالاً في '],
|
||||
[/^Head south onto\s+/i, 'اتجه جنوباً في '],
|
||||
[/^Head east onto\s+/i, 'اتجه شرقاً في '],
|
||||
[/^Head west onto\s+/i, 'اتجه غرباً في '],
|
||||
[/^Head northeast onto\s+/i, 'اتجه نحو الشمال الشرقي في '],
|
||||
[/^Head northwest onto\s+/i, 'اتجه نحو الشمال الغربي في '],
|
||||
[/^Head southeast onto\s+/i, 'اتجه نحو الجنوب الشرقي في '],
|
||||
[/^Head southwest onto\s+/i, 'اتجه نحو الجنوب الغربي في '],
|
||||
|
||||
[/^Head north/i, 'اتجه شمالاً'],
|
||||
[/^Head south/i, 'اتجه جنوباً'],
|
||||
[/^Head east/i, 'اتجه شرقاً'],
|
||||
[/^Head west/i, 'اتجه غرباً'],
|
||||
[/^Head northeast/i, 'اتجه شمال شرق'],
|
||||
[/^Head northwest/i, 'اتجه شمال غرب'],
|
||||
[/^Head southeast/i, 'اتجه جنوب شرق'],
|
||||
[/^Head southwest/i, 'اتجه جنوب غرب'],
|
||||
|
||||
// Toward / Onto / Through prepositions
|
||||
[/\btoward\b/gi, 'باتجاه'],
|
||||
[/\btowards\b/gi, 'باتجاه'],
|
||||
[/\bonto\b/gi, 'في'],
|
||||
[/\bthrough\b/gi, 'عبر'],
|
||||
|
||||
// Destinations & Finish
|
||||
[/^Arrive at destination/i, 'الوصول إلى الوجهة'],
|
||||
[/^Reached destination/i, 'تم الوصول إلى الوجهة'],
|
||||
[/^Destination/i, 'الوصول إلى الوجهة'],
|
||||
[/^النهاية/i, 'الوصول إلى الوجهة']
|
||||
];
|
||||
|
||||
for (const [regex, replacement] of phrases) {
|
||||
text = text.replace(regex, replacement);
|
||||
}
|
||||
|
||||
// Clean up excessive whitespace
|
||||
text = text.replace(/\s+/g, ' ').trim();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private estimateElevation(lat: number, lng: number): number {
|
||||
if (lng < 35.6 && lat < 32.2 && lat > 31.0) {
|
||||
return -400 + Math.abs(lng - 35.5) * 3000;
|
||||
|
||||
Reference in New Issue
Block a user