aboutsummaryrefslogtreecommitdiff
path: root/src/Costasdev.Busurbano.Backend/Controllers/TrafficDataController.cs
blob: a3dc84315628e0f39ed8dc570e646efaf670e4a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.Globalization;
using System.Text;
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);
    }
}