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

Chirag Shah
  • 3,034
  • 1
  • 30
  • 61

8 Answers8

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 
Michal Šrůtek
  • 1,647
  • 16
  • 17
priya.vr
  • 239
  • 5
  • 12
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);
Uma Madhavi
  • 4,851
  • 5
  • 38
  • 73
Sunil_Vaishnav
  • 425
  • 1
  • 5
  • 15
  • 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. – Chirag Shah Apr 18 '16 at 05:21
  • @Sunil. how to set this CGAffineTransformMakeRotation in swift 3 – Uma Madhavi Mar 28 '17 at 11:45
  • CGAffineTransform(rotationAngle: (M_PI * (course_of_location) / 180.0)) – Sunil_Vaishnav Mar 29 '17 at 09:04
  • 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 that – siva krishna Apr 25 '17 at 08:36
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;
}
Haider
  • 4,961
  • 2
  • 18
  • 25
  • 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? – ios developer Dec 08 '16 at 06:40
  • @Haider. how can i set position of marker based on latitude & longitude .These are coming from server. How can i set rotation.. – Uma Madhavi Dec 15 '16 at 11:36
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()
}
Rohan Kumar
  • 40,431
  • 11
  • 76
  • 106
BizDev
  • 371
  • 1
  • 4
  • 21
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;
}
Tomasz Pluskiewicz
  • 3,622
  • 1
  • 19
  • 42
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; }
Waseem Sarwar
  • 2,645
  • 1
  • 21
  • 18
  • 2
    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. – Waseem Sarwar Aug 21 '16 at 08:45
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;
    }
}
Anil Kukadeja
  • 1,348
  • 1
  • 14
  • 27
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
A. Lebedko
  • 61
  • 9