在UBER等谷歌地图上移动GMSMarker [英] Move GMSMarker on Google Map Like UBER

查看:156
本文介绍了在UBER等谷歌地图上移动GMSMarker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我得到了以前的lat / long的角度,当前的lat / long和动画mapwithBearing with the rotation

这是代码

  [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 =相机;如果([data objectForKey:@preLat]!= [NSNull null]&& [data objectForKey:@preLng]!= [NSNull null]){b

$ b {
if([[data objectForKey:@preLat] floatValue]!= 0.0f&& [[data objectForKey:@preLng] floatValue]!= 0.0f){
NSLog @pre_lat =%f和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文章取得学位代码,当汽车静止或转弯时,它会闪烁



这里是从另一个SO帖子获取角度的代码。

<$ (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))];

$ b - (double)ToRad :(双)度{
返回度*(M_PI / 180);
}
$ b $ - (double)ToBearing:(double)radians {
return [self ToDegrees:radians] + 360%360;
}

- (double)ToDegrees:(double)radians {
返回弧度* 180 / M_PI;
}

任何人都可以帮忙或者提出任何其他解决方案吗?

解决方案

一些如何处理这段代码。您可以尝试使用此代码进行一些逻辑更改。但是,它会正常工作。



  CLLocationCoordinate2D oldCoodinate = CLLocationCoordinate2DMake([[value 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]; //标记添加
时通过计算找到方位值driverMarker.position = oldCoodinate; //这可以使汽车运动到新位置的旧位置
driverMarker.map = mapView_;

//标记移动动画
[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]; //汽车移动完成后,后端的新轴承值
}];

driverMarker.position = newCoodinate; //汽车从旧位置移动到新位置后,这可以是新位置,使用动画
driverMarker.map = mapView_;
driverMarker.groundAnchor = CGPointMake(0.5,0.5);
driverMarker.rotation = [self getHeadingForDirectionFromCoordinate:oldCoodinate toCoordinate:newCoodinate]; //通过计算找到方位值
[CATransaction commit];

在.h文件中定义这两个



<$ (x)(M_PI * x / 180.0)
#define radiansToDegrees(x)(x * 180.0 / M_PI)
#define degreesToRadians >

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



< (CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = degreesToRadians(fromLoc.latitude); pre> - (float)getHeadingForDirectionFromCoordinate:
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 {
返回360度;
}
}

Swift 3.1 p>

  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)
//标记添加$ b $时计算方位值b driverMarker.position = oldCoodinate
//这可以使汽车移动到新位置的旧位置
driverMarker.map = mapView_
//标记移动动画
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))
//汽车移动完成后,来自后端的新轴承值
})
driverMarker.position = newCoodinate
//汽车从旧位置移动到带有动画的新位置后,这可能是新位置
driverMarker.map = mapView_
driverMarker.groundAnchor = CGPoint(x:CGFloat(0.5),y:CGFloat(0.5))
driverMarker.rotation = getHeadingForDirection(fromCoordinate:oldCoodinate,toCoordinate:newCoodinate)
//通过计算找到方位值
CATransaction.commit()



 扩展名Int {
var degreesToRadians:Double {return Double(self)* .pi / 180}
}
扩展FloatingPoint {
var degreesToRadians: Self {return self * .pi / 180}
var radiansToDegrees:Self {return self * 180 / .pi}
}



  func getHeadingForDirection(fromCoordinate fromLoc:CLLocationCoordinate2D,toCoordinat e toLoc:CLLocationCoordinate2D) - >浮动{

让fLat:Float = Float((fromLoc.latitude).degreesToRadians)
让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
如果degree> = 0 {
返回学位
}
其他{
return 360 + degree
}
}

用于github链接: ARCarMovement


I am developing some navigation tasks on google map. I have to move markers as vehicles moves with turns as uber does in their app. I have tried different solutions as offered on @SO but It is not working as I need.

I am getting angle with previous lat/long with current lat/long and animating mapwithBearing with that rotation

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

I just taken degree code from another @SO post, It works when I'm on straight road but when car is still or turning, it gives flickering

Here is code of getting angle from another SO post.

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

Can anyone help on this or propose any other solution?

解决方案

Some how working with this code. You can try with this code with some logics change. But, it will work fine.

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

define these two in .h file

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

method for get bearing value from old and new coordinates

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

for github link: ARCarMovement

这篇关于在UBER等谷歌地图上移动GMSMarker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆