diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2026-03-16 13:01:36 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2026-03-16 13:01:36 +0100 |
| commit | 3ce586243a49f34b36d0fe4099bbfb2631610f11 (patch) | |
| tree | e1a654141bd8aef1852883aeef25392409c73891 /src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs | |
| parent | 99005bce74288a415ac748414e0f8b522e207c93 (diff) | |
New marquee generation logic for Xunta
Diffstat (limited to 'src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs')
| -rw-r--r-- | src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs | 99 |
1 files changed, 94 insertions, 5 deletions
diff --git a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs index 5bdb5bb..84e0d0f 100644 --- a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs @@ -1,3 +1,4 @@ +using System.Text; using Enmarcha.Sources.OpenTripPlannerGql.Queries; namespace Enmarcha.Backend.Services.Processors; @@ -20,17 +21,105 @@ public class NextStopsProcessor : IArrivalsProcessor foreach (var arrival in context.Arrivals) { if (arrival.RawOtpTrip is not ArrivalsAtStopResponse.Arrival otpArrival) continue; + if (arrival.Headsign.Marquee is not null) continue; // Filter stoptimes that are after the current stop's departure var currentStopDeparture = otpArrival.ScheduledDepartureSeconds; - arrival.NextStops = otpArrival.Trip.Stoptimes - .Where(s => s.ScheduledDeparture > currentStopDeparture) - .OrderBy(s => s.ScheduledDeparture) - .Select(s => _feedService.NormalizeStopName(feedId, s.Stop.Name)) - .ToList(); + if (feedId == "xunta") + { + arrival.NextStops = otpArrival.Trip.Stoptimes + .Where(s => s.ScheduledDeparture > currentStopDeparture) + .OrderBy(s => s.ScheduledDeparture) + .Select(s => s.Stop.Description) + .Distinct() + .ToList(); + } + else + { + arrival.NextStops = otpArrival.Trip.Stoptimes + .Where(s => s.ScheduledDeparture > currentStopDeparture) + .OrderBy(s => s.ScheduledDeparture) + .Select(s => FeedService.NormalizeStopName(feedId, s.Stop.Name)) + .ToList(); + } + + arrival.Headsign.Marquee = GenerateMarquee(feedId, arrival.NextStops); } return Task.CompletedTask; } + + private static string? GenerateMarquee(string feedId, List<string> nextStops) + { + if (nextStops.Count == 0) return null; + + if (feedId is "vitrasa" or "tranvias" or "tussa" or "ourense") + { + var streets = nextStops + .Select(FeedService.GetStreetName) + .Where(s => !string.IsNullOrWhiteSpace(s)) + .Distinct() + .ToList(); + + return string.Join(" - ", streets); + } + + if (feedId == "xunta") + { + var points = nextStops + .Select(SplitXuntaStopDescription) + .ToList(); + + List<string> seenConcellos = new(); + List<string> seenParroquias = new(); + List<string> items = []; + + foreach (var (parroquia, concello) in points) + { + // Santiago de Compostela -- Santiago de Compostela > Conxo -- Santiago de Compostela > BiduĂdo -- Ames > Calo -- Teo > Bugallido -- Ames + // Santiago de Compostela -> Conxo -> Bidueiro (Ames) -> Calo (Teo) -> Bugallido + string item = ""; + + if (!seenParroquias.Contains(parroquia)) + { + seenParroquias.Add(parroquia); + item += $"{parroquia}"; + + if (parroquia == concello) + { + seenConcellos.Add(concello); + } + + if (!seenConcellos.Contains(concello)) + { + seenConcellos.Add(concello); + item += $" ({concello})"; + } + + items.Add(item); + } + + } + + return string.Join(" > ", items); + } + + return feedId switch + { + "renfe" => string.Join(" - ", nextStops), + _ => string.Join(", ", nextStops.Take(4)) + }; + } + + private static (string parroquia, string concello) SplitXuntaStopDescription(string stopName) + { + var parts = stopName.Split(" -- ", 2); + if (parts.Length != 2) + { + return ("", ""); // TODO: Throw + } + + return (parts[0], parts[1]); + } } |
