using BlazorGeolocation; using cwebplusApp.Shared.Models; using cwebplusApp.Shared.ResourceFiles; using cwebplusApp.Shared.Services; using FisSst.BlazorMaps; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using System; using System.Threading.Tasks; namespace cwebplusApp.Pages { public class CaritasServiceFundVeloKeyDataPageBase : ComponentBase { protected readonly LatLng center; protected Map mapRef; protected MapOptions mapOptions; protected BicycleGeoPosition bicycleGeoPosition; private Marker bicyclePositionMarker; private MarkerOptions bicycleMarkerOptions; private NominatimReverseAddress addressDto; 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; } [Inject] private OnlineStatusProvider OnlineStatusProvider { get; init; } [Inject] private PermissionsProvider PermissionsProvider { 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 InitializeDeviceMapPosition() { CreateBicycleMarkerOptions(); await AddEventsToMap(); return await ShowDeviceGeoLocation(); } protected async Task InitializeBicycleMapPosition() { CreateBicycleMarkerOptions(); await AddEventsToMap(); await ShowBicycleGeoLocation(false); } protected async Task GetFormattedAddressZipAndTown(ReportDataProvider ReportDataProvider) { if (this.addressDto == null) { this.bicycleGeoPosition.Latitude = ReportDataProvider.GetFoundReport().GeographicInfo.Latitude; this.bicycleGeoPosition.Longitude = ReportDataProvider.GetFoundReport().GeographicInfo.Longitude; if (OnlineStatusProvider.Online && this.bicycleGeoPosition.Latitude != 0 && this.bicycleGeoPosition.Longitude != 0) { this.addressDto = await NominatimService.GetAddressForCoordinates(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude); } if (this.addressDto == null) { this.addressDto = new(); this.addressDto.address = new(); this.addressDto.address.postcode = ReportDataProvider.GetFoundReport().GeographicInfo.Postcode; this.addressDto.address.town = ReportDataProvider.GetFoundReport().GeographicInfo.Town; } } return GetFormattedAddressZipAndTown(addressDto); } protected async Task AddBicycleMarkerOnClickPosition(MouseEvent mouseEvent) { if (mouseEvent.LatLng.Lat != 0 && mouseEvent.LatLng.Lng != 0) { if (this.bicyclePositionMarker != null) { await bicyclePositionMarker.Remove(); } this.bicyclePositionMarker = await this.MarkerFactory.CreateAndAddToMap(mouseEvent.LatLng, this.mapRef, this.bicycleMarkerOptions); } } protected async Task GetDeviceGeoLocation() { Console.WriteLine("GetDeviceGeoLocation..."); LatLng geoPosition = new(46.80121, 8.22669); // Centered on Swiss if (PermissionsProvider.IsGeoLocationAllowed) { Console.WriteLine("GetDeviceGeoLocation - THEN"); BlazorGeolocationPosition position = await this.BlazorGeolocationService.GetPositionAsync(); if (position.ErrorCode != null) { Console.WriteLine("GetDeviceGeoLocation - THEN -ERROR"); Toaster.ShowError(I18n.GetString("Error.GeoLocation.Title", position.ErrorCode), I18n.GetString("Error.GeoLocation.Msg", position.ErrorMessage)); } else { geoPosition = new((double)position.Latitude, (double)position.Longitude); } } else { Console.WriteLine("GetDeviceGeoLocation - ELSE"); Toaster.ShowWarning(I18n.GetString("Warning.Permission.GeoLocation.Title"), I18n.GetString("Warning.Permission.GeoLocation.Msg")); } return geoPosition; } 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() { LatLng geoPosition = await GetDeviceGeoLocation(); if (this.devicePositionMarker != null) { await devicePositionMarker.Remove(); } if (PermissionsProvider.IsGeoLocationAllowed) { this.devicePositionMarker = await this.MarkerFactory.CreateAndAddToMap(geoPosition, this.mapRef); await this.mapRef.SetZoom(16); } else { await this.mapRef.SetZoom(6); } await this.mapRef.SetView(geoPosition); return geoPosition; } protected async Task ShowBicycleGeoLocation(bool forceRecalc) { if (this.bicycleGeoPosition.Latitude != 0 && this.bicycleGeoPosition.Longitude != 0 && !forceRecalc) { LatLng geoPosition = new(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude); await this.mapRef.SetZoom(16); await this.mapRef.SetView(geoPosition); } else if (!String.IsNullOrEmpty(this.bicycleGeoPosition.Address) && !String.IsNullOrEmpty(this.bicycleGeoPosition.Zip) && !String.IsNullOrEmpty(this.bicycleGeoPosition.City)) { LatLng geoPosition = await NominatimService.GetCoordinatesForAddress(bicycleGeoPosition.Address + ", " + bicycleGeoPosition.Zip + " " + bicycleGeoPosition.City); if (geoPosition != null) { this.bicycleGeoPosition.Latitude = geoPosition.Lat; this.bicycleGeoPosition.Longitude = geoPosition.Lng; await this.mapRef.SetZoom(16); await this.mapRef.SetView(geoPosition); MouseEvent mouseEvent = new MouseEvent(); mouseEvent.LatLng = geoPosition; await AddBicycleMarkerOnClickPosition(mouseEvent); } } } private static string GetFormattedAddressZipAndTown(NominatimReverseAddress addressDto) { string zip = SplitAndGetFirstPostcode(addressDto.address.postcode); string town = addressDto.address.city ?? addressDto.address.town ?? addressDto.address.village; return (zip + " " + town).TrimEnd(); } private static string SplitAndGetFirstPostcode(string postcode) { return String.IsNullOrEmpty(postcode) ? "" : postcode.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0]; } protected async Task OnMouseMapClicked(MouseEvent mouseEvent) { await AddBicycleMarkerOnClickPosition(mouseEvent); this.bicycleGeoPosition.Latitude = mouseEvent.LatLng.Lat; this.bicycleGeoPosition.Longitude = mouseEvent.LatLng.Lng; addressDto = await NominatimService.GetAddressForCoordinates(mouseEvent.LatLng.Lat, mouseEvent.LatLng.Lng); if (addressDto != null) { this.bicycleGeoPosition.Address = GetFormattedAddressStreet(addressDto); this.bicycleGeoPosition.City = addressDto.address.city ?? addressDto.address.town ?? addressDto.address.village; this.bicycleGeoPosition.Zip = SplitAndGetFirstPostcode(addressDto.address.postcode); this.bicycleGeoPosition.DisplayCity = GetFormattedAddressZipAndTown(addressDto); } else { Toaster.ShowWarning(I18n.GetString("Warning.Nominatim.Title"), I18n.GetString("Warning.Nominatim.Msg")); } StateHasChanged(); } private static string GetFormattedAddressStreet(NominatimReverseAddress addressDto) { string street = addressDto.address.road; string houseNr = addressDto.address.house_number ?? ""; return street + (!houseNr.Equals("") ? " " + houseNr : ""); } } }