diff options
Diffstat (limited to 'platform/ios/app')
-rw-r--r-- | platform/ios/app/MBXUserLocationAnnotationView.h | 5 | ||||
-rw-r--r-- | platform/ios/app/MBXUserLocationAnnotationView.m | 165 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 24 |
3 files changed, 193 insertions, 1 deletions
diff --git a/platform/ios/app/MBXUserLocationAnnotationView.h b/platform/ios/app/MBXUserLocationAnnotationView.h new file mode 100644 index 0000000000..39ed729d2b --- /dev/null +++ b/platform/ios/app/MBXUserLocationAnnotationView.h @@ -0,0 +1,5 @@ +#import <Mapbox/Mapbox.h> + +@interface MBXUserLocationAnnotationView : MGLUserLocationAnnotationView + +@end diff --git a/platform/ios/app/MBXUserLocationAnnotationView.m b/platform/ios/app/MBXUserLocationAnnotationView.m new file mode 100644 index 0000000000..a0347a174f --- /dev/null +++ b/platform/ios/app/MBXUserLocationAnnotationView.m @@ -0,0 +1,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 diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index f1eed9625b..4c98dc75fb 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -4,6 +4,7 @@ #import "MBXCustomCalloutView.h" #import "MBXOfflinePacksTableViewController.h" #import "MBXAnnotationView.h" +#import "MBXUserLocationAnnotationView.h" #import "MGLFillStyleLayer.h" #import <Mapbox/Mapbox.h> @@ -42,6 +43,7 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie @property (nonatomic) IBOutlet MGLMapView *mapView; @property (nonatomic) NSInteger styleIndex; @property (nonatomic) BOOL debugLoggingEnabled; +@property (nonatomic) BOOL customUserLocationAnnnotationEnabled; @end @@ -201,7 +203,10 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie @"Start World Tour", @"Add Custom Callout Point", @"Remove Annotations", - @"Runtime styling", + @"Runtime Styling", + ((_customUserLocationAnnnotationEnabled) + ? @"Disable Custom User Dot" + : @"Enable Custom User Dot"), nil]; if (self.debugLoggingEnabled) @@ -283,6 +288,12 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie { [self testRuntimeStyling]; } + else if (buttonIndex == actionSheet.firstOtherButtonIndex + 17) + { + _customUserLocationAnnnotationEnabled = !_customUserLocationAnnnotationEnabled; + self.mapView.showsUserLocation = NO; + self.mapView.userTrackingMode = MGLUserTrackingModeFollow; + } else if (buttonIndex == actionSheet.numberOfButtons - 2 && self.debugLoggingEnabled) { NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogfilePath] encoding:NSUTF8StringEncoding error:nil]; @@ -697,6 +708,17 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation { + if (annotation == mapView.userLocation) + { + if (_customUserLocationAnnnotationEnabled) + { + MBXUserLocationAnnotationView *annotationView = [[MBXUserLocationAnnotationView alloc] initWithFrame:CGRectZero]; + annotationView.frame = CGRectMake(0, 0, annotationView.intrinsicContentSize.width, annotationView.intrinsicContentSize.height); + return annotationView; + } + + return nil; + } // Use GL backed pins for dropped pin annotations if ([annotation isKindOfClass:[MBXDroppedPinAnnotation class]] || [annotation isKindOfClass:[MBXSpriteBackedAnnotation class]]) { |