summaryrefslogtreecommitdiff
path: root/platform/ios/app/MBXUserLocationAnnotationView.m
blob: 675a01930ae5f8a18b0ca1aa35d00bc03be0e33a (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#import "MBXUserLocationAnnotationView.h"

const CGFloat MBXUserLocationDotSize = 10;

@implementation MBXUserLocationAnnotationView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self == nil) return nil;
    self.backgroundColor = [UIColor clearColor];
    return self;
}

- (void)update
{
    [self updateFrameWithSize:self.intrinsicContentSize];
    [self setNeedsDisplay];
}


- (CGSize)intrinsicContentSize
{
    CGSize carSize = CGSizeMake(30, 60);
    return (self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? carSize : [self dotSize];
}

- (CGSize)dotSize
{
    CGFloat minDotSize = 30;
    CGFloat dotSize = MAX(minDotSize, self.accuracyInPoints);
    return CGSizeMake(dotSize, dotSize);
}

- (void)updateFrameWithSize:(CGSize)size
{
    if (CGSizeEqualToSize(self.frame.size, size)) return;

    // Update frame size, keeping the existing center point.
    CGRect newFrame = self.frame;
    CGPoint oldCenter = self.center;
    newFrame.size = size;
    self.frame = newFrame;
    self.center = oldCenter;
}

- (CGFloat)accuracyInPoints
{
    CGFloat metersPerPoint = [self.mapView metersPerPointAtLatitude:self.userLocation.location.coordinate.latitude];
    return self.userLocation.location.horizontalAccuracy / metersPerPoint;
}

- (void)drawRect:(CGRect)rect
{
    (self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? [self drawCar] : [self drawDot];
}

- (void)drawDot
{
    // Accuracy
    CGFloat accuracy = self.accuracyInPoints;

    CGFloat center = self.bounds.size.width / 2.0 - accuracy / 2.0;
    UIBezierPath *accuracyPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(center, center, accuracy, accuracy)];
    UIColor *accuracyColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:.4];
    [accuracyColor setFill];
    [accuracyPath fill];

    // Dot
    center = self.bounds.size.width / 2.0 - MBXUserLocationDotSize / 2.0;
    UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(center, center, MBXUserLocationDotSize, MBXUserLocationDotSize)];
    [UIColor.greenColor setFill];
    [ovalPath fill];

    [UIColor.blackColor setStroke];
    ovalPath.lineWidth = 1;
    [ovalPath stroke];

    // Accuracy text
    UIFont *font = [UIFont systemFontOfSize:11];
    [[NSString stringWithFormat:@"%.0f", accuracy]
     drawAtPoint:CGPointZero withAttributes:@{NSFontAttributeName: font,
                                              NSBackgroundColorAttributeName: [UIColor colorWithWhite:0 alpha:.5],
                                              NSForegroundColorAttributeName: [UIColor whiteColor]}];
}

- (void)drawCar
{
    UIColor* fillColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
    UIColor* strokeColor = [UIColor colorWithRed: 0.592 green: 0.592 blue: 0.592 alpha: 1];
    UIColor* fillColor2 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];

    UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
    [bezier2Path moveToPoint: CGPointMake(30, 7.86)];
    [bezier2Path addLineToPoint: CGPointMake(30, 52.66)];
    [bezier2Path addCurveToPoint: CGPointMake(0, 52.66) controlPoint1: CGPointMake(30, 62.05) controlPoint2: CGPointMake(0, 62.84)];
    [bezier2Path addCurveToPoint: CGPointMake(0, 7.86) controlPoint1: CGPointMake(0, 42.48) controlPoint2: CGPointMake(0, 17.89)];
    [bezier2Path addCurveToPoint: CGPointMake(30, 7.86) controlPoint1: CGPointMake(-0, -2.17) controlPoint2: CGPointMake(30, -3.05)];
    [bezier2Path closePath];
    bezier2Path.usesEvenOddFillRule = YES;

    [fillColor setFill];
    [bezier2Path fill];

    UIBezierPath* bezier3Path = [UIBezierPath bezierPath];
    [bezier3Path moveToPoint: CGPointMake(30, 7.86)];
    [bezier3Path addLineToPoint: CGPointMake(30, 52.66)];
    [bezier3Path addCurveToPoint: CGPointMake(0, 52.66) controlPoint1: CGPointMake(30, 62.05) controlPoint2: CGPointMake(0, 62.84)];
    [bezier3Path addCurveToPoint: CGPointMake(0, 7.86) controlPoint1: CGPointMake(0, 42.48) controlPoint2: CGPointMake(0, 17.89)];
    [bezier3Path addCurveToPoint: CGPointMake(30, 7.86) controlPoint1: CGPointMake(0, -2.17) controlPoint2: CGPointMake(30, -3.05)];
    [bezier3Path closePath];
    [strokeColor setStroke];
    bezier3Path.lineWidth = 1;
    [bezier3Path stroke];

    UIBezierPath* bezier4Path = [UIBezierPath bezierPath];
    [bezier4Path moveToPoint: CGPointMake(15.56, 4.26)];
    [bezier4Path addCurveToPoint: CGPointMake(26, 6) controlPoint1: CGPointMake(21, 4.26) controlPoint2: CGPointMake(26, 6)];
    [bezier4Path addCurveToPoint: CGPointMake(23, 21) controlPoint1: CGPointMake(26, 6) controlPoint2: CGPointMake(29, 17)];
    [bezier4Path addCurveToPoint: CGPointMake(16, 21) controlPoint1: CGPointMake(20.03, 22.98) controlPoint2: CGPointMake(16, 21)];
    [bezier4Path addCurveToPoint: CGPointMake(7, 21) controlPoint1: CGPointMake(16, 21) controlPoint2: CGPointMake(9.02, 23.53)];
    [bezier4Path addCurveToPoint: CGPointMake(4, 6) controlPoint1: CGPointMake(3, 16) controlPoint2: CGPointMake(4, 6)];
    [bezier4Path addCurveToPoint: CGPointMake(15.56, 4.26) controlPoint1: CGPointMake(4, 6) controlPoint2: CGPointMake(10.12, 4.26)];
    [bezier4Path closePath];
    bezier4Path.usesEvenOddFillRule = YES;

    [fillColor2 setFill];
    [bezier4Path fill];

    UIBezierPath* rectanglePath = [UIBezierPath bezierPath];
    [rectanglePath moveToPoint: CGPointMake(25, 46)];
    [rectanglePath addCurveToPoint: CGPointMake(21, 55) controlPoint1: CGPointMake(31, 46) controlPoint2: CGPointMake(28.5, 55)];
    [rectanglePath addCurveToPoint: CGPointMake(9, 55) controlPoint1: CGPointMake(13.5, 55) controlPoint2: CGPointMake(14, 55)];
    [rectanglePath addCurveToPoint: CGPointMake(5, 46) controlPoint1: CGPointMake(4, 55) controlPoint2: CGPointMake(0, 46)];
    [rectanglePath addCurveToPoint: CGPointMake(25, 46) controlPoint1: CGPointMake(10, 46) controlPoint2: CGPointMake(19, 46)];
    [rectanglePath closePath];
    [UIColor.whiteColor setFill];
    [rectanglePath fill];

    UIBezierPath* bezierPath = [UIBezierPath bezierPath];
    [UIColor.whiteColor setFill];
    [bezierPath fill];

    UIBezierPath* rectangle2Path = [UIBezierPath bezierPath];
    [rectangle2Path moveToPoint: CGPointMake(2, 35)];
    [rectangle2Path addCurveToPoint: CGPointMake(4.36, 35) controlPoint1: CGPointMake(2, 39) controlPoint2: CGPointMake(4.36, 35)];
    [rectangle2Path addCurveToPoint: CGPointMake(4.36, 22) controlPoint1: CGPointMake(4.36, 35) controlPoint2: CGPointMake(5.55, 26)];
    [rectangle2Path addCurveToPoint: CGPointMake(2, 22) controlPoint1: CGPointMake(3.18, 18) controlPoint2: CGPointMake(2, 22)];
    [rectangle2Path addCurveToPoint: CGPointMake(2, 35) controlPoint1: CGPointMake(2, 22) controlPoint2: CGPointMake(2, 31)];
    [rectangle2Path closePath];
    [UIColor.whiteColor setFill];
    [rectangle2Path fill];

    UIBezierPath* rectangle3Path = [UIBezierPath bezierPath];
    [rectangle3Path moveToPoint: CGPointMake(28, 35)];
    [rectangle3Path addCurveToPoint: CGPointMake(25.64, 35) controlPoint1: CGPointMake(28, 39) controlPoint2: CGPointMake(25.64, 35)];
    [rectangle3Path addCurveToPoint: CGPointMake(25.64, 22) controlPoint1: CGPointMake(25.64, 35) controlPoint2: CGPointMake(24.45, 26)];
    [rectangle3Path addCurveToPoint: CGPointMake(28, 22) controlPoint1: CGPointMake(26.82, 18) controlPoint2: CGPointMake(28, 22)];
    [rectangle3Path addCurveToPoint: CGPointMake(28, 35) controlPoint1: CGPointMake(28, 22) controlPoint2: CGPointMake(28, 31)];
    [rectangle3Path closePath];
    [UIColor.whiteColor setFill];
    [rectangle3Path fill];
}

@end