better ui
This commit is contained in:
1 parent
e0b0ca48f2
commit
84abee712d
6 files changed
+66
-17
No files matched your search
@@ -17,9 +17,16 @@ public class ApiController: Controller
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult Roads(string city, int year=2025)
|
public ActionResult Roads(string city, string date="")
|
||||||
{
|
{
|
||||||
return Json(_dataService.GetRoads(city, year));
|
var extractDate = Util.ParseDateOnly(date);
|
||||||
|
if (!extractDate.HasValue)
|
||||||
|
{
|
||||||
|
return BadRequest($"Cannot parse provided date {date}. The date must be in the format yyyy-MM-dd.");
|
||||||
|
}
|
||||||
|
return Json(_dataService.GetRoads(city, extractDate.Value));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ using YongeStreet.Services;
|
|||||||
|
|
||||||
namespace YongeStreet.Controllers;
|
namespace YongeStreet.Controllers;
|
||||||
|
|
||||||
public record CityModel(string City, IList<CityRoadLengthStats> CityRoadLengthStats);
|
public record CityModel(string City, IList<CityRoadLengthStats> CityRoadLengthStats, DateOnly Date);
|
||||||
|
|
||||||
public record IndexModel(IList<CityOverview> Cities);
|
public record IndexModel(IList<CityOverview> Cities);
|
||||||
|
|
||||||
@@ -20,10 +20,11 @@ public class HomeController : Controller
|
|||||||
_dataService = dataService;
|
_dataService = dataService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult City(string city)
|
public IActionResult City(string city, string date)
|
||||||
{
|
{
|
||||||
var cityRoadLengthStats = _dataService.GetCityRoadLengthStats(city);
|
var cityRoadLengthStats = _dataService.GetCityRoadLengthStats(city);
|
||||||
return View(new CityModel(city, cityRoadLengthStats));
|
var parsedDate = Util.ParseDateOnly(date) ?? new DateOnly(2025, 1, 1);
|
||||||
|
return View(new CityModel(city, cityRoadLengthStats, parsedDate ));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace YongeStreet.Controllers;
|
||||||
|
|
||||||
|
public static class Util
|
||||||
|
{
|
||||||
|
public static DateOnly? ParseDateOnly(string? date)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(date))
|
||||||
|
{
|
||||||
|
return new DateOnly(2025, 1, 1);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DateOnly.ParseExact(date, "yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
catch (FormatException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ namespace YongeStreet.Services;
|
|||||||
|
|
||||||
public record Road(int RelationId, List<List<double>> Points);
|
public record Road(int RelationId, List<List<double>> Points);
|
||||||
|
|
||||||
public record CityOverview(string Name, double TotalStreetSize, IList<int> AvailableYears);
|
public record CityOverview(string Name, double TotalStreetSize, IList<DateOnly> AvailableDates);
|
||||||
|
|
||||||
public record CityRoadLengthStats(string Name, double MunicipalRoadLength, int Year);
|
public record CityRoadLengthStats(string Name, double MunicipalRoadLength, DateOnly Date);
|
||||||
|
|
||||||
public class DataService
|
public class DataService
|
||||||
{
|
{
|
||||||
@@ -20,7 +20,7 @@ public class DataService
|
|||||||
"unclassified"];
|
"unclassified"];
|
||||||
private readonly string path = "/home/didier/dev/YongeStreet/real.duckdb";
|
private readonly string path = "/home/didier/dev/YongeStreet/real.duckdb";
|
||||||
|
|
||||||
public IList<Road> GetRoads(string city, int year)
|
public IList<Road> GetRoads(string city, DateOnly extractDate)
|
||||||
{
|
{
|
||||||
using var duckDBConnection = new DuckDBConnection($"Data Source={path};ACCESS_MODE=READ_ONLY");
|
using var duckDBConnection = new DuckDBConnection($"Data Source={path};ACCESS_MODE=READ_ONLY");
|
||||||
duckDBConnection.Open();
|
duckDBConnection.Open();
|
||||||
@@ -34,7 +34,7 @@ public class DataService
|
|||||||
AND list_contains($allowed_highway, highway)
|
AND list_contains($allowed_highway, highway)
|
||||||
""";
|
""";
|
||||||
command.Parameters.Add(new DuckDBParameter("city_name", city));
|
command.Parameters.Add(new DuckDBParameter("city_name", city));
|
||||||
command.Parameters.Add(new DuckDBParameter("extract_date", new DateOnly(year, 1, 1)));
|
command.Parameters.Add(new DuckDBParameter("extract_date", extractDate));
|
||||||
command.Parameters.Add(new DuckDBParameter("allowed_highway", CITY_STREET_HIGHWAY));
|
command.Parameters.Add(new DuckDBParameter("allowed_highway", CITY_STREET_HIGHWAY));
|
||||||
using var reader = command.ExecuteReader();
|
using var reader = command.ExecuteReader();
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public class DataService
|
|||||||
command.CommandText = """
|
command.CommandText = """
|
||||||
SELECT city_name,
|
SELECT city_name,
|
||||||
SUM(length) FILTER (list_contains($allowed_highway, highway) AND extract_date = (Date '2025-01-01')) AS length,
|
SUM(length) FILTER (list_contains($allowed_highway, highway) AND extract_date = (Date '2025-01-01')) AS length,
|
||||||
LIST(DISTINCT extract('year' FROM extract_date)) AS available_years
|
LIST(DISTINCT extract_date) AS available_years
|
||||||
FROM city_road
|
FROM city_road
|
||||||
GROUP BY city_name
|
GROUP BY city_name
|
||||||
ORDER BY length desc
|
ORDER BY length desc
|
||||||
@@ -70,7 +70,7 @@ public class DataService
|
|||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
ret.Add(new CityOverview(reader.GetString(0),
|
ret.Add(new CityOverview(reader.GetString(0),
|
||||||
reader.GetDouble(1),
|
reader.GetDouble(1),
|
||||||
reader.GetFieldValue<List<int>>(2)));
|
reader.GetFieldValue<List<DateOnly>>(2)));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -83,11 +83,11 @@ public class DataService
|
|||||||
using var command = duckDBConnection.CreateCommand();
|
using var command = duckDBConnection.CreateCommand();
|
||||||
command.CommandText = """
|
command.CommandText = """
|
||||||
SELECT SUM(length) FILTER (list_contains($allowed_highway, highway)) AS length,
|
SELECT SUM(length) FILTER (list_contains($allowed_highway, highway)) AS length,
|
||||||
extract('year' FROM extract_date) AS year
|
extract_date AS date
|
||||||
FROM city_road
|
FROM city_road
|
||||||
WHERE city_name = $city_name
|
WHERE city_name = $city_name
|
||||||
GROUP BY extract_date
|
GROUP BY extract_date
|
||||||
ORDER BY year DESC
|
ORDER BY date DESC
|
||||||
""";
|
""";
|
||||||
command.Parameters.Add(new DuckDBParameter("city_name", city));
|
command.Parameters.Add(new DuckDBParameter("city_name", city));
|
||||||
command.Parameters.Add(new DuckDBParameter("allowed_highway", CITY_STREET_HIGHWAY));
|
command.Parameters.Add(new DuckDBParameter("allowed_highway", CITY_STREET_HIGHWAY));
|
||||||
@@ -98,7 +98,7 @@ public class DataService
|
|||||||
{
|
{
|
||||||
ret.Add(new CityRoadLengthStats(city,
|
ret.Add(new CityRoadLengthStats(city,
|
||||||
reader.GetInt32(0),
|
reader.GetInt32(0),
|
||||||
reader.GetInt32(1)));
|
reader.GetFieldValue<DateOnly>(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
|
@using System.Runtime.InteropServices.JavaScript
|
||||||
@model YongeStreet.Controllers.CityModel
|
@model YongeStreet.Controllers.CityModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "La Province";
|
ViewData["Title"] = "La Province";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>@Model.City - @Model.Date.ToString("yyyy-MM-dd")</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="uk-height-large uk-flex uk-flex-center uk-flex-middle uk-background-cover uk-light"
|
<div class="uk-height-large uk-flex uk-flex-center uk-flex-middle uk-background-cover uk-light"
|
||||||
style="background-color: black"
|
style="background-color: black"
|
||||||
id="leaflet-map"
|
id="leaflet-map"
|
||||||
@@ -19,10 +24,25 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach(var stats in Model.CityRoadLengthStats)
|
|
||||||
|
@foreach (var stats in Model.CityRoadLengthStats)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>@stats.Year</td>
|
<td>
|
||||||
|
@if (stats.Date != Model.Date)
|
||||||
|
{
|
||||||
|
@Html.ActionLink(stats.Date.ToString("yyyy-MM-dd"),
|
||||||
|
"City",
|
||||||
|
"Home",
|
||||||
|
new { City = Model.City, Date = stats.Date.ToString("yyyy-MM-dd"), })
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@stats.Date.ToString("yyyy-MM-dd")
|
||||||
|
}
|
||||||
|
|
||||||
|
</td>
|
||||||
<td>@((stats.MunicipalRoadLength / 1000).ToString("N"))</td>
|
<td>@((stats.MunicipalRoadLength / 1000).ToString("N"))</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>@Html.ActionLink(city.Name, "City", "Home", new {City=city.Name})</td>
|
<td>@Html.ActionLink(city.Name, "City", "Home", new {City=city.Name})</td>
|
||||||
<td>@((city.TotalStreetSize / 1000 ).ToString("N"))</td>
|
<td>@((city.TotalStreetSize / 1000 ).ToString("N"))</td>
|
||||||
<td>@string.Join(", ", city.AvailableYears)</td>
|
<td>@string.Join(", ", city.AvailableDates)</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user