|
@@ -1,105 +1,532 @@
|
|
|
+using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.ObjectModel;
|
|
|
+using System.Drawing;
|
|
|
+using System.Linq;
|
|
|
+using System.Linq.Expressions;
|
|
|
using System.Windows;
|
|
|
-using System.Windows.Media;
|
|
|
-using InABox.WPF;
|
|
|
-using net.sf.mpxj;
|
|
|
+using System.Windows.Threading;
|
|
|
+using Comal.Classes;
|
|
|
+using InABox.Clients;
|
|
|
+using InABox.Core;
|
|
|
+using Inflector;
|
|
|
using Syncfusion.UI.Xaml.Maps;
|
|
|
+using Point = System.Windows.Point;
|
|
|
|
|
|
namespace PRSDesktop;
|
|
|
|
|
|
-public enum MapViewType
|
|
|
+public enum LiveMapView
|
|
|
{
|
|
|
- Current,
|
|
|
- History
|
|
|
+ All,
|
|
|
+ Selected
|
|
|
}
|
|
|
|
|
|
public class MapViewModel : DependencyObject
|
|
|
{
|
|
|
|
|
|
- private readonly List<MapMarker> _markers = new();
|
|
|
- private readonly List<MapMarker> _waypoints = new();
|
|
|
- private MapMarker? _selected;
|
|
|
+ static readonly DependencyProperty ViewProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(View),
|
|
|
+ typeof(LiveMapView),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(LiveMapView.All)
|
|
|
+ );
|
|
|
|
|
|
- public MapViewModel()
|
|
|
+ public LiveMapView View
|
|
|
{
|
|
|
- Markers = new ObservableCollection<MapMarker>();
|
|
|
- WayPoints = new ObservableCollection<Point>();
|
|
|
+ get => (LiveMapView)GetValue(ViewProperty);
|
|
|
+ set
|
|
|
+ {
|
|
|
+ SetValue(ViewProperty, value);
|
|
|
+ Refresh();
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ static readonly DependencyProperty StyleProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(Style),
|
|
|
+ typeof(LiveMapStyle),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(LiveMapStyle.OSM)
|
|
|
+ );
|
|
|
|
|
|
- public ObservableCollection<MapMarker> Markers { get; }
|
|
|
- public ObservableCollection<Point> WayPoints { get; }
|
|
|
+ public LiveMapStyle Style
|
|
|
+ {
|
|
|
+ get => (LiveMapStyle)GetValue(StyleProperty);
|
|
|
+ set => SetValue(StyleProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- static readonly DependencyProperty ViewProperty =
|
|
|
+ static readonly DependencyProperty ApiKeyProperty =
|
|
|
DependencyProperty.Register(
|
|
|
- nameof(View),
|
|
|
- typeof(MapViewType),
|
|
|
- typeof(MapViewModel));
|
|
|
+ nameof(ApiKey),
|
|
|
+ typeof(string),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata("")
|
|
|
+ );
|
|
|
+
|
|
|
+ public string ApiKey
|
|
|
+ {
|
|
|
+ get => (string)GetValue(ApiKeyProperty);
|
|
|
+ set => SetValue(ApiKeyProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ static readonly DependencyProperty LayersProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(Layers),
|
|
|
+ typeof(ObservableCollection<ImageryLayer>),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(new ObservableCollection<ImageryLayer>())
|
|
|
+ );
|
|
|
|
|
|
- public MapViewType View
|
|
|
+ public ObservableCollection<ImageryLayer> Layers => (ObservableCollection<ImageryLayer>)GetValue(LayersProperty);
|
|
|
+
|
|
|
+ static readonly DependencyProperty EntityTypesProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EntityTypes),
|
|
|
+ typeof(Dictionary<Type, String>),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(new Dictionary<Type, String>())
|
|
|
+ );
|
|
|
+
|
|
|
+ public Dictionary<Type, String> EntityTypes => (Dictionary<Type, String>)GetValue(EntityTypesProperty);
|
|
|
+
|
|
|
+ static readonly DependencyProperty EntityTypeProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EntityType),
|
|
|
+ typeof(Type),
|
|
|
+ typeof(MapViewModel)
|
|
|
+ );
|
|
|
+
|
|
|
+ public Type? EntityType
|
|
|
{
|
|
|
- get => (MapViewType)GetValue(ViewProperty);
|
|
|
+ get => (Type) GetValue(EntityTypeProperty);
|
|
|
set
|
|
|
{
|
|
|
- SetValue(ViewProperty, value);
|
|
|
- Refresh();
|
|
|
+ SetValue(EntityTypesProperty, value);
|
|
|
+ ResetGroups();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ static readonly DependencyProperty EntityGroupsProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EntityGroups),
|
|
|
+ typeof(Dictionary<Guid, String>),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(new Dictionary<Guid, String>())
|
|
|
+ );
|
|
|
+
|
|
|
+ public Dictionary<Guid, String> EntityGroups => (Dictionary<Guid, String>)GetValue(EntityGroupsProperty);
|
|
|
|
|
|
- public MapMarker Selected
|
|
|
+ static readonly DependencyProperty EntityGroupProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EntityGroup),
|
|
|
+ typeof(Guid),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(Guid.Empty)
|
|
|
+ );
|
|
|
+
|
|
|
+ public Guid EntityGroup
|
|
|
{
|
|
|
- get => _selected;
|
|
|
+ get => (Guid)GetValue(EntityGroupProperty);
|
|
|
set
|
|
|
{
|
|
|
- _selected = value;
|
|
|
+ SetValue(EntityGroupProperty,value);
|
|
|
Refresh();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public void AddWayPoint(MapMarker waypoint)
|
|
|
+
|
|
|
+ //private readonly List<MapMarker> _markers = new();
|
|
|
+ //private readonly List<MapMarker> _waypoints = new();
|
|
|
+ //private MapMarker? _selected;
|
|
|
+
|
|
|
+
|
|
|
+ static readonly DependencyProperty MarkersProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(Markers),
|
|
|
+ typeof(ObservableCollection<MapMarker>),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(new ObservableCollection<MapMarker>())
|
|
|
+ );
|
|
|
+
|
|
|
+ public ObservableCollection<MapMarker> Markers => (ObservableCollection<MapMarker>)GetValue(MarkersProperty);
|
|
|
+
|
|
|
+
|
|
|
+ static readonly DependencyProperty SelectedMarkerProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(SelectedMarker),
|
|
|
+ typeof(MapMarker),
|
|
|
+ typeof(MapViewModel)
|
|
|
+ );
|
|
|
+
|
|
|
+ public MapMarker? SelectedMarker
|
|
|
{
|
|
|
- _waypoints.Add(waypoint);
|
|
|
+ get => GetValue(SelectedMarkerProperty) as MapMarker;
|
|
|
+ set => SetValue(SelectedMarkerProperty, value);
|
|
|
}
|
|
|
|
|
|
- public void AddMarker(MapMarker marker, bool refresh = false)
|
|
|
+ static readonly DependencyProperty WayPointsProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(WayPoints),
|
|
|
+ typeof(ObservableCollection<PointF>),
|
|
|
+ typeof(MapViewModel),
|
|
|
+ new PropertyMetadata(new ObservableCollection<PointF>())
|
|
|
+ );
|
|
|
+
|
|
|
+ public ObservableCollection<PointF> WayPoints => (ObservableCollection<PointF>)GetValue(WayPointsProperty);
|
|
|
+
|
|
|
+ private LiveMapsSettings? _settings;
|
|
|
+
|
|
|
+ public void Setup(LiveMapsSettings settings)
|
|
|
{
|
|
|
- _markers.Add(marker);
|
|
|
- if (refresh)
|
|
|
- Refresh();
|
|
|
- }
|
|
|
+ _settings = settings;
|
|
|
+
|
|
|
+ LoadEntityTypes();
|
|
|
+
|
|
|
+ EntityType = !String.IsNullOrWhiteSpace(_settings.EntityType)
|
|
|
+ ? EntityTypes.Any(x => String.Equals(x.Key.EntityName(), _settings.EntityType))
|
|
|
+ ? Type.GetType(_settings.EntityType)
|
|
|
+ : null
|
|
|
+ : null;
|
|
|
+
|
|
|
+ EntityGroup = EntityGroups.Any(x => String.Equals(x.Key, _settings.EntityGroup))
|
|
|
+ ? _settings.EntityGroup
|
|
|
+ : Guid.Empty;
|
|
|
+
|
|
|
+ Style = _settings.MapStyle;
|
|
|
+
|
|
|
+ ApiKey = _settings.ApiKey;
|
|
|
|
|
|
- public void Clear()
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadEntityTypes()
|
|
|
{
|
|
|
- _selected = null;
|
|
|
- _markers.Clear();
|
|
|
- _waypoints.Clear();
|
|
|
- Refresh();
|
|
|
+
|
|
|
+ if (ClientFactory.IsSupported<Equipment>())
|
|
|
+ EntityTypes[typeof(Equipment)] = typeof(Equipment).GetCaption().Pluralize();
|
|
|
+
|
|
|
+ if (ClientFactory.IsSupported<Job>())
|
|
|
+ EntityTypes[typeof(Job)] = typeof(Job).GetCaption().Pluralize();
|
|
|
+
|
|
|
+ if (ClientFactory.IsSupported<TimeSheet>())
|
|
|
+ EntityTypes[typeof(TimeSheet)] = typeof(TimeSheet).GetCaption().Pluralize();
|
|
|
+
|
|
|
+ if (ClientFactory.IsSupported<GPSTracker>())
|
|
|
+ EntityTypes[typeof(GPSTracker)] = typeof(GPSTracker).GetCaption().Pluralize();
|
|
|
}
|
|
|
|
|
|
+ private void ResetGroups()
|
|
|
+ {
|
|
|
+ EntityGroups.Clear();
|
|
|
+
|
|
|
+ if (Type.Equals(EntityType,typeof(Equipment)))
|
|
|
+ LoadGroups<EquipmentGroup>("All Equipment", x => x.Description);
|
|
|
+
|
|
|
+ else if (Type.Equals(EntityType,typeof(Job)))
|
|
|
+ LoadGroups<JobStatus>("All Jobs", x => x.Description);
|
|
|
+
|
|
|
+ else if (Type.Equals(EntityType,typeof(GPSTracker)))
|
|
|
+ LoadGroups<GPSTrackerType>("All Trackers", x => x.Description);
|
|
|
+
|
|
|
+ else if (Type.Equals(EntityType,typeof(TimeSheet)))
|
|
|
+ {
|
|
|
+ EntityGroups[Guid.Empty] = "Open TimeSheets";
|
|
|
+ EntityGroups[Guid.NewGuid()] = "TimeSheet Starts";
|
|
|
+ EntityGroups[CoreUtils.FullGuid] = "TimeSheet Finishes";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadGroups<TGroup>(string all, Expression<Func<TGroup, string>> description)
|
|
|
+ where TGroup : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ EntityGroups.Add(Guid.Empty, all);
|
|
|
+ var _groups = new Client<TGroup>().Query(
|
|
|
+ LookupFactory.DefineFilter<TGroup>(),
|
|
|
+ LookupFactory.DefineColumns<TGroup>(),
|
|
|
+ LookupFactory.DefineSort<TGroup>()
|
|
|
+ );
|
|
|
+ foreach (var _row in _groups.Rows)
|
|
|
+ EntityGroups[_row.Get<TGroup, Guid>(x => x.ID)] = _row.Get(description);
|
|
|
+ }
|
|
|
+
|
|
|
public void Refresh()
|
|
|
{
|
|
|
Markers.Clear();
|
|
|
WayPoints.Clear();
|
|
|
- if (View == MapViewType.Current)
|
|
|
- {
|
|
|
- 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);
|
|
|
- }
|
|
|
- else if (_selected != null)
|
|
|
+ if (View == LiveMapView.All)
|
|
|
+ LoadMarkers();
|
|
|
+ else if (SelectedMarker != null)
|
|
|
{
|
|
|
+ LoadWayPoints();
|
|
|
foreach (var waypoint in _waypoints)
|
|
|
{
|
|
|
Markers.Add(waypoint);
|
|
|
WayPoints.Add(new Point(double.Parse(waypoint.Longitude), double.Parse(waypoint.Latitude)));
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public void LoadMarkers()
|
|
|
+ {
|
|
|
+ if (EntityType != null)
|
|
|
+ {
|
|
|
+ if (EntityType.Equals("Equipment"))
|
|
|
+ {
|
|
|
+ var filter = new Filter<Equipment>(x => x.TrackerLink.Location.Timestamp).IsNotEqualTo(DateTime.MinValue);
|
|
|
+ if (!Security.IsAllowed<CanViewPrivateEquipment>())
|
|
|
+ filter = filter.And(x => x.Private).IsEqualTo(false);
|
|
|
+ if (EntityGroup != Guid.Empty)
|
|
|
+ filter = filter.And(x => x.GroupLink.ID).IsEqualTo(EntityGroup);
|
|
|
+
|
|
|
+ LoadMarkers(
|
|
|
+ filter,
|
|
|
+ x => x.ID,
|
|
|
+ x => x.Code,
|
|
|
+ x => x.Description,
|
|
|
+ x => x.TrackerLink.DeviceID,
|
|
|
+ x => x.TrackerLink.Location.Latitude,
|
|
|
+ x => x.TrackerLink.Location.Longitude,
|
|
|
+ x => x.TrackerLink.Description,
|
|
|
+ x => x.TrackerLink.Location.Timestamp
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (EntityType.Equals("Jobs"))
|
|
|
+ {
|
|
|
+ var filter = new Filter<Job>(x => x.SiteAddress.Location.Timestamp).IsNotEqualTo(DateTime.MinValue);
|
|
|
+ if (EntityGroup != Guid.Empty)
|
|
|
+ filter = filter.And(x => x.JobStatus.ID).IsEqualTo(EntityGroup);
|
|
|
+
|
|
|
+ LoadMarkers(
|
|
|
+ filter,
|
|
|
+ x => x.ID,
|
|
|
+ x => x.JobNumber,
|
|
|
+ x => x.Name,
|
|
|
+ null,
|
|
|
+ x => x.SiteAddress.Location.Latitude,
|
|
|
+ x => x.SiteAddress.Location.Longitude,
|
|
|
+ x => x.LastUpdateBy,
|
|
|
+ x => x.SiteAddress.Location.Timestamp
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ else if (EntityType.Equals("TimeSheets"))
|
|
|
+ {
|
|
|
+ if (EntityGroup == Guid.Empty) // Starts
|
|
|
+ LoadMarkers(
|
|
|
+ new Filter<TimeSheet>(x => x.Date).IsEqualTo(DateTime.Today).And(x => x.StartLocation.Timestamp)
|
|
|
+ .IsNotEqualTo(new TimeSpan(0)),
|
|
|
+ x => x.EmployeeLink.ID,
|
|
|
+ x => x.EmployeeLink.Code,
|
|
|
+ x => x.EmployeeLink.Name,
|
|
|
+ null,
|
|
|
+ x => x.StartLocation.Latitude,
|
|
|
+ x => x.StartLocation.Longitude,
|
|
|
+ x => x.SoftwareVersion,
|
|
|
+ x => x.StartLocation.Timestamp
|
|
|
+ );
|
|
|
+ else if (EntityGroup == CoreUtils.FullGuid) // Finishes
|
|
|
+ LoadMarkers(
|
|
|
+ new Filter<TimeSheet>(x => x.Date).IsEqualTo(DateTime.Today).And(x => x.Finish).IsNotEqualTo(new TimeSpan(0))
|
|
|
+ .And(x => x.FinishLocation.Timestamp).IsNotEqualTo(new TimeSpan(0)),
|
|
|
+ x => x.EmployeeLink.ID,
|
|
|
+ x => x.EmployeeLink.Code,
|
|
|
+ x => x.EmployeeLink.Name,
|
|
|
+ null,
|
|
|
+ x => x.FinishLocation.Latitude,
|
|
|
+ x => x.FinishLocation.Longitude,
|
|
|
+ x => x.SoftwareVersion,
|
|
|
+ x => x.FinishLocation.Timestamp
|
|
|
+ );
|
|
|
+ else // Open
|
|
|
+ LoadMarkers(
|
|
|
+ new Filter<TimeSheet>(x => x.Date).IsEqualTo(DateTime.Today).And(x => x.Finish).IsEqualTo(new TimeSpan(0))
|
|
|
+ .And(x => x.StartLocation.Timestamp).IsNotEqualTo(new TimeSpan(0)),
|
|
|
+ x => x.EmployeeLink.ID,
|
|
|
+ x => x.EmployeeLink.Code,
|
|
|
+ x => x.EmployeeLink.Name,
|
|
|
+ null,
|
|
|
+ x => x.StartLocation.Latitude,
|
|
|
+ x => x.StartLocation.Longitude,
|
|
|
+ x => x.SoftwareVersion,
|
|
|
+ x => x.StartLocation.Timestamp
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
+ else if (EntityType.Equals("Trackers"))
|
|
|
+ {
|
|
|
+ var filter = new Filter<GPSTracker>(x => x.Location.Timestamp).IsNotEqualTo(DateTime.MinValue);
|
|
|
+ if (EntityGroup != Guid.Empty)
|
|
|
+ filter = filter.And(x => x.Type.ID).IsEqualTo(EntityGroup);
|
|
|
|
|
|
+ LoadMarkers(
|
|
|
+ filter,
|
|
|
+ x => x.ID,
|
|
|
+ x => x.DeviceID,
|
|
|
+ x => x.Description,
|
|
|
+ x => x.DeviceID,
|
|
|
+ x => x.Location.Latitude,
|
|
|
+ x => x.Location.Longitude,
|
|
|
+ x => x.LastUpdateBy,
|
|
|
+ x => x.Location.Timestamp
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class DbMarker
|
|
|
+ {
|
|
|
+ public DbMarker(string code, string description, DateTime timestamp, double latitude, double longitude, string updatedby, string deviceid)
|
|
|
+ {
|
|
|
+ Code = code;
|
|
|
+ Description = description;
|
|
|
+ TimeStamp = timestamp;
|
|
|
+ Latitude = latitude;
|
|
|
+ Longitude = longitude;
|
|
|
+ UpdatedBy = updatedby;
|
|
|
+ DeviceID = deviceid;
|
|
|
+ }
|
|
|
+
|
|
|
+ public string Code { get; }
|
|
|
+ public string Description { get; }
|
|
|
+ public DateTime TimeStamp { get; }
|
|
|
+ public double Latitude { get; }
|
|
|
+ public double Longitude { get; }
|
|
|
+ public string UpdatedBy { get; }
|
|
|
+ public string DeviceID { get; }
|
|
|
}
|
|
|
+
|
|
|
+ private void LoadMarkers<T>(Filter<T> filter, Expression<Func<T, Guid>> guid, Expression<Func<T, string>>? code,
|
|
|
+ Expression<Func<T, string>> description, Expression<Func<T, string>>? deviceid, Expression<Func<T, double>> latitude,
|
|
|
+ Expression<Func<T, double>> longitude, Expression<Func<T, string>> updatedby, Expression<Func<T, DateTime>> timestamp, bool first = true)
|
|
|
+ where T : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ var _columns = new Columns<T>(x=>x.ID)
|
|
|
+ .Add(guid)
|
|
|
+ .Add(description)
|
|
|
+ .Add(latitude)
|
|
|
+ .Add(longitude)
|
|
|
+ .Add(timestamp)
|
|
|
+ .Add(updatedby);
|
|
|
+
|
|
|
+ if (code != null)
|
|
|
+ _columns.Add(code);
|
|
|
+
|
|
|
+ if (deviceid != null && !_columns.ColumnNames().Contains(CoreUtils.GetFullPropertyName(deviceid, ".")))
|
|
|
+ _columns.Add(deviceid);
|
|
|
+
|
|
|
+
|
|
|
+ new Client<T>().Query(
|
|
|
+ filter,
|
|
|
+ _columns,
|
|
|
+ null,
|
|
|
+ (table, error) =>
|
|
|
+ {
|
|
|
+ Dispatcher.Invoke(() =>
|
|
|
+ {
|
|
|
+ if (error != null)
|
|
|
+ {
|
|
|
+ MessageBox.Show(error.Message);
|
|
|
+ }
|
|
|
+ else if (table != null)
|
|
|
+ {
|
|
|
+ var _values = new Dictionary<Guid, DbMarker>();
|
|
|
+
|
|
|
+ var _groups = table.Rows
|
|
|
+ .OrderBy(x=>x.Get(code ?? description))
|
|
|
+ .ThenBy(x=>x.Get(timestamp))
|
|
|
+ .Select(x => x.ToObject<T>())
|
|
|
+ .GroupBy(x => x.ID);
|
|
|
+
|
|
|
+ foreach (var _group in _groups)
|
|
|
+ {
|
|
|
+ var last = _group.OrderBy(timefunc).LastOrDefault();
|
|
|
+ if (last != null)
|
|
|
+ Markers.Add(
|
|
|
+ new MapMarker
|
|
|
+ {
|
|
|
+ ID = last.ID,
|
|
|
+ Label = last.,
|
|
|
+ Latitude = string.Format("{0:F6}", _values[key].Latitude),
|
|
|
+ Longitude = string.Format("{0:F6}", _values[key].Longitude),
|
|
|
+ Description = _values[key].Description,
|
|
|
+ Updated = _values[key].TimeStamp,
|
|
|
+ UpdatedBy = _values[key].UpdatedBy,
|
|
|
+ DeviceID = _values[key].DeviceID
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var _row in table.Rows)
|
|
|
+ {
|
|
|
+ var _id = _row.Get(guid);
|
|
|
+ var _time = _row.Get(timestamp);
|
|
|
+ if (!_values.ContainsKey(_id) || (first ? _values[_id].TimeStamp < _time : _values[_id].TimeStamp > _time))
|
|
|
+ _values[_id] = new DbMarker(
|
|
|
+ code != null ? _row.Get(code) : "",
|
|
|
+ _row.Get(description),
|
|
|
+ _time,
|
|
|
+ _row.Get(latitude),
|
|
|
+ _row.Get(longitude),
|
|
|
+ _row.Get(updatedby),
|
|
|
+ deviceid != null ? _row.Get(deviceid) : ""
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var key in _values.Keys)
|
|
|
+ Markers.Add(
|
|
|
+ new MapMarker
|
|
|
+ {
|
|
|
+ ID = key,
|
|
|
+ Label = _values[key].Code,
|
|
|
+ Latitude = string.Format("{0:F6}", _values[key].Latitude),
|
|
|
+ Longitude = string.Format("{0:F6}", _values[key].Longitude),
|
|
|
+ Description = _values[key].Description,
|
|
|
+ Updated = _values[key].TimeStamp,
|
|
|
+ UpdatedBy = _values[key].UpdatedBy,
|
|
|
+ DeviceID = _values[key].DeviceID
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ ResetZoom();
|
|
|
+
|
|
|
+ LoadMarkerList();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ResetZoom()
|
|
|
+ {
|
|
|
+ var nwLon = double.MaxValue;
|
|
|
+ var nwLat = double.MinValue;
|
|
|
+ var seLon = double.MinValue;
|
|
|
+ var seLat = double.MaxValue;
|
|
|
+
|
|
|
+ foreach (var marker in _markers)
|
|
|
+ {
|
|
|
+ var lat = double.Parse(marker.Latitude);
|
|
|
+ var lon = double.Parse(marker.Longitude);
|
|
|
+ if (lat != 0.0F && lon != 0.00)
|
|
|
+ {
|
|
|
+ nwLat = lat > nwLat ? lat : nwLat;
|
|
|
+ seLat = lat < seLat ? lat : seLat;
|
|
|
+ nwLon = lon < nwLon ? lon : nwLon;
|
|
|
+ seLon = lon > seLon ? lon : seLon;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ var cLat = (nwLat + seLat) / 2.0F;
|
|
|
+ var cLon = (nwLon + seLon) / 2.0F;
|
|
|
+ Center = new Point(cLat, cLon);
|
|
|
+ var nw = new Location { Latitude = nwLat, Longitude = nwLon };
|
|
|
+ var c = new Location { Latitude = cLat, Longitude = cLon };
|
|
|
+ Radius = c.DistanceTo(nw, UnitOfLength.Kilometers) / 2.0F;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double Radius { get; set; }
|
|
|
+ public Point Center { get; set; }
|
|
|
+
|
|
|
}
|