diff --git a/YongeStreet/Controllers/HomeController.cs b/YongeStreet/Controllers/HomeController.cs index bbe4453..b6e4ea4 100644 --- a/YongeStreet/Controllers/HomeController.cs +++ b/YongeStreet/Controllers/HomeController.cs @@ -5,16 +5,20 @@ using YongeStreet.Services; namespace YongeStreet.Controllers; -public record CityModel(string City, IList CityRoadLengthStats, DateOnly Date); +public record MapLocation(double? lon, double? lat, int? zoom); + +public record CityModel( + string City, + IList CityRoadLengthStats, + DateOnly Date, + MapLocation mapLocation); public record IndexModel(List Cities); -public record TmpModel(IList Cities); - public class HomeController : Controller { - private readonly ILogger _logger; private readonly DataService _dataService; + private readonly ILogger _logger; public HomeController(ILogger logger, DataService dataService) { @@ -22,11 +26,12 @@ public class HomeController : Controller _dataService = dataService; } - public IActionResult City(string city, string date) + public IActionResult City(string city, string date, double? lon, double? lat, int? zoom) { var cityRoadLengthStats = _dataService.GetCityRoadLengthStats(city); var parsedDate = Util.ParseDateOnly(date) ?? new DateOnly(2025, 1, 1); - return View(new CityModel(city, cityRoadLengthStats, parsedDate )); + var mapLocation = new MapLocation(lon, lat, zoom); + return View(new CityModel(city, cityRoadLengthStats, parsedDate, mapLocation)); } public IActionResult Index() @@ -35,9 +40,9 @@ public class HomeController : Controller return View(new IndexModel(cities)); } - public IActionResult CityList_Partial(string? search) + public IActionResult CityList_Partial(string? search) { - var cities = _dataService.GetCityOverview(search??""); + var cities = _dataService.GetCityOverview(search ?? ""); return View(new IndexModel(cities)); } @@ -51,4 +56,4 @@ public class HomeController : Controller { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } -} +} \ No newline at end of file diff --git a/YongeStreet/Views/Home/City.cshtml b/YongeStreet/Views/Home/City.cshtml index 11b5920..06d139a 100644 --- a/YongeStreet/Views/Home/City.cshtml +++ b/YongeStreet/Views/Home/City.cshtml @@ -13,7 +13,10 @@ style="" id="leaflet-map" data-city="@Model.City" - data-date="@Model.Date.ToString("yyyy-MM-dd")"> + data-date="@Model.Date.ToString("yyyy-MM-dd")" + data-initial-zoom="@Model.mapLocation.zoom" + data-initial-lon="@Model.mapLocation.lon" + data-initial-lat="@Model.mapLocation.lat"> @@ -35,7 +38,8 @@ @Html.ActionLink(stats.Date.ToString("yyyy-MM-dd"), "City", "Home", - new { City = Model.City, Date = stats.Date.ToString("yyyy-MM-dd"), }) + new { City = Model.City, Date = stats.Date.ToString("yyyy-MM-dd"), }, + htmlAttributes: new {@class = "map-link"}) } else diff --git a/YongeStreet/Views/Shared/_Layout.cshtml b/YongeStreet/Views/Shared/_Layout.cshtml index be56d24..ecd33cb 100644 --- a/YongeStreet/Views/Shared/_Layout.cshtml +++ b/YongeStreet/Views/Shared/_Layout.cshtml @@ -22,7 +22,9 @@
diff --git a/YongeStreet/wwwroot/js/quebec-province-map.js b/YongeStreet/wwwroot/js/quebec-province-map.js index fa29de5..f977b8c 100644 --- a/YongeStreet/wwwroot/js/quebec-province-map.js +++ b/YongeStreet/wwwroot/js/quebec-province-map.js @@ -13,7 +13,28 @@ function findBaryCenter(points) { return [lat / points.length, lon / points.length] } -function getCenter(data) { +function elementSpecifyMapCenter(elm) { + return !!elm.getAttribute('data-initial-lon') && elm.getAttribute('data-initial-lat'); +} + +function getMapCenterFromElement(elm) { + const lon = parseFloat(elm.getAttribute('data-initial-lon')) + const lat = parseFloat(elm.getAttribute('data-initial-lat')) + return [lat, lon]; +} + +function elementSpecifyMapZoom(elm) { + return !!elm.getAttribute('data-initial-zoom'); +} + +function getMapZoomFromElement(elm) { + return parseFloat(elm.getAttribute('data-initial-zoom')) +} + +function getCenter(data, elm) { + if(elementSpecifyMapCenter(elm)){ + return getMapCenterFromElement(elm) + } if (!data) { return centerOfTheWorld; } @@ -49,11 +70,59 @@ function getUrl(city, date) { return `/api/roads?${new URLSearchParams(params).toString()}` } +function recenterURLPointsToMaps(url, center, zoom) { + url.searchParams.set('lat', center.lat); + url.searchParams.set('lon', center.lng); + url.searchParams.set('zoom', zoom); + return url; +} + +function recenterLinkThatPointsToMaps(elm, center, zoom) { + const href = elm.getAttribute("href"); + try { + const url = new URL(href, window.document.location.origin) + const newUrl = recenterURLPointsToMaps(url, center, zoom); + elm.setAttribute("href", newUrl.toString()); + } catch (e) { + console.error(`Could not recenter ${elm} with href ${href}.`) + } + +} + +function recenterLinksThatPointsToMaps(center, zoom) { + const elms = document.getElementsByClassName("map-link"); + for (const elm of elms) { + recenterLinkThatPointsToMaps(elm, center, zoom); + } +} + +function onMapChange(e) { + const center = e.target.getCenter(); + const zoom = e.target.getZoom(); + + recenterLinksThatPointsToMaps(center, zoom); + +} + +function hookEvents(map){ + const events = ['zoomend', 'moveend', 'load']; + events.forEach((event) => map.on(event, onMapChange)); +} + +function getZoom(elm){ + return elementSpecifyMapCenter(elm) ? getMapZoomFromElement(elm): 13; + +} + async function renderLeafletMap(city, date) { const resp = await fetch(getUrl(city, date)); const roads = await resp.json(); + const elm = document.getElementById("leaflet-map") - const map = leaflet.map("leaflet-map").setView(getCenter(roads), 13); + const map = leaflet.map(elm); + hookEvents(map) + + map.setView(getCenter(roads, elm), getZoom(elm)); leaflet .tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {maxZoom: 19})