Déplacer GMSMarker sur Google Map Like UBER

Je développe quelques tâches de navigation sur google map. Je dois déplacer des marqueurs lorsque les véhicules se déplacent avec des virages comme le fait uber dans leur application. J'ai essayé différentes solutions comme sur @SO mais ça ne marche pas comme j'ai besoin.

Je reçois un angle avec le lat / long précédent avec le courant lat / long et l'animation mapwithBearing avec cette rotation

Voici le code

[CATransaction begin]; [CATransaction setAnimationDuration:2.0]; NSDictionary *data = [[result objectForKey:@"returnData"] objectForKey:@"data"]; if (![data isEqual: [NSNull null]]) { driverLocationCoordinate = CLLocationCoordinate2DMake([[data objectForKey:@"lat"] doubleValue], [[data objectForKey:@"lng"] doubleValue]); driverMarker.position = driverLocationCoordinate; GMSCameraPosition * camera = [GMSCameraPosition cameraWithLatitude:driverLocationCoordinate.latitude longitude:driverLocationCoordinate.longitude zoom:16]; mapHomeView.camera = camera; if ([data objectForKey:@"preLat"] != [NSNull null] && [data objectForKey:@"preLng"] !=[NSNull null]){ if ([[data objectForKey:@"preLat"] floatValue] != 0.0f && [[data objectForKey:@"preLng"] floatValue] != 0.0f) { NSLog(@"pre_lat = %f and pre_lng = %f", [[data objectForKey:@"preLat"] floatValue], [[data objectForKey:@"preLng"] floatValue]); CLLocationCoordinate2D previousCoordinates = CLLocationCoordinate2DMake([[data objectForKey:@"preLat"] floatValue], [[data objectForKey:@"preLng"] floatValue]); driverMarker.rotation = [self DegreeBearing:previousCoordinates locationB:driverMarker.position]; [mapHomeView animateToBearing:driverMarker.rotation]; } } [CATransaction commit]; 

Je viens de prendre le code degré d'un autre post @SO, Il fonctionne quand je suis sur la route droite, mais quand la voiture est immobile ou en tournant, il donne des scintillements

Voici le code d'obtention de l'angle d'un autre message SO.

 -(double) DegreeBearing:(CLLocationCoordinate2D) A locationB: (CLLocationCoordinate2D)B{ double dlon = [self ToRad:(B.longitude - A.longitude) ]; double dPhi = log(tan([self ToRad:(B.latitude)] / 2 + M_PI / 4) / tan([self ToRad:(A.latitude)] / 2 + M_PI / 4)); if (fabs(dlon) > M_PI){ dlon = (dlon > 0) ? (dlon - 2*M_PI) : (2*M_PI + dlon); } return [self ToBearing:(atan2(dlon, dPhi))]; } -(double) ToRad: (double)degrees{ return degrees*(M_PI/180); } -(double) ToBearing:(double)radians{ return [self ToDegrees:radians] + 360 % 360; } -(double) ToDegrees: (double)radians{ return radians * 180 / M_PI; } 

Quelqu'un peut-il aider à ce sujet ou proposer une autre solution?

Certains comment fonctionnent avec ce code. Vous pouvez essayer avec ce code avec quelques changements de logique. Mais, cela fonctionnera bien.

 CLLocationCoordinate2D oldCoodinate = CLLocationCoordinate2DMake([[data valueForKey:@"lat"]doubleValue],[[data valueForKey:@"lng"]doubleValue]); CLLocationCoordinate2D newCoodinate = CLLocationCoordinate2DMake([[data valueForKey:@"lat"]doubleValue],[[data valueForKey:@"lng"]doubleValue]); driverMarker.groundAnchor = CGPointMake(0.5, 0.5); driverMarker.rotation = [self getHeadingForDirectionFromCoordinate:oldCoodinate toCoordinate:newCoodinate]; //found bearing value by calculation when marker add driverMarker.position = oldCoodinate; //this can be old position to make car movement to new position driverMarker.map = mapView_; //marker movement animation [CATransaction begin]; [CATransaction setValue:[NSNumber numberWithFloat:2.0] forKey:kCATransactionAnimationDuration]; [CATransaction setCompletionBlock:^{ driverMarker.groundAnchor = CGPointMake(0.5, 0.5); driverMarker.rotation = [[data valueForKey:@"bearing"] doubleValue]; //New bearing value from backend after car movement is done }]; driverMarker.position = newCoodinate; //this can be new position after car moved from old position to new position with animation driverMarker.map = mapView_; driverMarker.groundAnchor = CGPointMake(0.5, 0.5); driverMarker.rotation = [self getHeadingForDirectionFromCoordinate:oldCoodinate toCoordinate:newCoodinate]; //found bearing value by calculation [CATransaction commit]; 

définir ces deux files .h

 #define degreesToRadians(x) (M_PI * x / 180.0) #define radiansToDegrees(x) (x * 180.0 / M_PI) 

méthode pour get la valeur de relèvement des coordonnées anciennes et nouvelles

 - (float)getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc { float fLat = degreesToRadians(fromLoc.latitude); float fLng = degreesToRadians(fromLoc.longitude); float tLat = degreesToRadians(toLoc.latitude); float tLng = degreesToRadians(toLoc.longitude); float degree = radiansToDegrees(atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng))); if (degree >= 0) { return degree; } else { return 360+degree; } } 

Swift 3.1

  var oldCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2DMake(CDouble((data.value(forKey: "lat") as? CLLocationCoordinate2D)), CDouble((data.value(forKey: "lng") as? CLLocationCoordinate2D))) var newCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2DMake(CDouble((data.value(forKey: "lat") as? CLLocationCoordinate2D)), CDouble((data.value(forKey: "lng") as? CLLocationCoordinate2D))) driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5)) driverMarker.rotation = getHeadingForDirection(fromCoordinate: oldCoodinate, toCoordinate: newCoodinate) //found bearing value by calculation when marker add driverMarker.position = oldCoodinate //this can be old position to make car movement to new position driverMarker.map = mapView_ //marker movement animation CATransaction.begin() CATransaction.setValue(Int(2.0), forKey: kCATransactionAnimationDuration) CATransaction.setCompletionBlock({() -> Void in driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5)) driverMarker.rotation = CDouble(data.value(forKey: "bearing")) //New bearing value from backend after car movement is done }) driverMarker.position = newCoodinate //this can be new position after car moved from old position to new position with animation driverMarker.map = mapView_ driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5)) driverMarker.rotation = getHeadingForDirection(fromCoordinate: oldCoodinate, toCoordinate: newCoodinate) //found bearing value by calculation CATransaction.commit() 
 extension Int { var degreesToRadians: Double { return Double(self) * .pi / 180 } } extension FloatingPoint { var degreesToRadians: Self { return self * .pi / 180 } var radiansToDegrees: Self { return self * 180 / .pi } } 
 func getHeadingForDirection(fromCoordinate fromLoc: CLLocationCoordinate2D, toCoordinate toLoc: CLLocationCoordinate2D) -> Float { let fLat: Float = Float((fromLoc.latitude).degreesToRadians) let fLng: Float = Float((fromLoc.longitude).degreesToRadians) let tLat: Float = Float((toLoc.latitude).degreesToRadians) let tLng: Float = Float((toLoc.longitude).degreesToRadians) let degree: Float = (atan2(sin(tLng - fLng) * cos(tLat), cos(fLat) * sin(tLat) - sin(fLat) * cos(tLat) * cos(tLng - fLng))).radiansToDegrees if degree >= 0 { return degree } else { return 360 + degree } } 

pour le lien github: ARCarMovement