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 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; } private NominatimReverseAddress addressDto; 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(); await ShowDeviceGeoLocation(); } protected async Task InitializeBicycleMapPosition() { CreateBicycleMarkerOptions(); await AddEventsToMap(); await ShowBicycleGeoLocation(); } protected async Task GetFormattedAddressZipAndTown(ReportDataProvider ReportDataProvider) { if (addressDto == null) { this.bicycleGeoPosition.Latitude = ReportDataProvider.GetFoundReport().GeographicInfo.Latitude; this.bicycleGeoPosition.Longitude = ReportDataProvider.GetFoundReport().GeographicInfo.Longitude; addressDto = await NominatimService.GetAddressForCoordinates(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude); if (addressDto == null) { addressDto = new(); addressDto.address = new(); addressDto.address.postcode = ReportDataProvider.GetFoundReport().GeographicInfo.Postcode; addressDto.address.town = ReportDataProvider.GetFoundReport().GeographicInfo.Town; } } return GetFormattedAddressZipAndTown(addressDto); } protected 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 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 ShowBicycleGeoLocation() { if (this.bicycleGeoPosition.Latitude != 0 && this.bicycleGeoPosition.Longitude != 0) { LatLng geoPosition = new(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude); await this.mapRef.SetZoom(16); await this.mapRef.SetView(geoPosition); } } private static string GetFormattedAddressZipAndTown(NominatimReverseAddress addressDto) { string country_code = addressDto.address.country_code; string zip = SplitAndGetFirstPostcode(addressDto.address.postcode); string town = addressDto.address.city ?? addressDto.address.town ?? addressDto.address.village; return !String.IsNullOrEmpty(country_code) ? country_code.ToUpper() + "-" + zip + " " + town : zip + " " + town; } private static string SplitAndGetFirstPostcode(string postcode) { return String.IsNullOrEmpty(postcode) ? "" : postcode.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0]; } private 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 : ""); } } }