| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- using Avalonia;
- using Comal.Classes;
- using CommunityToolkit.Mvvm.ComponentModel;
- using CommunityToolkit.Mvvm.Input;
- using InABox.Avalonia;
- using InABox.Avalonia.Components;
- using InABox.Configuration;
- using InABox.Core;
- using PRS.Avalonia.Dialogs;
- using ReactiveUI;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Threading.Tasks;
- using static PRS.Avalonia.Modules.EquipmentMapsView;
- namespace PRS.Avalonia.Modules;
- public class EquipmentMapsSettings : ILocalConfigurationSettings
- {
- public Guid[] SelectedCategories { get; set; } = [];
- }
- public partial class EquipmentMapsViewModel : ModuleViewModel
- {
- public override string Title => "Live Maps";
- [ObservableProperty]
- private string _searchText = "";
- private readonly EquipmentMapsSettings _settings;
- [ObservableProperty]
- private ObservableCollection<Marker> _jobMarkers = new();
- [ObservableProperty]
- private ObservableCollection<Marker> _equipmentMarkers = new();
-
- [ObservableProperty]
- private JobModel _jobs;
-
- [ObservableProperty]
- private EquipmentModel _equipment;
- [ObservableProperty]
- private Point _coordinates;
- [ObservableProperty]
- private int _zoomLevel;
- public EquipmentMapsViewModel()
- {
- _settings = new LocalConfiguration<EquipmentMapsSettings>().Load();
- Jobs = new JobModel(
- DataAccess,
- () => Repositories.JobFilter(),
- () => DefaultCacheFileName<JobShell>());
- Equipment = new EquipmentModel(
- DataAccess,
- () => new Filter<Equipment>().All(),
- () => DefaultCacheFileName<EquipmentShell>());
- PrimaryMenu.Add(new AvaloniaMenuItem(Images.menu, SelectFilter));
- }
- protected override async Task<TimeSpan> OnRefresh()
- {
- await Task.WhenAll(
- Jobs.RefreshAsync(false),
- Equipment.RefreshAsync(false));
- Refresh();
- return TimeSpan.Zero;
- }
- private void Refresh()
- {
- var jobs = Jobs.Items.Where(FilterJob)
- .Select(x => new EquipmentMapsView.Marker(x.JobNumber, x.Location.Latitude, x.Location.Longitude))
- .ToArray();
- var equipment = Equipment.Items.Where(FilterEquipment)
- .Select(x => new EquipmentMapsView.Marker(x.Code, x.Latitude, x.Longitude))
- .ToArray();
- CenterAndZoom(jobs.Concat(equipment).Select(x => x.Coordinates).ToArray());
- JobMarkers = new ObservableCollection<Marker>(jobs);
- EquipmentMarkers = new ObservableCollection<Marker>(equipment);
- }
- private void CenterAndZoom(Point[] points)
- {
- points = points.Where(x => x != default).ToArray();
- Point coords;
- int zoom = 15;
- if (points.Length == 0)
- {
- if(App.GPS is not null)
- {
- coords = new Point(App.GPS.Latitude, App.GPS.Longitude);
- }
- else
- {
- return;
- }
- }
- else if (points.Length == 1)
- {
- coords = new Point(points[0].Y, points[0].X);
- }
- else
- {
- var latitudes = points.Select(x => x.Y).OrderBy(x => x).ToList();
- var longitudes = points.Select(x => x.X).OrderBy(x => x).ToList();
- var firstLat = latitudes.First();
- var lastLat = latitudes.Last();
- var firstLong = longitudes.First();
- var lastLong = longitudes.Last();
- var resultLat = (firstLat + lastLat) / 2;
- var resultLong = (firstLong + lastLong) / 2;
- var firstLocation = new Location()
- { Latitude = firstLat, Longitude = firstLong };
- var lastLocation = new Location()
- { Latitude = lastLat, Longitude = lastLong };
- var distance = firstLocation.DistanceTo(lastLocation, UnitOfLength.Kilometers);
- coords = new Point(resultLat, resultLong);
- zoom = CalculateZoom(distance);
- }
-
- Coordinates = coords;
- ZoomLevel = zoom;
- }
- private static int CalculateZoom(double distance)
- {
- Dictionary<double, int> thresholds = new Dictionary<double, int>()
- {
- { 1, 17 },
- { 5, 16 },
- { 10, 15 },
- { 20, 11 },
- { 50, 10 },
- { 100, 9 },
- { 200, 8 },
- { 400, 7 },
- };
- foreach (var key in thresholds.Keys.OrderBy(x => x))
- {
- if (distance < key)
- return thresholds[key];
- }
- return 6;
- }
- private bool FilterJob(JobShell shell)
- {
- return _settings.SelectedCategories.Contains(CoreUtils.FullGuid)
- && (shell.Location.Latitude != 0.0F) && (shell.Location.Longitude != 0.0F)
- && (
- SearchText.IsNullOrWhiteSpace()
- || shell.JobNumber.Contains(SearchText, StringComparison.InvariantCultureIgnoreCase)
- || shell.Name.Contains(SearchText, StringComparison.InvariantCultureIgnoreCase));
- }
- private bool FilterEquipment(EquipmentShell shell)
- {
- return _settings.SelectedCategories.Contains(shell.GroupID)
- && (shell.Latitude != 0.0F) && (shell.Longitude != 0.0F)
- && (
- SearchText.IsNullOrWhiteSpace()
- || shell.Code.Contains(SearchText, StringComparison.InvariantCultureIgnoreCase)
- || shell.Description.Contains(SearchText, StringComparison.InvariantCultureIgnoreCase));
- }
- private async Task<bool> SelectFilter()
- {
- await Navigation.Popup<EquipmentMapsMenuViewModel>(model =>
- {
- model.SelectedItems = _settings.SelectedCategories.ToHashSet();
- model.OnChanged += (o, e) =>
- {
- _settings.SelectedCategories = model.SelectedItems.ToArray();
- new LocalConfiguration<EquipmentMapsSettings>().Save(_settings);
- Refresh();
- };
- });
- return true;
- }
- [RelayCommand]
- private void Search()
- {
- Refresh();
- }
- [RelayCommand]
- private void Reset()
- {
- CenterAndZoom(JobMarkers.Concat(EquipmentMarkers).Select(x => x.Coordinates).ToArray());
- }
- }
|