-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMapViewModelBase.cs
More file actions
134 lines (105 loc) · 3.9 KB
/
Copy pathMapViewModelBase.cs
File metadata and controls
134 lines (105 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.Linq;
using Shared.Interfaces;
using Tracked.Contexts;
using Tracked.Controls;
using Tracked.Models;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace Tracked.Screens {
public abstract class MapViewModelBase : ViewModelBase {
private CustomMap map;
private MapType mapType;
public event EventHandler<MapClickedEventArgs> MapTapped;
public MapViewModelBase(MainContext context)
: base(context) {
}
protected virtual bool IsReadOnly => false;
protected virtual ILatLng Centre => new LatLng(57.1499749, -2.1950675);
public virtual bool CanChangeMapType => !IsReadOnly;
public CustomMap CreateMap() {
Position centre = new Position(Centre.Latitude, Centre.Longitude);
map = new CustomMap(MapSpan.FromCenterAndRadius(centre, Distance.FromMiles(.5)), IsReadOnly);
map.IsShowingUser = false;
map.SetBinding(Map.MapTypeProperty, nameof(MapType), BindingMode.TwoWay);
map.InputTransparent = IsReadOnly;
map.MapClicked += (s, e) => {
MapTapped?.Invoke(s, e);
};
CreatePolylines();
CreatePins();
return map;
}
protected abstract IEnumerable<MapPin> GetPins();
protected abstract IEnumerable<MapPolyline> GetPolylines();
private void CreatePins() {
var pins = GetPins().ToList();
RotatePins(pins);
foreach (var pin in pins) {
if (pin == null) {
continue;
}
map.Pins.Add(pin);
}
}
private void RotatePins(IList<MapPin> pins) {
var duplicatePins = pins
.Select(i => new {
i.PinId,
i.Position.Latitude,
i.Position.Longitude,
})
.GroupBy(i => new {
i.Latitude,
i.Longitude,
}, i => i.PinId)
.Where(i => i.Count() > 1)
.ToList();
int rotationAngle = 45;
foreach (var duplicates in duplicatePins) {
int pinCount = duplicates.Count();
int rotation = -(pinCount / 2 * rotationAngle) - (rotationAngle / 2);
foreach (var duplicatePinId in duplicates) {
var pin = pins.Single(i => i.PinId == duplicatePinId);
pin.Rotation = rotation += rotationAngle;
}
}
}
private void CreatePolylines() {
var polylines = GetPolylines().ToList();
foreach (var polyline in polylines) {
if (polyline == null) {
continue;
}
CreatePolyline(polyline);
}
}
protected void CreatePolyline(MapPolyline polyline) {
if (polyline.Positions.Count() <= 1) {
return;
}
map.MapElements.Add(polyline);
}
protected void RemovePolyline(MapPolyline polyline) {
if (polyline == null) {
return;
}
map.MapElements.Remove(polyline);
}
public IEnumerable<MapType> MapTypes => (IEnumerable<MapType>)Enum.GetValues(typeof(MapType));
public MapType MapType {
get { return mapType; }
set {
if (mapType != value) {
mapType = value;
OnPropertyChanged(nameof(MapType));
}
}
}
protected void GoToLocation(ILatLng midpoint, Distance distance) {
var position = new Position(midpoint.Latitude, midpoint.Longitude);
map.MoveToRegion(MapSpan.FromCenterAndRadius(position, distance));
}
}
}