Rotate GMSMarker in direction at which user facing
Asked Answered
C

8

19

I have requirement like on my current location one view will display. It will rotate if device was rotate or location will be change.I research lot but got all the code which have a fix location or angle at some location but i haven't fix location. Can anyone drive me at right direction.

I also used rotation property of the GMSMarker but it is not working.

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    if (newHeading.headingAccuracy < 0){
        NSLog(@"heading accuracy < 0");
        return;
    }

    // Convert Degree to Radian and move the needle
    float oldRad =  (- manager.heading.trueHeading) * M_PI / 180.0f;
    float newRad =  (- newHeading.trueHeading) * M_PI / 180.0f;

    // Compass animation
    CABasicAnimation *theAnimation;
    theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
    theAnimation.toValue   = [NSNumber numberWithFloat:newRad];
    theAnimation.duration  = 0.5f;
    [source.layer addAnimation:theAnimation forKey:@"animateMyRotation"];

//    source.transform =  CGAffineTransformMakeRotation(newRad)
//    GMSMarker *source = [googleMap selectedMarker];
//    source.rotation = newRad;
}

Update: I have rotation method but is there any way to rotate the GMSMarker because there is no method for transform.

How uber rotate their car in google map?

enter image description here

Conceivable answered 6/4, 2016 at 12:0 Comment(12)
degree should be some variable you stored for previous heading degree.Pinna
@zcui93 but at the first time how i find that degreeConceivable
You just assign it with a default value, corresponding to the default direction of your arrow when loaded.Pinna
@chiragshah, jo baka thodi taklif to revani.. :)Coppery
@Coppery please tame taklif thodi dur karo neConceivable
@chiragshah try the solution here. https://mcmap.net/q/667187/-how-to-rotate-custom-marker-image-on-google-map-objective-cCletus
@chiragshah Have you fixed this issue ? Please let me know if you solution for this ?Brod
@KarthiKMandava i haven't find any solution for it. If i found i can let you knowConceivable
@chiragshah have you find any solutions on thisParatuberculosis
@Paratuberculosis for which point?Conceivable
getting location from server for every 5 sec but during turning marker getting drifted. have you solve thisParatuberculosis
@Paratuberculosis try to get heading value with location it will help you for this type of issueConceivable
T
7

Current location 'CLLocation' object has a property called 'course'

@property(readonly, nonatomic) CLLocationDirection course;

of type CLLocationDirection(typedef of double) which is an angle of the location.

For car to rotate, You need extra field in your backend, direction, along with latitude and longitude. Use this information to rotate car by applying Transform on UIView

CGAffineTransformMakeRotation(M_PI * (course_of_location) / 180.0);
Taster answered 16/4, 2016 at 10:50 Comment(4)
I already try this but still you not provide me the answer where i put this "CGAffineTransformMakeRotation(M_PI * (course_of_location) / 180.0);" code. Because marker has not any property for transform.Conceivable
@Sunil. how to set this CGAffineTransformMakeRotation in swift 3Fetial
CGAffineTransform(rotationAngle: (M_PI * (course_of_location) / 180.0))Taster
Hi I'm using course of location. But i don't want to turn the marker, I want to turn the mapview so that my marker always points to north. for this Im doing like this . mapView.animate(toBearing: CLLocationDirection.abs(LatestLocation.course)) But mais roating toomuch, Bcoz when user is turning left my course is 270. the same Im giving it to map to rotate, But want to rotate -90. how to do thatAbidjan
Y
9

We can rotate image based on course property CLLocation Class

    let marker = GMSMarker(position: currentLocation!)
    let head = locationManager.location?.course ?? 0
    marker.rotation = head
    marker.icon = UIImage(named: "testyCar.png")
    marker.map = mapView 
Yearning answered 5/1, 2017 at 8:53 Comment(0)
T
7

Current location 'CLLocation' object has a property called 'course'

@property(readonly, nonatomic) CLLocationDirection course;

of type CLLocationDirection(typedef of double) which is an angle of the location.

For car to rotate, You need extra field in your backend, direction, along with latitude and longitude. Use this information to rotate car by applying Transform on UIView

CGAffineTransformMakeRotation(M_PI * (course_of_location) / 180.0);
Taster answered 16/4, 2016 at 10:50 Comment(4)
I already try this but still you not provide me the answer where i put this "CGAffineTransformMakeRotation(M_PI * (course_of_location) / 180.0);" code. Because marker has not any property for transform.Conceivable
@Sunil. how to set this CGAffineTransformMakeRotation in swift 3Fetial
CGAffineTransform(rotationAngle: (M_PI * (course_of_location) / 180.0))Taster
Hi I'm using course of location. But i don't want to turn the marker, I want to turn the mapview so that my marker always points to north. for this Im doing like this . mapView.animate(toBearing: CLLocationDirection.abs(LatestLocation.course)) But mais roating toomuch, Bcoz when user is turning left my course is 270. the same Im giving it to map to rotate, But want to rotate -90. how to do thatAbidjan
W
6

you can do something like -

-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {

    CLLocationDirection direction = newHeading.trueHeading;
    lastDriverAngleFromNorth = direction;
    self.driverMarker.rotation = lastDriverAngleFromNorth - mapBearing;
}

#pragma mark - GMSMapViewDelegate

- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {

    mapBearing = position.bearing;
    self.driverMarker.rotation = lastDriverAngleFromNorth - mapBearing;
}
Wistrup answered 25/4, 2016 at 10:41 Comment(2)
i added this code. and it's work but one problem i have face is the marker is jump on that location and updated location. and also marker is continuously rotate even i don't move from my location.what can i do?Nobile
@Haider. how can i set position of marker based on latitude & longitude .These are coming from server. How can i set rotation..Fetial
A
2

Try this, it worked for me

func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading:CLHeading) {
    UIView.animate(withDuration: 0.005) {
       let angle = newHeading.trueHeading.toRadians() // convert from degrees to radians
       self.yourImageHere.transform = CGAffineTransform(rotationAngle: CGFloat(angle)) // rotate the picture
    }
}
override func viewDidLoad() {
   super.viewDidLoad()
   locationManager.startUpdatingHeading()
}
Armoured answered 12/11, 2018 at 8:43 Comment(0)
C
1

//just do this only

- (void)locationManager:(CLLocationManager *)manager  didUpdateHeading:(CLHeading *)newHeading
{
   double heading = newHeading.trueHeading;
   marker.groundAnchor = CGPointMake(0.5, 0.5);
   marker.rotation = heading;
   marker.map = mapView;
}
Crackle answered 10/9, 2016 at 11:20 Comment(0)
O
0
marker.rotation = course_of_location;

Note: rotation to pin will happen only during movement. in case of static device there will be -1 value of location.course. Also this have no relation with device orientation. If you are looking to move pin according to device heading then do this

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
marker.rotation =  (manager.heading.trueHeading) * M_PI / 180.0f; }
Orme answered 19/8, 2016 at 6:36 Comment(1)
Rotation is property of GMSMarker, CLLocation class provides the Course which actual direction of movement (not a direction of device). So if you set above code even you can simply do 'marker.rotation = location.course; it wil work when you will move. When there is no movement then course value is -1 and it will not show any rotation.Orme
L
0

Here the code modified with the changes suggested by Oren Trutner and from me:

You just need to pass old location and new location. By passing required data you will get rotation value which is in float.

#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;
    }
}
Lochner answered 24/11, 2018 at 10:41 Comment(1)
I have tested and implemented in my one of the app recently.Lochner
C
0

Swift 4+

Thanks to priya.vr. When you updating location marker, try this:

 let locationManager = CLLocationManager()
 marker.position = position
 marker.appearAnimation = .none
 marker.rotation = locationManager.location?.course ?? 0
 marker.map = map
Crockery answered 28/2, 2019 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.