using BlazorGeolocation; using CaritasPWA.Shared.Models; using CaritasPWA.Shared.ResourceFiles; using CaritasPWA.Shared.Services; using FisSst.BlazorMaps; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using System; using System.Threading.Tasks; namespace CaritasPWA.Pages { public partial class CaritasServiceFundVeloKeyDataPageBase : ComponentBase { protected readonly LatLng center; protected Map mapRef; protected MapOptions mapOptions; protected BicycleGeoPosition bicycleGeoPosition; private Marker bicyclePositionMarker; private MarkerOptions bicycleMarkerOptions; private Marker devicePositionMarker; [Inject] private IMarkerFactory MarkerFactory { get; init; } [Inject] private IIconFactory IconFactory { get; init; } [Inject] private BlazorGeolocationService BlazorGeolocationService { get; init; } [Inject] private Toaster Toaster { get; init; } [Inject] private IStringLocalizer I18n { get; init; } private NominatimService NominatimService { get; set; } public CaritasServiceFundVeloKeyDataPageBase() : base() { this.center = new LatLng(46.80121, 8.22669); // Centered on Swiss this.mapOptions = new MapOptions() { DivId = "bicycleLocationMap", Center = center, Zoom = 6, UrlTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", SubOptions = new MapSubOptions() { Attribution = "© OpenStreetMap ", MaxZoom = 18, TileSize = 256, ZoomOffset = 0, } }; this.bicycleGeoPosition = new(); this.NominatimService = new NominatimService(); } protected async Task AddEventsToMap() { await this.mapRef.OnClick(async (MouseEvent mouseEvent) => await OnMouseMapClicked(mouseEvent)); } protected async Task InitializeMapPosition() { CreateBicycleMarkerOptions(); await AddEventsToMap(); await ShowDeviceGeoLocation(); } private async void CreateBicycleMarkerOptions() { this.bicycleMarkerOptions = new MarkerOptions() { IconRef = await this.IconFactory.Create(new IconOptions() { IconUrl = "./icons/bicycle_location.png", IconSize = new Point(48, 48), IconAnchor = new Point(24, 47), ShadowUrl = "./icons/bicycle_location_shadow.png", ShadowSize = new Point(48, 48), ShadowAnchor = new Point(16, 48), }) }; } private async Task ShowDeviceGeoLocation() { BlazorGeolocationPosition position = await this.BlazorGeolocationService.GetPositionAsync(); if (position.ErrorCode != null) { Toaster.ShowError(I18n.GetString("Error.GeoLocation.Title", position.ErrorCode), I18n.GetString("Error.GeoLocation.Msg", position.ErrorMessage)); } else { LatLng geoPosition = new((double)position.Latitude, (double)position.Longitude); if (this.devicePositionMarker != null) { await devicePositionMarker.Remove(); } this.devicePositionMarker = await this.MarkerFactory.CreateAndAddToMap(geoPosition, this.mapRef); await this.mapRef.SetZoom(16); await this.mapRef.SetView(geoPosition); } } private async Task OnMouseMapClicked(MouseEvent mouseEvent) { await AddBicycleMarkerOnClickPosition(mouseEvent); this.bicycleGeoPosition.Latitude = mouseEvent.LatLng.Lat; this.bicycleGeoPosition.Longitude = mouseEvent.LatLng.Lng; NominatimReverseAddress addressDto = await NominatimService.GetAddressForCoordinates(mouseEvent.LatLng.Lat, mouseEvent.LatLng.Lng); if (addressDto != null) { this.bicycleGeoPosition.Address = GetFormattedAddressStreet(addressDto); this.bicycleGeoPosition.City = GetFormattedAddressZipAndTown(addressDto); } else { Toaster.ShowWarning(I18n.GetString("Warning.Nominatim.Title"), I18n.GetString("Warning.Nominatim.Msg")); } StateHasChanged(); } private async Task AddBicycleMarkerOnClickPosition(MouseEvent mouseEvent) { if (this.bicyclePositionMarker != null) { await bicyclePositionMarker.Remove(); } this.bicyclePositionMarker = await this.MarkerFactory.CreateAndAddToMap(mouseEvent.LatLng, this.mapRef, this.bicycleMarkerOptions); } private static string GetFormattedAddressStreet(NominatimReverseAddress addressDto) { string street = addressDto.address.road; string houseNr = addressDto.address.house_number ?? ""; return street + (!houseNr.Equals("") ? " " + houseNr : ""); } private static string GetFormattedAddressZipAndTown(NominatimReverseAddress addressDto) { string country_code = addressDto.address.country_code; string zip = addressDto.address.postcode.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0]; string town = addressDto.address.town; return !String.IsNullOrEmpty(country_code) ? country_code.ToUpper() + "-" + zip + " " + town : zip + " " + town; } } }