aboutsummaryrefslogtreecommitdiff
path: root/src/Costasdev.Busurbano.Backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/Costasdev.Busurbano.Backend')
-rw-r--r--src/Costasdev.Busurbano.Backend/Configuration/AppConfiguration.cs4
-rw-r--r--src/Costasdev.Busurbano.Backend/Services/OtpService.cs62
-rw-r--r--src/Costasdev.Busurbano.Backend/Types/Otp/OtpModels.cs12
-rw-r--r--src/Costasdev.Busurbano.Backend/Types/Planner/PlannerModels.cs9
4 files changed, 80 insertions, 7 deletions
diff --git a/src/Costasdev.Busurbano.Backend/Configuration/AppConfiguration.cs b/src/Costasdev.Busurbano.Backend/Configuration/AppConfiguration.cs
index a61fdb6..3224515 100644
--- a/src/Costasdev.Busurbano.Backend/Configuration/AppConfiguration.cs
+++ b/src/Costasdev.Busurbano.Backend/Configuration/AppConfiguration.cs
@@ -13,4 +13,8 @@ public class AppConfiguration
public int MaxWalkDistance { get; set; } = 1000;
public int MaxWalkTime { get; set; } = 20;
public int NumItineraries { get; set; } = 4;
+
+ // Fare Configuration
+ public double FareCashPerBus { get; set; } = 1.63;
+ public double FareCardPerBus { get; set; } = 0.67;
}
diff --git a/src/Costasdev.Busurbano.Backend/Services/OtpService.cs b/src/Costasdev.Busurbano.Backend/Services/OtpService.cs
index 4c22ff5..77eddd3 100644
--- a/src/Costasdev.Busurbano.Backend/Services/OtpService.cs
+++ b/src/Costasdev.Busurbano.Backend/Services/OtpService.cs
@@ -141,14 +141,37 @@ public class OtpService
private RoutePlan MapToRoutePlan(OtpPlan otpPlan)
{
+ // Compute time offset: OTP's "date" field is the server time in millis
+ var otpServerTime = DateTimeOffset.FromUnixTimeMilliseconds(otpPlan.Date);
+ var now = DateTimeOffset.Now;
+ var timeOffsetSeconds = (long)(otpServerTime - now).TotalSeconds;
+
return new RoutePlan
{
- Itineraries = otpPlan.Itineraries.Select(MapItinerary).ToList()
+ Itineraries = otpPlan.Itineraries.Select(MapItinerary).ToList(),
+ TimeOffsetSeconds = timeOffsetSeconds
};
}
private Itinerary MapItinerary(OtpItinerary otpItinerary)
{
+ var legs = otpItinerary.Legs.Select(MapLeg).ToList();
+ var busLegs = legs.Where(leg => leg.Mode != null && leg.Mode.ToUpper() != "WALK");
+
+ var cashFareEuro = busLegs.Count() * _config.FareCashPerBus;
+
+ int cardTicketsRequired = 0;
+ DateTime? lastTicketPurchased = null;
+
+ foreach (var leg in busLegs)
+ {
+ if (lastTicketPurchased == null || (leg.StartTime - lastTicketPurchased.Value).TotalMinutes > 45)
+ {
+ cardTicketsRequired++;
+ lastTicketPurchased = leg.StartTime;
+ }
+ }
+
return new Itinerary
{
DurationSeconds = otpItinerary.Duration,
@@ -158,7 +181,9 @@ public class OtpService
WalkTimeSeconds = otpItinerary.WalkTime,
TransitTimeSeconds = otpItinerary.TransitTime,
WaitingTimeSeconds = otpItinerary.WaitingTime,
- Legs = otpItinerary.Legs.Select(MapLeg).ToList()
+ Legs = legs,
+ CashFareEuro = cashFareEuro,
+ CardFareEuro = cardTicketsRequired * _config.FareCardPerBus
};
}
@@ -172,12 +197,16 @@ public class OtpService
RouteLongName = otpLeg.RouteLongName,
Headsign = otpLeg.Headsign,
AgencyName = otpLeg.AgencyName,
+ RouteColor = otpLeg.RouteColor,
+ RouteTextColor = otpLeg.RouteTextColor,
From = MapPlace(otpLeg.From),
To = MapPlace(otpLeg.To),
StartTime = DateTimeOffset.FromUnixTimeMilliseconds(otpLeg.StartTime).LocalDateTime,
EndTime = DateTimeOffset.FromUnixTimeMilliseconds(otpLeg.EndTime).LocalDateTime,
+ DistanceMeters = otpLeg.Distance,
Geometry = DecodePolyline(otpLeg.LegGeometry?.Points),
- Steps = otpLeg.Steps.Select(MapStep).ToList()
+ Steps = otpLeg.Steps.Select(MapStep).ToList(),
+ IntermediateStops = otpLeg.IntermediateStops.Select(MapPlace).Where(p => p != null).Cast<PlannerPlace>().ToList()
};
}
@@ -186,14 +215,37 @@ public class OtpService
if (otpPlace == null) return null;
return new PlannerPlace
{
- Name = otpPlace.Name,
+ Name = CorrectStopName(otpPlace.Name),
Lat = otpPlace.Lat,
Lon = otpPlace.Lon,
StopId = otpPlace.StopId, // Use string directly
- StopCode = otpPlace.StopCode
+ StopCode = CorrectStopCode(otpPlace.StopCode)
};
}
+ private string CorrectStopCode(string? stopId)
+ {
+ if (string.IsNullOrEmpty(stopId)) return stopId ?? string.Empty;
+
+ var sb = new StringBuilder();
+ foreach (var c in stopId)
+ {
+ if (char.IsNumber(c))
+ {
+ sb.Append(c);
+ }
+ }
+
+ return int.Parse(sb.ToString()).ToString();
+ }
+
+ private string CorrectStopName(string? stopName)
+ {
+ if (string.IsNullOrEmpty(stopName)) return stopName ?? string.Empty;
+
+ return stopName!.Replace(" ", ", ").Replace("\"", "");
+ }
+
private Step MapStep(OtpWalkStep otpStep)
{
return new Step
diff --git a/src/Costasdev.Busurbano.Backend/Types/Otp/OtpModels.cs b/src/Costasdev.Busurbano.Backend/Types/Otp/OtpModels.cs
index 3d3de17..93c4d8b 100644
--- a/src/Costasdev.Busurbano.Backend/Types/Otp/OtpModels.cs
+++ b/src/Costasdev.Busurbano.Backend/Types/Otp/OtpModels.cs
@@ -102,6 +102,18 @@ public class OtpLeg
[JsonPropertyName("headsign")]
public string? Headsign { get; set; }
+
+ [JsonPropertyName("distance")]
+ public double Distance { get; set; }
+
+ [JsonPropertyName("routeColor")]
+ public string? RouteColor { get; set; }
+
+ [JsonPropertyName("routeTextColor")]
+ public string? RouteTextColor { get; set; }
+
+ [JsonPropertyName("intermediateStops")]
+ public List<OtpPlace> IntermediateStops { get; set; } = new();
}
public class OtpPlace
diff --git a/src/Costasdev.Busurbano.Backend/Types/Planner/PlannerModels.cs b/src/Costasdev.Busurbano.Backend/Types/Planner/PlannerModels.cs
index 30e5e2d..c31d12a 100644
--- a/src/Costasdev.Busurbano.Backend/Types/Planner/PlannerModels.cs
+++ b/src/Costasdev.Busurbano.Backend/Types/Planner/PlannerModels.cs
@@ -1,10 +1,9 @@
-using System.Text.Json.Serialization;
-
namespace Costasdev.Busurbano.Backend.Types.Planner;
public class RoutePlan
{
public List<Itinerary> Itineraries { get; set; } = new();
+ public long? TimeOffsetSeconds { get; set; }
}
public class Itinerary
@@ -17,6 +16,8 @@ public class Itinerary
public double TransitTimeSeconds { get; set; }
public double WaitingTimeSeconds { get; set; }
public List<Leg> Legs { get; set; } = new();
+ public double? CashFareEuro { get; set; }
+ public double? CardFareEuro { get; set; }
}
public class Leg
@@ -27,6 +28,8 @@ public class Leg
public string? RouteLongName { get; set; }
public string? Headsign { get; set; }
public string? AgencyName { get; set; }
+ public string? RouteColor { get; set; }
+ public string? RouteTextColor { get; set; }
public PlannerPlace? From { get; set; }
public PlannerPlace? To { get; set; }
public DateTime StartTime { get; set; }
@@ -37,6 +40,8 @@ public class Leg
public PlannerGeometry? Geometry { get; set; }
public List<Step> Steps { get; set; } = new();
+
+ public List<PlannerPlace> IntermediateStops { get; set; } = new();
}
public class PlannerPlace