feat(routing): smart street extraction and distinctive naming for main and alternative routes
This commit is contained in:
@@ -164,12 +164,34 @@ export class MapsService {
|
||||
const baseDuration = route.time / 1000;
|
||||
const trafficAwareDuration = baseDuration * trafficFactor;
|
||||
|
||||
// Process all paths to add metadata (Names, Tags, Elevation & Slope Warnings)
|
||||
// 1. Identify the primary route's major artery/street
|
||||
const mainInstructions = paths[0]?.instructions || [];
|
||||
const mainStreetName = this.getRouteName(mainInstructions);
|
||||
|
||||
// Process all paths to add metadata (Real Street Names, Tags, Elevation & Slope Warnings)
|
||||
const processedPaths = paths.map((p: any, index: number) => {
|
||||
const pCoords = this.decodePolyline(p.points);
|
||||
const pTrafficFactor = this.trafficGrid.getTrafficFactor(pCoords, hr, dow);
|
||||
const pDuration = Math.round((p.time / 1000) * pTrafficFactor);
|
||||
const routeName = this.getRouteName(p.instructions);
|
||||
|
||||
// For alternative routes, find the distinctive street that differentiates it from the main route
|
||||
let routeStreet = index === 0
|
||||
? mainStreetName
|
||||
: this.getRouteName(p.instructions, mainStreetName || undefined);
|
||||
|
||||
// Fallback to any valid street name if differential lookup didn't find one
|
||||
if (!routeStreet) {
|
||||
routeStreet = this.getRouteName(p.instructions);
|
||||
}
|
||||
|
||||
// Format route name with Arabic prefix
|
||||
let finalRouteName = '';
|
||||
if (routeStreet) {
|
||||
const cleanStreet = routeStreet.replace(/^عبر\s+/, '').trim();
|
||||
finalRouteName = `عبر ${cleanStreet}`;
|
||||
} else {
|
||||
finalRouteName = index === 0 ? 'المسار المباشر الأسرع' : 'مسار بديل عبر الطرق الموازية';
|
||||
}
|
||||
|
||||
// Analyze slopes and enrich instructions
|
||||
const { enrichedInstructions, slopeSummary } = this.enrichInstructionsWithSlopeAnalysis(p.instructions, pCoords);
|
||||
@@ -184,7 +206,7 @@ export class MapsService {
|
||||
}
|
||||
|
||||
return {
|
||||
routeName: routeName ? `عبر ${routeName}` : `المسار ${index + 1}`,
|
||||
routeName: finalRouteName,
|
||||
tags,
|
||||
distance: p.distance,
|
||||
duration: pDuration,
|
||||
@@ -430,18 +452,47 @@ export class MapsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the most significant street name from instructions to name the route.
|
||||
* Intelligently extracts the most descriptive, distinctive street or highway name for a route.
|
||||
*/
|
||||
private getRouteName(instructions: any[]): string | null {
|
||||
private getRouteName(instructions: any[], excludeStreet?: string): string | null {
|
||||
if (!instructions || instructions.length === 0) return null;
|
||||
|
||||
const streetDistances: Record<string, number> = {};
|
||||
|
||||
for (const inst of instructions) {
|
||||
if (inst.street_name && inst.street_name.trim() !== '') {
|
||||
streetDistances[inst.street_name] = (streetDistances[inst.street_name] || 0) + (inst.distance || 0);
|
||||
let candidate = inst.street_name?.trim();
|
||||
|
||||
// If street_name is empty, check highway ref or destination (e.g., Highway 35 / طريق جرش / طريق المطار)
|
||||
if (!candidate || candidate === '') {
|
||||
if (inst.street_destination_ref) {
|
||||
candidate = `طريق ${inst.street_destination_ref}`;
|
||||
} else if (inst.street_ref) {
|
||||
candidate = `طريق ${inst.street_ref}`;
|
||||
} else if (inst.street_destination) {
|
||||
candidate = `طريق ${inst.street_destination}`;
|
||||
}
|
||||
}
|
||||
|
||||
// If still empty, attempt to extract named street from instruction text
|
||||
if (!candidate || candidate === '') {
|
||||
const match = inst.text?.match(/(?:عبر|في|إلى|خلال|من خلال)\s+(شارع\s+[\u0621-\u064A0-9\s]+|طريق\s+[\u0621-\u064A0-9\s]+|دوار\s+[\u0621-\u064A0-9\s]+|الدوار\s+[\u0621-\u064A0-9\s]+|جسر\s+[\u0621-\u064A0-9\s]+)/i);
|
||||
if (match && match[1]) {
|
||||
candidate = match[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate && candidate !== '') {
|
||||
// Remove trailing or leading noise
|
||||
candidate = candidate.replace(/^عبر\s+/, '').trim();
|
||||
|
||||
// If we have an exclusion, only add if different
|
||||
if (!excludeStreet || candidate !== excludeStreet.replace(/^عبر\s+/, '').trim()) {
|
||||
streetDistances[candidate] = (streetDistances[candidate] || 0) + (inst.distance || 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pick candidate with longest distance
|
||||
let longestStreet: string | null = null;
|
||||
let maxDist = 0;
|
||||
|
||||
@@ -452,6 +503,11 @@ export class MapsService {
|
||||
}
|
||||
}
|
||||
|
||||
// If no non-excluded street found, fallback to any longest street
|
||||
if (!longestStreet && excludeStreet) {
|
||||
return this.getRouteName(instructions);
|
||||
}
|
||||
|
||||
return longestStreet;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user