|
@@ -6,7 +6,6 @@ using System.Linq.Expressions;
|
|
|
using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
using System.Windows.Input;
|
|
|
-using System.Windows.Media;
|
|
|
using Comal.Classes;
|
|
|
using Comal.Stores;
|
|
|
using InABox.Clients;
|
|
@@ -15,74 +14,11 @@ using InABox.Core;
|
|
|
using InABox.Wpf;
|
|
|
using Syncfusion.UI.Xaml.Maps;
|
|
|
using System.ComponentModel;
|
|
|
+using System.Drawing;
|
|
|
+using Point = System.Windows.Point;
|
|
|
|
|
|
namespace PRSDesktop
|
|
|
{
|
|
|
- public class MapMarker
|
|
|
- {
|
|
|
- public Guid ID { get; set; }
|
|
|
- public string Latitude { get; set; }
|
|
|
- public string Longitude { get; set; }
|
|
|
- public string Code { get; set; }
|
|
|
- public string Description { get; set; }
|
|
|
- public DateTime Updated { get; set; }
|
|
|
- public string UpdatedBy { get; set; }
|
|
|
- public string DeviceID { get; set; }
|
|
|
- public Brush Background { get; internal set; }
|
|
|
- }
|
|
|
-
|
|
|
- public class ViewModel
|
|
|
- {
|
|
|
- private readonly List<MapMarker> _markers = new();
|
|
|
-
|
|
|
- private MapMarker _selected;
|
|
|
-
|
|
|
- public ViewModel()
|
|
|
- {
|
|
|
- Markers = new ObservableCollection<MapMarker>();
|
|
|
- }
|
|
|
-
|
|
|
- public ObservableCollection<MapMarker> Markers { get; }
|
|
|
-
|
|
|
- public MapMarker Selected
|
|
|
- {
|
|
|
- get => _selected;
|
|
|
- set
|
|
|
- {
|
|
|
- _selected = value;
|
|
|
- Refresh();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void Add(MapMarker marker, bool refresh = false)
|
|
|
- {
|
|
|
- _markers.Add(marker);
|
|
|
- if (refresh)
|
|
|
- Refresh();
|
|
|
- }
|
|
|
-
|
|
|
- public void Clear()
|
|
|
- {
|
|
|
- _selected = null;
|
|
|
- _markers.Clear();
|
|
|
- Refresh();
|
|
|
- }
|
|
|
-
|
|
|
- public void Refresh()
|
|
|
- {
|
|
|
- Markers.Clear();
|
|
|
- foreach (var marker in _markers)
|
|
|
- {
|
|
|
- marker.Background = new SolidColorBrush(marker == _selected ? Colors.Yellow : Colors.Orange);
|
|
|
- if (marker != _selected)
|
|
|
- Markers.Add(marker);
|
|
|
- }
|
|
|
-
|
|
|
- if (_selected != null)
|
|
|
- Markers.Add(_selected);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
public class ImageryLayerExt : ImageryLayer
|
|
|
{
|
|
|
protected override string GetUri(int X, int Y, int Scale)
|
|
@@ -108,14 +44,12 @@ namespace PRSDesktop
|
|
|
private LiveMapsSettings _settings;
|
|
|
|
|
|
private bool bFirst = true;
|
|
|
- private readonly ViewModel viewmodel = new();
|
|
|
|
|
|
private readonly int ZOOMEDIN = 16;
|
|
|
|
|
|
public MapsPanel()
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
- DataContext = viewmodel;
|
|
|
//ausgov.Uri = "c:\\development\\maps\\MB_2011_WA.shp";
|
|
|
}
|
|
|
|
|
@@ -355,7 +289,7 @@ namespace PRSDesktop
|
|
|
|
|
|
private void LoadDayMarkers()
|
|
|
{
|
|
|
- viewmodel.Markers.Clear();
|
|
|
+ ViewModel.Markers.Clear();
|
|
|
}
|
|
|
|
|
|
private void LoadMarkers<T>(Filter<T> filter, Expression<Func<T, object>> guid, Expression<Func<T, object>> code,
|
|
@@ -363,7 +297,7 @@ namespace PRSDesktop
|
|
|
Expression<Func<T, object>> longitude, Expression<Func<T, object>> updatedby, Expression<Func<T, object>> timestamp, bool first = true)
|
|
|
where T : Entity, IRemotable, IPersistent, new()
|
|
|
{
|
|
|
- viewmodel.Clear();
|
|
|
+ ViewModel.Clear();
|
|
|
var columns = new Columns<T>(guid, code, description, latitude, longitude, timestamp, updatedby);
|
|
|
if (deviceid != null && !columns.ColumnNames().Contains(CoreUtils.GetFullPropertyName(deviceid, ".")))
|
|
|
columns.Add(deviceid);
|
|
@@ -376,7 +310,7 @@ namespace PRSDesktop
|
|
|
{
|
|
|
Dispatcher.Invoke(() =>
|
|
|
{
|
|
|
- viewmodel.Markers.Clear();
|
|
|
+ ViewModel.Markers.Clear();
|
|
|
if (error != null)
|
|
|
{
|
|
|
MessageBox.Show(error.Message);
|
|
@@ -401,11 +335,11 @@ namespace PRSDesktop
|
|
|
}
|
|
|
|
|
|
foreach (var key in values.Keys)
|
|
|
- viewmodel.Add(
|
|
|
+ ViewModel.AddMarker(
|
|
|
new MapMarker
|
|
|
{
|
|
|
ID = key,
|
|
|
- Code = values[key].Code,
|
|
|
+ Label = values[key].Code,
|
|
|
Latitude = string.Format("{0:F6}", values[key].Latitude),
|
|
|
Longitude = string.Format("{0:F6}", values[key].Longitude),
|
|
|
Description = values[key].Description,
|
|
@@ -414,7 +348,7 @@ namespace PRSDesktop
|
|
|
DeviceID = values[key].DeviceID
|
|
|
}
|
|
|
);
|
|
|
- viewmodel.Refresh();
|
|
|
+ ViewModel.Refresh();
|
|
|
}
|
|
|
|
|
|
//if (bFirst)
|
|
@@ -434,7 +368,7 @@ namespace PRSDesktop
|
|
|
var seLon = double.MinValue;
|
|
|
var seLat = double.MaxValue;
|
|
|
|
|
|
- foreach (var marker in viewmodel.Markers)
|
|
|
+ foreach (var marker in ViewModel.Markers)
|
|
|
{
|
|
|
var lat = double.Parse(marker.Latitude);
|
|
|
var lon = double.Parse(marker.Longitude);
|
|
@@ -570,12 +504,17 @@ namespace PRSDesktop
|
|
|
return;
|
|
|
LoadDeviceHistory(marker.DeviceID);
|
|
|
}
|
|
|
+
|
|
|
+ private class WayPoint
|
|
|
+ {
|
|
|
+ public PointF Location { get; set; }
|
|
|
+ public DateTime From { get; set; }
|
|
|
+ public DateTime To { get; set; }
|
|
|
+ }
|
|
|
|
|
|
private void LoadDeviceHistory(string deviceID)
|
|
|
{
|
|
|
- History.ItemsSource = null;
|
|
|
- var movements = new ObservableCollection<GPSHistory>();
|
|
|
- History.ItemsSource = movements;
|
|
|
+
|
|
|
new Client<GPSTrackerLocation>().Query(
|
|
|
new Filter<GPSTrackerLocation>(x => x.DeviceID).IsEqualTo(deviceID)
|
|
|
.And(x => x.Location.Timestamp).IsGreaterThanOrEqualTo(Date.Date.Date)
|
|
@@ -584,6 +523,8 @@ namespace PRSDesktop
|
|
|
new SortOrder<GPSTrackerLocation>(x => x.Location.Timestamp, SortDirection.Descending),
|
|
|
(table, error) =>
|
|
|
{
|
|
|
+
|
|
|
+ var movements = new ObservableCollection<GPSHistory>();
|
|
|
if (table != null)
|
|
|
{
|
|
|
var updates = new List<GPSTrackerLocation>();
|
|
@@ -638,11 +579,49 @@ namespace PRSDesktop
|
|
|
Latitude = 0.0F,
|
|
|
Longitude = 0.0F
|
|
|
};
|
|
|
- Dispatcher.Invoke(() => { movements.Add(history); });
|
|
|
+ movements.Add(history);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<WayPoint> waypoints = new List<WayPoint>();
|
|
|
+ WayPoint? previous = null;
|
|
|
+ foreach (var movement in movements.OrderBy(x=>x.Date))
|
|
|
+ {
|
|
|
+ var current = new PointF((float)movement.Longitude, (float)movement.Latitude);
|
|
|
+
|
|
|
+ if (previous == null || Location.DistanceBetween(previous.Location, current, UnitOfLength.Kilometers) >= 0.05)
|
|
|
+ {
|
|
|
+ previous = new WayPoint()
|
|
|
+ {
|
|
|
+ Location = new PointF((float)movement.Longitude, (float)movement.Latitude),
|
|
|
+ From = movement.Date,
|
|
|
+ To = movement.Date
|
|
|
+ };
|
|
|
+ waypoints.Add(previous);
|
|
|
}
|
|
|
+ else
|
|
|
+ previous.To = movement.Date;
|
|
|
}
|
|
|
+
|
|
|
+ Dispatcher.BeginInvoke(() =>
|
|
|
+ {
|
|
|
+ foreach (var waypoint in waypoints.Where(x=>x.To - x.From >= TimeSpan.FromMinutes(15)))
|
|
|
+ {
|
|
|
+ ViewModel.AddWayPoint(new MapMarker()
|
|
|
+ {
|
|
|
+ Label = $"{waypoint.From:h:mm}-{waypoint.To:h:mm}",
|
|
|
+ Latitude = string.Format("{0:F6}", waypoint.Location.Y),
|
|
|
+ Longitude = string.Format("{0:F6}", waypoint.Location.X),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ ViewModel.Refresh();
|
|
|
+ History.ItemsSource = null;
|
|
|
+ History.ItemsSource = movements;
|
|
|
+ });
|
|
|
}
|
|
|
);
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private bool Moved(List<CoreRow> rows, int row1, int row2)
|
|
@@ -716,12 +695,12 @@ namespace PRSDesktop
|
|
|
//timer.Tick += ((t,e) =>
|
|
|
//{
|
|
|
//timer.IsEnabled = false;
|
|
|
- viewmodel.Refresh();
|
|
|
+ ViewModel.Refresh();
|
|
|
|
|
|
var layer = Map.Layers[0] as ImageryLayer;
|
|
|
var nw = layer.GetLatLonFromPoint(new Point(0F, 0F));
|
|
|
var se = layer.GetLatLonFromPoint(new Point(Map.ActualWidth, Map.ActualHeight));
|
|
|
- var markers = viewmodel.Markers.Where(marker => ShowAll.IsChecked == true ? true : IsMarkerVisible(marker, nw, se))
|
|
|
+ var markers = ViewModel.Markers.Where(marker => ShowAll.IsChecked == true ? true : IsMarkerVisible(marker, nw, se))
|
|
|
.OrderBy(x => x.Description);
|
|
|
Markers.ItemsSource = markers.ToArray();
|
|
|
//});
|
|
@@ -741,6 +720,9 @@ namespace PRSDesktop
|
|
|
|
|
|
private void ZoomToMarker(MapMarker marker)
|
|
|
{
|
|
|
+ if (marker == null)
|
|
|
+ return;
|
|
|
+
|
|
|
if (double.Parse(marker.Latitude) != 0.0F && double.Parse(marker.Longitude) != 0.0F)
|
|
|
{
|
|
|
var layer = Map.Layers[0] as ImageryLayer;
|
|
@@ -752,7 +734,7 @@ namespace PRSDesktop
|
|
|
private void Markers_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
{
|
|
|
var marker = Markers.SelectedItem as MapMarker;
|
|
|
- viewmodel.Selected = Markers.SelectedItem as MapMarker;
|
|
|
+ ViewModel.Selected = Markers.SelectedItem as MapMarker;
|
|
|
|
|
|
if (marker != null)
|
|
|
{
|
|
@@ -820,7 +802,7 @@ namespace PRSDesktop
|
|
|
cur.Center = center;
|
|
|
cur.Radius = radius;
|
|
|
cur.MarkerTemplate = template;
|
|
|
- cur.Markers = viewmodel.Markers;
|
|
|
+ cur.Markers = ViewModel.Markers;
|
|
|
cur.BingMapKey = "5kn7uPPBBGKdmWYiwHJL~LjUY7IIgFzGdXpkpWT7Fsw~AmlksNuYOBHNQ3cOa61Nz2ghvK5EbrBZ3aQqvTS4OjcPxTBGNGsj2hKc058CgtgJ";
|
|
|
}
|
|
|
|
|
@@ -882,5 +864,15 @@ namespace PRSDesktop
|
|
|
public string UpdatedBy { get; }
|
|
|
public string DeviceID { get; }
|
|
|
}
|
|
|
+
|
|
|
+ private void TabView_PageChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ ViewModel.View = TabView.SelectedIndex == 0
|
|
|
+ ? MapViewType.Current
|
|
|
+ : MapViewType.History;
|
|
|
+ // ImageryLayer.MarkerTemplate = TabView.SelectedIndex == 0
|
|
|
+ // ? TryFindResource("MapMarkerTemplate") as DataTemplate
|
|
|
+ // : TryFindResource("MapWayPointTemplate") as DataTemplate;
|
|
|
+ }
|
|
|
}
|
|
|
}
|