diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-11-17 18:06:01 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-11-17 18:06:01 +0100 |
| commit | e6cff4e94e16deaebcfa986d5943caf4c69b7f6c (patch) | |
| tree | a54f4e2c260eec37b9bbb24d35903032550713ed /src/Costasdev.Busurbano.Backend | |
| parent | ef86a09ee8d8fc287b382cf9092af8726b44ceae (diff) | |
Implement showing traffic density with municipal data
Diffstat (limited to 'src/Costasdev.Busurbano.Backend')
| -rw-r--r-- | src/Costasdev.Busurbano.Backend/Controllers/TrafficDataController.cs | 109 | ||||
| -rw-r--r-- | src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj | 3 |
2 files changed, 112 insertions, 0 deletions
diff --git a/src/Costasdev.Busurbano.Backend/Controllers/TrafficDataController.cs b/src/Costasdev.Busurbano.Backend/Controllers/TrafficDataController.cs new file mode 100644 index 0000000..002d6b4 --- /dev/null +++ b/src/Costasdev.Busurbano.Backend/Controllers/TrafficDataController.cs @@ -0,0 +1,109 @@ +using System.Globalization; +using System.Text; +using System.Text.Json; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using NetTopologySuite.Features; +using NetTopologySuite.IO; + +namespace Costasdev.Busurbano.Backend.Controllers; + +[ApiController] +[Route("api")] +public class TrafficDataController : ControllerBase +{ + private readonly ILogger<TrafficDataController> _logger; + private readonly IMemoryCache _cache; + private readonly HttpClient _httpClient; + + public TrafficDataController( + ILogger<TrafficDataController> logger, + IMemoryCache cache, + HttpClient httpClient + ) + { + _logger = logger; + _cache = cache; + _httpClient = httpClient; + } + + [HttpGet("traffic")] + public async Task<IActionResult> Get() + { + var trafficData = _cache.GetOrCreate("vigo-traffic-geojson", entry => + { + var data = GetTrafficData(); + + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); + + return data.Result; + }); + + return Content(trafficData, "application/json", Encoding.UTF8); + } + + private async Task<string> GetTrafficData() + { + var resp = await _httpClient.GetAsync("https://datos.vigo.org/data/trafico/treal.geojson"); + var body = resp.Content.ReadAsStringAsync().Result; + + var reader = new GeoJsonReader(); + var featureCollection = reader.Read<FeatureCollection>(body); + + // Fitler by style=#SINDATOS; vehiculos=NULL and actualizacion NOT 2025 (or above) + + var filteredFeatures = new FeatureCollection(); + foreach (var kvp in featureCollection) + { + var newAttributes = new AttributesTable(); + + if ( + !kvp.Attributes.Exists("actualizacion") || + !kvp.Attributes.Exists("style") + ) + { + continue; + } + + var updateParsed = DateTime.TryParseExact( + kvp.Attributes["actualizacion"].ToString(), + "dd/MM/yyyy HH:mm:ss", + null, + DateTimeStyles.None, + out var updatedAt + ); + + if (!updateParsed || updatedAt < DateTime.Today) + { + continue; + } + + var style = kvp.Attributes["style"].ToString(); + + if (style == "#SINDATOS") + { + continue; + } + + var vehiculosAttribute = (kvp.Attributes["vehiculos"] ?? "0").ToString(); + + var vehiclesParsed = int.TryParse(vehiculosAttribute, out var vehicles); + if (!vehiclesParsed || vehicles <= 0) + { + continue; + } + + newAttributes.Add("updatedAt", updatedAt.ToString("O")); + newAttributes.Add("style", style); + newAttributes.Add("vehicles", vehicles); + + kvp.Attributes = newAttributes; + filteredFeatures.Add(kvp); + } + + var writer = new GeoJsonWriter(); + + return writer.Write(filteredFeatures); + } +} diff --git a/src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj b/src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj index cda9ac4..abacd68 100644 --- a/src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj +++ b/src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj @@ -15,6 +15,9 @@ <PackageReference Include="Costasdev.VigoTransitApi" Version="0.1.0" /> <PackageReference Include="Google.Protobuf" Version="3.33.1" /> <PackageReference Include="ProjNet" Version="2.1.0" /> + + <PackageReference Include="NetTopologySuite" Version="2.6.0" /> + <PackageReference Include="NetTopologySuite.IO.GeoJSON" Version="4.0.0" /> </ItemGroup> <ItemGroup> |
