像UBER一样在Google Map上移动GMSMarker

我正在谷歌地图上开发一些导航任务。 随着车辆在其应用程序中的移动,我必须移动标记。 我已经尝试了@SO提供的不同的解决scheme,但它不能按我的需要工作。

我得到与以前经纬/长与当前纬度/经度和animationmapwithwith旋转的angular度

这里是代码

[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]; 

我只是从另一个@SO职位取得学位证书,当我在直路上行驶时,但是当车辆静止或转弯时,它会发生闪烁

这是从另一个SOpost获取angular度的代码。

 -(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; } 

任何人都可以帮助或build议任何其他解决scheme?

一些如何使用这个代码。 你可以用这个代码尝试一些逻辑改变。 但是,它会正常工作。

 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]; 

在.h文件中定义这两个

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

从新旧坐标中获取方位值的方法

 - (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 } } 

为github链接: ARCarMovement