How to get animated polyline route in GMSMapView, so that it move along with map when map is moved?
SWIFT
Declartion
var polyline = GMSPolyline()var animationPolyline = GMSPolyline()var path = GMSPath()var animationPath = GMSMutablePath()var i: UInt = 0var timer: Timer!
To Darw Route
func drawRoute(routeDict: Dictionary<String, Any>) { let routesArray = routeDict ["routes"] as! NSArray if (routesArray.count > 0) { let routeDict = routesArray[0] as! Dictionary<String, Any> let routeOverviewPolyline = routeDict["overview_polyline"] as! Dictionary<String, Any> let points = routeOverviewPolyline["points"] self.path = GMSPath.init(fromEncodedPath: points as! String)! self.polyline.path = path self.polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) self.polyline.strokeWidth = 3.0 self.polyline.map = self.mapView self.timer = Timer.scheduledTimer(timeInterval: 0.003, target: self, selector: #selector(animatePolylinePath), userInfo: nil, repeats: true) } }
To Animate Path
func animatePolylinePath() { if (self.i < self.path.count()) { self.animationPath.add(self.path.coordinate(at: self.i)) self.animationPolyline.path = self.animationPath self.animationPolyline.strokeColor = UIColor.black self.animationPolyline.strokeWidth = 3 self.animationPolyline.map = self.mapView self.i += 1 } else { self.i = 0 self.animationPath = GMSMutablePath() self.animationPolyline.map = nil } }
Don't forgot to stop timer in viewWillDisappear
self.timer.invalidate()
Output
I am create GMSPath
animation with path coordinate
Objective C
interface
@interface MapWithTracking () @property (weak, nonatomic) IBOutlet GMSMapView *mapView;@property (nonatomic,strong) GMSMutablePath *path2;@property (nonatomic,strong)NSMutableArray *arrayPolylineGreen;@property (nonatomic,strong) GMSPolyline *polylineBlue;@property (nonatomic,strong) GMSPolyline *polylineGreen;@end
implementation
-(void)viewDidLoad { _arrayPolylineGreen = [[NSMutableArray alloc] init]; _path2 = [[GMSMutablePath alloc]init];}
Get a GMSPath
and create a blue polyline.
-(void)createBluePolyline(GMSPath *path) { // Here create a blue poly line _polylineBlue = [GMSPolyline polylineWithPath:path]; _polylineBlue.strokeColor = [UIColor blueColor]; _polylineBlue.strokeWidth = 3; _polylineBlue.map = _mapView; // animate green path with timer [NSTimer scheduledTimerWithTimeInterval:0.003 repeats:true block:^(NSTimer * _Nonnull timer) { [self animate:path]; }];}
Animate a Green Polyline
Adding coordinate to path 2 and assign to map
-(void)animate:(GMSPath *)path { dispatch_async(dispatch_get_main_queue(), ^{ if (i < path.count) { [_path2 addCoordinate:[path coordinateAtIndex:i]]; _polylineGreen = [GMSPolyline polylineWithPath:_path2]; _polylineGreen.strokeColor = [UIColor greenColor]; _polylineGreen.strokeWidth = 3; _polylineGreen.map = _mapView; [arrayPolylineGreen addObject:_polylineGreen]; i++; } else { i = 0; _path2 = [[GMSMutablePath alloc] init]; for (GMSPolyline *line in arrayPolylineGreen) { line.map = nil; } } });}
This is an adaptation of the code from Elangovan
The changes that I did was to remove the var from the class to be just in the function and also removed the #selector that is no longer need in iOS >= 10.
var timerAnimation: Timer!var mapView:GMSMapView? func drawRoute(encodedString: String, animated: Bool) { if let path = GMSMutablePath(fromEncodedPath: encodedString) { let polyline = GMSPolyline(path: path) polyline.strokeWidth = 3.0 polyline.strokeColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) polyline.map = Singleton.shared.getMapView() if(animated){ self.animatePolylinePath(path: path) } } } func animatePolylinePath(path: GMSMutablePath) { var pos: UInt = 0 var animationPath = GMSMutablePath() let animationPolyline = GMSPolyline() self.timerAnimation = Timer.scheduledTimer(withTimeInterval: 0.003, repeats: true) { timer in pos += 1 if(pos >= path.count()){ pos = 0 animationPath = GMSMutablePath() animationPolyline.map = nil } animationPath.add(path.coordinate(at: pos)) animationPolyline.path = animationPath animationPolyline.strokeColor = UIColor.yellow animationPolyline.strokeWidth = 3 animationPolyline.map = self.mapView } } func stopAnimatePolylinePath() { self.timerAnimation.invalidate() }