| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="BlazorAnimate" Version="3.0.0" /> | <PackageReference Include="BlazorAnimate" Version="3.0.0" /> | ||||
| <PackageReference Include="Darnton.Blazor.Leaflet" Version="0.1.3" /> | |||||
| <PackageReference Include="BlazorGeolocation" Version="0.1.1" /> | |||||
| <PackageReference Include="FisSst.BlazorMaps" Version="1.0.1" /> | |||||
| <PackageReference Include="Json.Net" Version="1.0.33" /> | |||||
| <PackageReference Include="MatBlazor" Version="2.9.0-develop-042" /> | <PackageReference Include="MatBlazor" Version="2.9.0-develop-042" /> | ||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.7" /> | <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.7" /> | ||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.7" PrivateAssets="all" /> | <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.7" PrivateAssets="all" /> |
| @inherits CaritasServiceFundVeloKeyDataPageBase | @inherits CaritasServiceFundVeloKeyDataPageBase | ||||
| @using CaritasPWA.Shared.Models; | @using CaritasPWA.Shared.Models; | ||||
| @using CaritasPWA.Shared.Services; | @using CaritasPWA.Shared.Services; | ||||
| @using System.Globalization; | @using System.Globalization; | ||||
| <label for="file"> | <label for="file"> | ||||
| <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" width="48px" height="48px" viewBox="0 0 24 24" fill="#000000"> | <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" width="48px" height="48px" viewBox="0 0 24 24" fill="#000000"> | ||||
| <g><rect fill="none" height="24" width="24" /></g> | <g><rect fill="none" height="24" width="24" /></g> | ||||
| <g><g><path d="M13,4H6v16h12V9h-5V4z M16,15h-3v4h-2v-4H8l4.01-4L16,15z" opacity=".3" /> | |||||
| <path d="M14,2H6C4.9,2,4.01,2.9,4.01,4L4,20c0,1.1,0.89,2,1.99,2H18c1.1,0,2-0.9,2-2V8L14,2z M18,20H6V4h7v5h5V20z" /> | |||||
| <polygon points="8,15 11,15 11,19 13,19 13,15 16,15 12.01,11" /> | |||||
| </g></g> | |||||
| <g> | |||||
| <g> | |||||
| <path d="M13,4H6v16h12V9h-5V4z M16,15h-3v4h-2v-4H8l4.01-4L16,15z" opacity=".3" /> | |||||
| <path d="M14,2H6C4.9,2,4.01,2.9,4.01,4L4,20c0,1.1,0.89,2,1.99,2H18c1.1,0,2-0.9,2-2V8L14,2z M18,20H6V4h7v5h5V20z" /> | |||||
| <polygon points="8,15 11,15 11,19 13,19 13,15 16,15 12.01,11" /> | |||||
| </g> | |||||
| </g> | |||||
| </svg> | </svg> | ||||
| </label> | </label> | ||||
| </MatRipple> | </MatRipple> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-1 justify-content-center" style="text-align: center"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-1 justify-content-center" style="text-align: center"> | ||||
| <MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default"> | |||||
| <MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeMapPosition"> | |||||
| <label> | <label> | ||||
| <svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 0 24 24" width="48px" fill="#000000"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 0 24 24" fill="#000000"> | |||||
| <path d="M0 0h24v24H0V0z" fill="none" /> | <path d="M0 0h24v24H0V0z" fill="none" /> | ||||
| <path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" /> | <path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" /> | ||||
| <circle cx="12" cy="12" opacity=".3" r="2" /> | <circle cx="12" cy="12" opacity=".3" r="2" /> | ||||
| <path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" /> | <path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" /> | ||||
| </svg> | |||||
| </svg> | |||||
| </label> | </label> | ||||
| </MatRipple> | |||||
| </MatRipple> | |||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-3"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-3"> | ||||
| <div class="w-100 fv-osm-tile"> | |||||
| <LeafletMap Map="PositionMap" TileLayer="OpenStreetMapsTileLayer" /> | |||||
| <div class="w-100 fv-osm-tile map-wrapper"> | |||||
| <Map @ref="mapRef" MapOptions="@mapOptions"></Map> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-8-tablet mat-layout-grid-cell-span-4-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-8-tablet mat-layout-grid-cell-span-4-desktop"> | ||||
| <div class="mat-layout-grid-inner"> | <div class="mat-layout-grid-inner"> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | ||||
| <MatStringField Class="w-100 form-check-label" Label="@getAddressLbl()" Outlined="true" type="text"></MatStringField> | |||||
| <MatStringField Class="w-100 form-check-label" Label="@getAddressLbl()" Outlined="true" Required="true" type="text" @bind-Value="@bicycleGeoPosition.Address" ></MatStringField> | |||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | ||||
| <MatStringField Class="w-100 form-check-label" Label="@getPlaceLbl()" Outlined="true" type="text"></MatStringField> | |||||
| <MatStringField Class="w-100 form-check-label" Label="@getPlaceLbl()" Outlined="true" Required="true" type="text" @bind-Value="@bicycleGeoPosition.City"></MatStringField> | |||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | ||||
| <MatStringField Class="w-100 form-check-label" Label="@i18n["Latitude"]" Outlined="true" type="text"></MatStringField> | |||||
| <MatTextField Class="w-100 form-check-label italic" Label="@i18n["Latitude"]" Outlined="true" ReadOnly="true" @bind-Value="@bicycleGeoPosition.Latitude"></MatTextField> | |||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | ||||
| <MatStringField Class="w-100 form-check-label" Label="@i18n["Longitude"]" Outlined="true" type="text"></MatStringField> | |||||
| <MatTextField Class="w-100 form-check-label italic" Label="@i18n["Longitude"]" Outlined="true" ReadOnly="true" @bind-Value="@bicycleGeoPosition.Longitude"></MatTextField> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| } | } | ||||
| protected async override void OnInitialized() { | protected async override void OnInitialized() { | ||||
| base.OnInitialized(); | |||||
| Console.WriteLine("CurrentCulture is {0}.", CultureInfo.CurrentCulture.Name); | Console.WriteLine("CurrentCulture is {0}.", CultureInfo.CurrentCulture.Name); | ||||
| Console.WriteLine("Current language is {0}.", CultureInfo.CurrentCulture.TwoLetterISOLanguageName.ToUpper()); | Console.WriteLine("Current language is {0}.", CultureInfo.CurrentCulture.TwoLetterISOLanguageName.ToUpper()); | ||||
| await GetBicycleTypes(); | await GetBicycleTypes(); | ||||
| await GetBrands(); | await GetBrands(); | ||||
| PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | ||||
| base.OnInitialized(); | |||||
| } | } | ||||
| private Brand getBrand(Brand brand) { | private Brand getBrand(Brand brand) { | ||||
| } | } | ||||
| } | } | ||||
| public void Show(MatToastType type, string title, string message, string icon = "") { | |||||
| Toaster.Add(message, type, title, icon); | |||||
| } | |||||
| //public void Show(MatToastType type, string title, string message, string icon = "") { | |||||
| // Toaster.Add(message, type, title, icon); | |||||
| //} | |||||
| //private async Task OnGatheringPicture(InputFileChangeEventArgs e) { | //private async Task OnGatheringPicture(InputFileChangeEventArgs e) { |
| using System; | |||||
| using Microsoft.AspNetCore.Components; | |||||
| using System; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Components; | |||||
| using CaritasPWA.Shared.Models.OSM; | |||||
| using Darnton.Blazor.Leaflet.LeafletMap; | |||||
| using FisSst.BlazorMaps; | |||||
| using BlazorGeolocation; | |||||
| using Microsoft.Extensions.Localization; | |||||
| using CaritasPWA.Shared.ResourceFiles; | |||||
| using CaritasPWA.Shared.Models; | |||||
| using CaritasPWA.Shared.Services; | |||||
| namespace CaritasPWA.Pages { | namespace CaritasPWA.Pages { | ||||
| public class CaritasServiceFundVeloKeyDataPageBase : ComponentBase, IAsyncDisposable { | |||||
| public partial class CaritasServiceFundVeloKeyDataPageBase : ComponentBase { | |||||
| protected Map PositionMap; | |||||
| protected TileLayer OpenStreetMapsTileLayer; | |||||
| protected MapStateViewModel MapStateViewModel; | |||||
| protected MarkerViewModel MarkerViewModel; | |||||
| 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 MatBlazor.IMatToaster Toaster { get; init; } | |||||
| [Inject] | |||||
| private IStringLocalizer<Resources> I18n { get; init; } | |||||
| private NominatimService nominatimService { get; set; } | |||||
| public CaritasServiceFundVeloKeyDataPageBase() : base() { | public CaritasServiceFundVeloKeyDataPageBase() : base() { | ||||
| var mapCentre = new LatLng(46.80121, 8.22669); // Centered on Swiss | |||||
| MapStateViewModel = new MapStateViewModel { | |||||
| MapCentreLatitude = mapCentre.Lat, | |||||
| MapCentreLongitude = mapCentre.Lng, | |||||
| Zoom = 6 | |||||
| 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 = "© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap </a>", | |||||
| MaxZoom = 18, | |||||
| TileSize = 256, | |||||
| ZoomOffset = 0, | |||||
| } | |||||
| }; | }; | ||||
| PositionMap = new Map("bicycleLocationMap", new MapOptions { | |||||
| Center = mapCentre, | |||||
| Zoom = MapStateViewModel.Zoom | |||||
| }); | |||||
| this.bicycleGeoPosition = new(); | |||||
| this.nominatimService = new NominatimService(); | |||||
| } | |||||
| OpenStreetMapsTileLayer = new TileLayer( | |||||
| "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", | |||||
| new TileLayerOptions { | |||||
| Attribution = @"Map data © <a href=""https://www.openstreetmap.org/"">OpenStreetMap</a> contributors, " + | |||||
| @"<a href=""https://creativecommons.org/licenses/by-sa/2.0/"">CC-BY-SA</a>" | |||||
| } | |||||
| ); | |||||
| protected void Show(MatBlazor.MatToastType type, string title, string message, string icon = "") { | |||||
| Toaster.Add(message, type, title, icon); | |||||
| } | |||||
| MarkerViewModel = new MarkerViewModel(); | |||||
| protected async Task AddEventsToMap() { | |||||
| await this.mapRef.OnClick(async (MouseEvent mouseEvent) => await OnMouseMapClicked(mouseEvent)); | |||||
| } | |||||
| protected async Task InitializeMapPosition() { | |||||
| createBicycleMarkerOptions(); | |||||
| await AddEventsToMap(); | |||||
| await ShowDeviceGeoLocation(); | |||||
| } | } | ||||
| protected async void GetMapState() { | |||||
| var mapCentre = await PositionMap.GetCenter(); | |||||
| MapStateViewModel.MapCentreLatitude = mapCentre.Lat; | |||||
| MapStateViewModel.MapCentreLongitude = mapCentre.Lng; | |||||
| MapStateViewModel.Zoom = await PositionMap.GetZoom(); | |||||
| MapStateViewModel.MapContainerSize = await PositionMap.GetSize(); | |||||
| MapStateViewModel.MapViewPixelBounds = await PositionMap.GetPixelBounds(); | |||||
| MapStateViewModel.MapLayerPixelOrigin = await PositionMap.GetPixelOrigin(); | |||||
| StateHasChanged(); | |||||
| 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) { | |||||
| Show(MatBlazor.MatToastType.Danger, 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); | |||||
| } | |||||
| } | } | ||||
| protected async void SetMapState() { | |||||
| var mapCentre = new LatLng(MapStateViewModel.MapCentreLatitude, MapStateViewModel.MapCentreLongitude); | |||||
| await PositionMap.SetView(mapCentre, MapStateViewModel.Zoom); | |||||
| 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 { | |||||
| Show(MatBlazor.MatToastType.Warning, I18n.GetString("Warning.Nominatim.Title"), I18n.GetString("Warning.Nominatim.Msg")); | |||||
| } | |||||
| StateHasChanged(); | |||||
| } | } | ||||
| protected async void AddMarkerAtMapCenter() { | |||||
| var mapCentre = await PositionMap.GetCenter(); | |||||
| var marker = new Marker(mapCentre, new MarkerOptions { | |||||
| Keyboard = MarkerViewModel.Keyboard, | |||||
| Title = MarkerViewModel.Title, | |||||
| Alt = MarkerViewModel.Alt, | |||||
| ZIndexOffset = MarkerViewModel.ZIndexOffset, | |||||
| Opacity = MarkerViewModel.Opacity, | |||||
| RiseOnHover = MarkerViewModel.RiseOnHover, | |||||
| RiseOffset = MarkerViewModel.RiseOffset, | |||||
| }); | |||||
| await marker.AddTo(PositionMap); | |||||
| 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); | |||||
| } | } | ||||
| public async ValueTask DisposeAsync() { | |||||
| await OpenStreetMapsTileLayer.DisposeAsync(); | |||||
| await PositionMap.DisposeAsync(); | |||||
| private String getFormattedAddressStreet(NominatimReverseAddress addressDto) { | |||||
| String street = addressDto.address.road; | |||||
| String houseNr = addressDto.address.house_number != null ? addressDto.address.house_number : ""; | |||||
| return street + (!houseNr.Equals("") ? " " + houseNr : ""); | |||||
| } | } | ||||
| private 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; | |||||
| } | |||||
| } | } | ||||
| } | } |
| using CaritasPWA.Shared; | using CaritasPWA.Shared; | ||||
| using CaritasPWA.Shared.Services; | using CaritasPWA.Shared.Services; | ||||
| using FisSst.BlazorMaps.DependencyInjection; | |||||
| using BlazorGeolocation; | |||||
| using MatBlazor; | using MatBlazor; | ||||
| using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | ||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
| using System.Net.Http; | using System.Net.Http; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace CaritasPWA { | namespace CaritasPWA { | ||||
| public class Program { | public class Program { | ||||
| public static async Task Main(string[] args) { | public static async Task Main(string[] args) { | ||||
| builder.Services.AddScoped<UserDataProvider>(); | builder.Services.AddScoped<UserDataProvider>(); | ||||
| builder.Services.AddScoped<MasterDataService>(); | builder.Services.AddScoped<MasterDataService>(); | ||||
| builder.Services.AddLocalization(); | builder.Services.AddLocalization(); | ||||
| builder.Services.AddBlazorLeafletMaps(); | |||||
| builder.Services.AddScoped<BlazorGeolocationService>(); | |||||
| builder.Services.AddMatToaster(config => { | builder.Services.AddMatToaster(config => { | ||||
| config.Position = MatToastPosition.BottomCenter; | config.Position = MatToastPosition.BottomCenter; |
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| }, | }, | ||||
| "nativeDebugging": true, | |||||
| "nativeDebugging": false, | |||||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | "applicationUrl": "https://localhost:5001;http://localhost:5000", | ||||
| "jsWebView2Debugging": false, | |||||
| "jsWebView2Debugging": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" | ||||
| } | } | ||||
| } | } |
| public string Name { get; set; } | public string Name { get; set; } | ||||
| public string RGB { get; set; } | public string RGB { get; set; } | ||||
| public ColorItem() { } | |||||
| public ColorItem() { } | |||||
| public ColorItem(int index, string name, string rgb) { | public ColorItem(int index, string name, string rgb) { | ||||
| Index = index; | Index = index; |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Threading.Tasks; | |||||
| namespace CaritasPWA.Shared.Models { | |||||
| public class BicycleGeoPosition { | |||||
| public BicycleGeoPosition() { | |||||
| Latitude = 0.0; | |||||
| Longitude = 0.0; | |||||
| Address = ""; | |||||
| City = ""; | |||||
| } | |||||
| public double Latitude { get; set; } | |||||
| public double Longitude { get; set; } | |||||
| public string Address { get; set; } | |||||
| public string City { get; set; } | |||||
| } | |||||
| } |
| using Darnton.Blazor.Leaflet.LeafletMap; | |||||
| namespace CaritasPWA.Shared.Models.OSM { | |||||
| public class MapStateViewModel { | |||||
| public double MapCentreLatitude { get; set; } | |||||
| public double MapCentreLongitude { get; set; } | |||||
| public int Zoom { get; set; } | |||||
| public Point MapContainerSize { get; set; } | |||||
| public Bounds MapViewPixelBounds { get; set; } | |||||
| public Point MapLayerPixelOrigin { get; set; } | |||||
| } | |||||
| } |
| namespace CaritasPWA.Shared.Models.OSM { | |||||
| public class MarkerViewModel { | |||||
| public bool Keyboard { get; set; } = true; | |||||
| public string Title { get; set; } | |||||
| public string Alt { get; set; } | |||||
| public int ZIndexOffset { get; set; } | |||||
| public double Opacity { get; set; } = 1.0f; | |||||
| public bool RiseOnHover { get; set; } | |||||
| public int RiseOffset { get; set; } = 250; | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Threading.Tasks; | |||||
| using Json.Net; | |||||
| namespace CaritasPWA.Shared.Models { | |||||
| public class NominatimReverseAddress { | |||||
| public string place_id; | |||||
| public string licence; | |||||
| public string osm_type; | |||||
| public string osm_id; | |||||
| public string lat; | |||||
| public string lon; | |||||
| public string display_name; | |||||
| public Address address; | |||||
| public string[] boundingbox; | |||||
| public class Address { | |||||
| public string house_number; | |||||
| public string road; | |||||
| public string town; | |||||
| public string state; | |||||
| public string postcode; | |||||
| public string country; | |||||
| public string country_code; | |||||
| } | |||||
| } | |||||
| } |
| <data name="DevelopedBy" xml:space="preserve"> | <data name="DevelopedBy" xml:space="preserve"> | ||||
| <value>Entwickelt durch</value> | <value>Entwickelt durch</value> | ||||
| </data> | </data> | ||||
| <data name="Error.GeoLocation.Msg" xml:space="preserve"> | |||||
| <value>Die Geoposition konnte nicht ermittelt werden. Fehlermeldung : {0:s}</value> | |||||
| </data> | |||||
| <data name="Error.GeoLocation.Title" xml:space="preserve"> | |||||
| <value>Error {0:d} beim Ermitteln der Geoposition.</value> | |||||
| </data> | |||||
| <data name="Error.IOException.Msg" xml:space="preserve"> | <data name="Error.IOException.Msg" xml:space="preserve"> | ||||
| <value>Die Datei konnte nicht gelesen werden.</value> | <value>Die Datei konnte nicht gelesen werden.</value> | ||||
| </data> | </data> | ||||
| <data name="Username" xml:space="preserve"> | <data name="Username" xml:space="preserve"> | ||||
| <value>Benutzername oder E-Mail</value> | <value>Benutzername oder E-Mail</value> | ||||
| </data> | </data> | ||||
| <data name="Warning.Nominatim.Msg" xml:space="preserve"> | |||||
| <value>Die Adresse konnte beim Aufrufen des Nominatim-Dienstes nicht aufgelöst werden. Bitte geben Sie die Straße und Postleitzahl/Ort manuell ein.</value> | |||||
| </data> | |||||
| <data name="Warning.Nominatim.Title" xml:space="preserve"> | |||||
| <value>Fehler im Nominatim-Dienst!</value> | |||||
| </data> | |||||
| <data name="Welcome" xml:space="preserve"> | <data name="Welcome" xml:space="preserve"> | ||||
| <value>Willkommen bei Caritas!</value> | <value>Willkommen bei Caritas!</value> | ||||
| </data> | </data> |
| <data name="DevelopedBy" xml:space="preserve"> | <data name="DevelopedBy" xml:space="preserve"> | ||||
| <value>Développé par</value> | <value>Développé par</value> | ||||
| </data> | </data> | ||||
| <data name="Error.GeoLocation.Msg" xml:space="preserve"> | |||||
| <value>La géoposition n'a pas pu être déterminée. Message d'erreur : {0:s}</value> | |||||
| </data> | |||||
| <data name="Error.GeoLocation.Title" xml:space="preserve"> | |||||
| <value>Erreur {0:d} lors de la détermination de la position géographique.</value> | |||||
| </data> | |||||
| <data name="Error.IOException.Msg" xml:space="preserve"> | <data name="Error.IOException.Msg" xml:space="preserve"> | ||||
| <value>The file could not be read.</value> | <value>The file could not be read.</value> | ||||
| </data> | </data> | ||||
| <data name="Username" xml:space="preserve"> | <data name="Username" xml:space="preserve"> | ||||
| <value>Nom d'utilisateur ou courriel</value> | <value>Nom d'utilisateur ou courriel</value> | ||||
| </data> | </data> | ||||
| <data name="Warning.Nominatim.Msg" xml:space="preserve"> | |||||
| <value>L'adresse n'a pas pu être résolue en invoquant le service Nominatim. Veuillez saisir l'adresse en indiquant la rue et le code postal/ville.</value> | |||||
| </data> | |||||
| <data name="Warning.Nominatim.Title" xml:space="preserve"> | |||||
| <value>Erreur du service Nominatim!</value> | |||||
| </data> | |||||
| <data name="Welcome" xml:space="preserve"> | <data name="Welcome" xml:space="preserve"> | ||||
| <value>Bienvenue chez Caritas!</value> | <value>Bienvenue chez Caritas!</value> | ||||
| </data> | </data> |
| <data name="DevelopedBy" xml:space="preserve"> | <data name="DevelopedBy" xml:space="preserve"> | ||||
| <value>Sviluppata da</value> | <value>Sviluppata da</value> | ||||
| </data> | </data> | ||||
| <data name="Error.GeoLocation.Msg" xml:space="preserve"> | |||||
| <value>Non è stato possibile determinare la posizione geografica. Messaggio d'errore: {0:s}</value> | |||||
| </data> | |||||
| <data name="Error.GeoLocation.Title" xml:space="preserve"> | |||||
| <value>Errore {0:d} durante la determinazione della posizione geografica.</value> | |||||
| </data> | |||||
| <data name="Error.IOException.Msg" xml:space="preserve"> | <data name="Error.IOException.Msg" xml:space="preserve"> | ||||
| <value>Il file non ha potuto essere caricato.</value> | <value>Il file non ha potuto essere caricato.</value> | ||||
| </data> | </data> | ||||
| <data name="Username" xml:space="preserve"> | <data name="Username" xml:space="preserve"> | ||||
| <value>Nome d'utente o e-mail</value> | <value>Nome d'utente o e-mail</value> | ||||
| </data> | </data> | ||||
| <data name="Warning.Nominatim.Msg" xml:space="preserve"> | |||||
| <value>L'indirizzo non può essere risolto invocando il servizio Nominatim. Si prega di digitare la via e CAP/città.</value> | |||||
| </data> | |||||
| <data name="Warning.Nominatim.Title" xml:space="preserve"> | |||||
| <value>Errore del servizio Nominatim!</value> | |||||
| </data> | |||||
| <data name="Welcome" xml:space="preserve"> | <data name="Welcome" xml:space="preserve"> | ||||
| <value>Benvenuti alla Caritas!</value> | <value>Benvenuti alla Caritas!</value> | ||||
| </data> | </data> |
| <data name="DevelopedBy" xml:space="preserve"> | <data name="DevelopedBy" xml:space="preserve"> | ||||
| <value>Developed by</value> | <value>Developed by</value> | ||||
| </data> | </data> | ||||
| <data name="Error.GeoLocation.Msg" xml:space="preserve"> | |||||
| <value>The Geo Location couldn't be get. ErrorMessage : {0:s}</value> | |||||
| </data> | |||||
| <data name="Error.GeoLocation.Title" xml:space="preserve"> | |||||
| <value>Error {0:d} trying to get Geo Location</value> | |||||
| </data> | |||||
| <data name="Error.IOException.Msg" xml:space="preserve"> | <data name="Error.IOException.Msg" xml:space="preserve"> | ||||
| <value>The file could not be read.</value> | <value>The file could not be read.</value> | ||||
| </data> | </data> | ||||
| <data name="Username" xml:space="preserve"> | <data name="Username" xml:space="preserve"> | ||||
| <value>Username or E-Mail</value> | <value>Username or E-Mail</value> | ||||
| </data> | </data> | ||||
| <data name="Warning.Nominatim.Msg" xml:space="preserve"> | |||||
| <value>The address could not be resolved invoking Nominatim service. Please type in the address street and zip/town.</value> | |||||
| </data> | |||||
| <data name="Warning.Nominatim.Title" xml:space="preserve"> | |||||
| <value>Nominatim service error!</value> | |||||
| </data> | |||||
| <data name="Welcome" xml:space="preserve"> | <data name="Welcome" xml:space="preserve"> | ||||
| <value>Welcome to Caritas!</value> | <value>Welcome to Caritas!</value> | ||||
| </data> | </data> |
| } | } | ||||
| public List<BicycleType> GetBicycleTypes() { | public List<BicycleType> GetBicycleTypes() { | ||||
| List<BicycleType> bicycleTypes = new (); | |||||
| List<BicycleType> bicycleTypes = new(); | |||||
| foreach (BicycleType bct in Defaults.BycicleTypes) { | foreach (BicycleType bct in Defaults.BycicleTypes) { | ||||
| bicycleTypes.Add(new BicycleType(bct.Id, _i18n.GetString("Bike." + bct.Type))); | bicycleTypes.Add(new BicycleType(bct.Id, _i18n.GetString("Bike." + bct.Type))); | ||||
| } | } |
| ColorItem[] result; | ColorItem[] result; | ||||
| var str = await _jsRuntime.InvokeAsync<string>("BlazorGetLocalStorage", KeyNameColors); | var str = await _jsRuntime.InvokeAsync<string>("BlazorGetLocalStorage", KeyNameColors); | ||||
| if (str != null) { | if (str != null) { | ||||
| result = System.Text.Json.JsonSerializer.Deserialize<ColorItem[]>(str) ?? Array.Empty<ColorItem>(); | |||||
| result = System.Text.Json.JsonSerializer.Deserialize<ColorItem[]>(str) ?? Array.Empty<ColorItem>(); | |||||
| } else { | } else { | ||||
| result = Array.Empty<ColorItem>(); | result = Array.Empty<ColorItem>(); | ||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Globalization; | |||||
| using System.Linq; | |||||
| using System.Net.Http; | |||||
| using System.Threading.Tasks; | |||||
| using CaritasPWA.Shared.Models; | |||||
| using Json.Net; | |||||
| namespace CaritasPWA.Shared.Services { | |||||
| public class NominatimService { | |||||
| public async Task<NominatimReverseAddress> GetAddressForCoordinates(double latitude, double longitude) { | |||||
| string lat = latitude.ToString("0.0000000000", CultureInfo.InvariantCulture); | |||||
| string lng = longitude.ToString("0.0000000000", CultureInfo.InvariantCulture); | |||||
| HttpClient httpClient = new HttpClient { | |||||
| BaseAddress = new Uri("https://nominatim.openstreetmap.org/") | |||||
| }; | |||||
| try { | |||||
| HttpResponseMessage httpResult = await httpClient.GetAsync(string.Format("reverse?format=json&lat={0}&lon={1}", lat, lng)); | |||||
| if (httpResult.StatusCode == System.Net.HttpStatusCode.OK) { | |||||
| NominatimReverseAddress addressDto = JsonNet.Deserialize<NominatimReverseAddress>(await httpResult.Content.ReadAsStringAsync()); | |||||
| return addressDto; | |||||
| } | |||||
| return null; | |||||
| } catch (Exception ex) { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| private readonly IJSRuntime _jsRuntime; | private readonly IJSRuntime _jsRuntime; | ||||
| private bool _initialized; | private bool _initialized; | ||||
| private UserData _data = new (); | |||||
| private UserData _data = new(); | |||||
| public UserData Data { | public UserData Data { | ||||
| get => _data; | get => _data; |
| @using Microsoft.JSInterop | @using Microsoft.JSInterop | ||||
| @using MatBlazor | @using MatBlazor | ||||
| @using BlazorAnimate | @using BlazorAnimate | ||||
| @using Darnton.Blazor.Leaflet.LeafletMap | |||||
| @using FisSst.BlazorMaps | |||||
| @using BlazorGeolocation | |||||
| @using CaritasPWA | @using CaritasPWA | ||||
| @using CaritasPWA.Shared | @using CaritasPWA.Shared | ||||
| @using CaritasPWA.Shared.ResourceFiles | @using CaritasPWA.Shared.ResourceFiles |
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <configuration> | <configuration> | ||||
| <packageSources> | |||||
| <add key="LocalSharedNugets" value="D:\Work\LeafletBlazor\Darnton.Blazor.Leaflet\bin\Debug" /> | |||||
| </packageSources> | |||||
| <packageSources> | |||||
| <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> | |||||
| </packageSources> | |||||
| </configuration> | </configuration> |
| } | } | ||||
| #bicycleLocationMap { | #bicycleLocationMap { | ||||
| position: relative; | |||||
| z-index: 0; | z-index: 0; | ||||
| width: 100%; | width: 100%; | ||||
| padding-top: 100%; | padding-top: 100%; | ||||
| border-radius: 20px; | border-radius: 20px; | ||||
| } | |||||
| label.italic input.mat-text-field-input { | |||||
| font-style: italic; | |||||
| } | } |
| <head> | <head> | ||||
| <title>Caritas PWA</title> | <title>Caritas PWA</title> | ||||
| <base href="/" /> | |||||
| <base href="/FundveloApp/" /> | |||||
| <meta charset="utf-8" /> | <meta charset="utf-8" /> | ||||
| <meta name="description" content="Caritas PWA, developed by INTEGRATE AG, Switzerland"> | <meta name="description" content="Caritas PWA, developed by INTEGRATE AG, Switzerland"> | ||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes" /> | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes" /> |