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/Controllers/VigoController.cs34
-rw-r--r--src/Costasdev.Busurbano.Backend/Services/ShapeTraversalService.cs30
-rw-r--r--src/Costasdev.Busurbano.Backend/Types/ConsolidatedCirculation.cs2
3 files changed, 61 insertions, 5 deletions
diff --git a/src/Costasdev.Busurbano.Backend/Controllers/VigoController.cs b/src/Costasdev.Busurbano.Backend/Controllers/VigoController.cs
index 6423c2f..f1f5f4a 100644
--- a/src/Costasdev.Busurbano.Backend/Controllers/VigoController.cs
+++ b/src/Costasdev.Busurbano.Backend/Controllers/VigoController.cs
@@ -46,6 +46,38 @@ public class VigoController : ControllerBase
}
}
+ [HttpGet("GetShape")]
+ public async Task<IActionResult> GetShape(
+ [FromQuery] string shapeId,
+ [FromQuery] int startPointIndex = 0
+ )
+ {
+ // Include a significant number of previous points to ensure continuity and context
+ // Backtrack 50 points to cover any potential gaps or dense point sequences
+ var adjustedStartIndex = Math.Max(0, startPointIndex - 50);
+ var path = await _shapeService.GetShapePathAsync(shapeId, adjustedStartIndex);
+ if (path == null)
+ {
+ return NotFound();
+ }
+
+ // Convert to GeoJSON LineString
+ var coordinates = path.Select(p => new[] { p.Longitude, p.Latitude }).ToList();
+
+ var geoJson = new
+ {
+ type = "Feature",
+ geometry = new
+ {
+ type = "LineString",
+ coordinates = coordinates
+ },
+ properties = new { }
+ };
+
+ return Ok(geoJson);
+ }
+
[HttpGet("GetStopTimetable")]
public async Task<IActionResult> GetStopTimetable(
[FromQuery] int stopId,
@@ -278,6 +310,7 @@ public class VigoController : ControllerBase
Minutes = (int)(closestCirculation.CallingDateTime()!.Value - now).TotalMinutes,
TripId = closestCirculation.TripId,
ServiceId = closestCirculation.ServiceId,
+ ShapeId = closestCirculation.ShapeId,
},
RealTime = new RealTimeData
{
@@ -316,6 +349,7 @@ public class VigoController : ControllerBase
Minutes = (int)(sched.CallingDateTime()!.Value - now).TotalMinutes,
TripId = sched.TripId,
ServiceId = sched.ServiceId,
+ ShapeId = sched.ShapeId,
},
RealTime = null
});
diff --git a/src/Costasdev.Busurbano.Backend/Services/ShapeTraversalService.cs b/src/Costasdev.Busurbano.Backend/Services/ShapeTraversalService.cs
index bded78b..37b76ee 100644
--- a/src/Costasdev.Busurbano.Backend/Services/ShapeTraversalService.cs
+++ b/src/Costasdev.Busurbano.Backend/Services/ShapeTraversalService.cs
@@ -60,6 +60,23 @@ public class ShapeTraversalService
}
}
+ public async Task<List<Position>?> GetShapePathAsync(string shapeId, int startIndex)
+ {
+ var shape = await LoadShapeAsync(shapeId);
+ if (shape == null) return null;
+
+ var result = new List<Position>();
+ // Ensure startIndex is within bounds
+ if (startIndex < 0) startIndex = 0;
+ if (startIndex >= shape.Points.Count) return result;
+
+ for (int i = startIndex; i < shape.Points.Count; i++)
+ {
+ result.Add(TransformToLatLng(shape.Points[i]));
+ }
+ return result;
+ }
+
/// <summary>
/// Calculates the bus position by reverse-traversing the shape from the stop location
/// </summary>
@@ -78,13 +95,15 @@ public class ShapeTraversalService
int closestPointIndex = FindClosestPointIndex(shape.Points, stopLocation);
// Traverse backwards from the closest point to find the position at the given distance
- var (busPoint, forwardPoint) = TraverseBackwards(shape.Points.ToArray(), closestPointIndex, distanceMeters);
+ var (busPoint, forwardIndex) = TraverseBackwards(shape.Points.ToArray(), closestPointIndex, distanceMeters);
if (busPoint == null)
{
return null;
}
+ var forwardPoint = shape.Points[forwardIndex];
+
// Compute orientation in EPSG:25829 (meters): 0°=North, 90°=East (azimuth)
var dx = forwardPoint.X - busPoint.X; // Easting difference
var dy = forwardPoint.Y - busPoint.Y; // Northing difference
@@ -94,19 +113,20 @@ public class ShapeTraversalService
// Transform from EPSG:25829 (meters) to EPSG:4326 (lat/lng)
var pos = TransformToLatLng(busPoint);
pos.OrientationDegrees = (int)Math.Round(bearing);
+ pos.ShapeIndex = forwardIndex;
return pos;
}
/// <summary>
/// Traverses backwards along the shape from a starting point by the specified distance
/// </summary>
- private (Epsg25829 point, Epsg25829 forward) TraverseBackwards(Epsg25829[] shapePoints, int startIndex, double distanceMeters)
+ private (Epsg25829 point, int forwardIndex) TraverseBackwards(Epsg25829[] shapePoints, int startIndex, double distanceMeters)
{
if (startIndex <= 0)
{
// Already at the beginning, return the first point
var forwardIdx = Math.Min(1, shapePoints.Length - 1);
- return (shapePoints[0], shapePoints[forwardIdx]);
+ return (shapePoints[0], forwardIdx);
}
double remainingDistance = distanceMeters;
@@ -123,7 +143,7 @@ public class ShapeTraversalService
var ratio = remainingDistance / segmentDistance;
var interpolated = InterpolatePoint(shapePoints[currentIndex], shapePoints[currentIndex - 1], ratio);
// Forward direction is towards the stop (increasing index direction)
- return (interpolated, shapePoints[currentIndex]);
+ return (interpolated, currentIndex);
}
remainingDistance -= segmentDistance;
@@ -131,7 +151,7 @@ public class ShapeTraversalService
}
// We've reached the beginning of the shape
- var fwd = shapePoints[Math.Min(1, shapePoints.Length - 1)];
+ var fwd = Math.Min(1, shapePoints.Length - 1);
return (shapePoints[0], fwd);
}
diff --git a/src/Costasdev.Busurbano.Backend/Types/ConsolidatedCirculation.cs b/src/Costasdev.Busurbano.Backend/Types/ConsolidatedCirculation.cs
index a21aa60..2ac3206 100644
--- a/src/Costasdev.Busurbano.Backend/Types/ConsolidatedCirculation.cs
+++ b/src/Costasdev.Busurbano.Backend/Types/ConsolidatedCirculation.cs
@@ -23,6 +23,7 @@ public class ScheduleData
public required int Minutes { get; set; }
public required string ServiceId { get; set; }
public required string TripId { get; set; }
+ public string? ShapeId { get; set; }
}
public class Position
@@ -30,4 +31,5 @@ public class Position
public required double Latitude { get; set; }
public required double Longitude { get; set; }
public int OrientationDegrees { get; set; }
+ public int ShapeIndex { get; set; }
}