1//
2// Created by Leland Richardson on 12/27/15.
3// Copyright (c) 2015 Facebook. All rights reserved.
4//
5
6#import "AIRMapPolyline.h"
7#import "AIRMapPolylineRenderer.h"
8#import <React/UIView+React.h>
9
10
11@implementation AIRMapPolyline {
12
13}
14
15- (void)setFillColor:(UIColor *)fillColor {
16    _fillColor = fillColor;
17    [self update];
18}
19
20- (void)setStrokeColor:(UIColor *)strokeColor {
21    _strokeColor = strokeColor;
22    [self update];
23}
24
25- (void)setStrokeColors:(NSArray<UIColor *> *)strokeColors {
26    _strokeColors = strokeColors;
27    if ((self.renderer != nil) && ![_renderer isKindOfClass:[AIRMapPolylineRenderer class]]) {
28        self.renderer = [self createRenderer];
29    }
30    [self update];
31}
32
33- (void)setStrokeWidth:(CGFloat)strokeWidth {
34    _strokeWidth = strokeWidth;
35    [self update];
36}
37
38- (void)setLineJoin:(CGLineJoin)lineJoin {
39    _lineJoin = lineJoin;
40    [self update];
41}
42
43- (void)setLineCap:(CGLineCap)lineCap {
44    _lineCap = lineCap;
45    [self update];
46}
47
48- (void)setMiterLimit:(CGFloat)miterLimit {
49    _miterLimit = miterLimit;
50    [self update];
51}
52
53- (void)setLineDashPhase:(CGFloat)lineDashPhase {
54    _lineDashPhase = lineDashPhase;
55    [self update];
56}
57
58- (void)setLineDashPattern:(NSArray <NSNumber *> *)lineDashPattern {
59    _lineDashPattern = lineDashPattern;
60    [self update];
61}
62
63-(void)setGeodesic:(BOOL)geodesic
64{
65  _geodesic = geodesic;
66    if(_coordinates){
67        [self setCoordinates:_coordinates];
68    }
69}
70
71- (void)setCoordinates:(NSArray<AIRMapCoordinate *> *)coordinates {
72    _coordinates = coordinates;
73    CLLocationCoordinate2D *coords = calloc(coordinates.count, sizeof(CLLocationCoordinate2D));
74    for(int i = 0; i < coordinates.count; i++)
75    {
76        coords[i] = coordinates[i].coordinate;
77    }
78    if(_geodesic){
79        self.polyline = [MKGeodesicPolyline polylineWithCoordinates:coords count:coordinates.count];
80    } else {
81        self.polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count];
82    }
83    free(coords);
84
85    self.renderer = [self createRenderer];
86    [self update];
87}
88
89- (MKOverlayPathRenderer*)createRenderer {
90    if (self.polyline == nil) return nil;
91    if (self.strokeColors == nil) {
92        // Use the default renderer when no array of stroke-colors is defined.
93        // This behaviour may be changed in the future if we permanently want to
94        // use the custom renderer, because it can add funtionality that is not
95        // supported by the default renderer.
96        return [[MKPolylineRenderer alloc] initWithPolyline:self.polyline];
97    }
98    else {
99        return [[AIRMapPolylineRenderer alloc] initWithOverlay:self polyline:self.polyline];
100    }
101}
102
103- (void) update
104{
105    if (!_renderer) return;
106    [self updateRenderer:_renderer];
107
108    if (_map == nil) return;
109    [_map removeOverlay:self];
110    [_map addOverlay:self];
111}
112
113- (void) updateRenderer:(MKOverlayPathRenderer*)renderer {
114    renderer.fillColor = _fillColor;
115    renderer.strokeColor = _strokeColor;
116    renderer.lineWidth = _strokeWidth;
117    renderer.lineCap = _lineCap;
118    renderer.lineJoin = _lineJoin;
119    renderer.miterLimit = _miterLimit;
120    renderer.lineDashPhase = _lineDashPhase;
121    renderer.lineDashPattern = _lineDashPattern;
122
123    if ([renderer isKindOfClass:[AIRMapPolylineRenderer class]]) {
124        ((AIRMapPolylineRenderer*)renderer).strokeColors = _strokeColors;
125    }
126}
127
128#pragma mark MKOverlay implementation
129
130- (CLLocationCoordinate2D) coordinate
131{
132    return self.polyline.coordinate;
133}
134
135- (MKMapRect) boundingMapRect
136{
137    return self.polyline.boundingMapRect;
138}
139
140- (BOOL)intersectsMapRect:(MKMapRect)mapRect
141{
142    BOOL answer = [self.polyline intersectsMapRect:mapRect];
143    return answer;
144}
145
146- (BOOL)canReplaceMapContent
147{
148    return NO;
149}
150
151
152#pragma mark AIRMapSnapshot implementation
153
154- (void) drawToSnapshot:(MKMapSnapshot *) snapshot context:(CGContextRef) context
155{
156    AIRMapPolylineRenderer* renderer = [[AIRMapPolylineRenderer alloc] initWithSnapshot:snapshot overlay:self polyline:self.polyline];
157    [self updateRenderer:renderer];
158    [renderer drawWithZoomScale:2 inContext:context];
159}
160
161@end
162