Replace blue dot in GMSMapView by an arrow - Swift
Asked Answered
A

2

1

I use the Google SDK for an application iOS8 (Swift). I want to replace the blue dot (my location) in a GMSMapView by an arrow witch rotate according to the orientation of the smartphone. How can I do that?

EDIT :

I managed to see my arrow but I have three problems :

enter image description here

1 : The arrow is cut and I do not find as enlarge the area

2 : The position of the arrow is not exactly on my location I solve this problem by delete "0,5" :

CGContextTranslateCTM(context, size.width, size.height)

3 : The direction of the arrow is symmetrical to the original I solve this problem by adding "-" before "degrees" :

CGContextRotateCTM(context, CGFloat(DegreesToRadians(Double(-degrees))))

How to solve these problems ?

Angy answered 11/3, 2015 at 13:34 Comment(0)
B
4

If you are using Google Maps iOS SDK, seems there is no way to replace the default user location icon. However the default icon already has an arrow to indicate which direction user is going (simply call mapView.myLocationEnabled = true).

A workaround is to put a marker on user's current position, and change the marker image based on heading.

Sample Code (the full source code):

    func RadiansToDegrees(radians: Double) -> Double {
        return radians * 180.0/M_PI
    }

    func DegreesToRadians(degrees: Double) -> Double {
        return degrees * M_PI / 180.0
    }

    var GeoAngle = 0.0
    var locationManager = CLLocationManager()
    var marker = GMSMarker()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var camera = GMSCameraPosition.cameraWithLatitude(-33.86,
            longitude: 151.20, zoom: 6)
        var mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
        self.view = mapView

        marker.map = mapView

        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
    }

    func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
        var camera = GMSCameraPosition.cameraWithLatitude(newLocation.coordinate.latitude,
            longitude: newLocation.coordinate.longitude, zoom: 15)
        (self.view as GMSMapView).animateToCameraPosition(camera)

        GeoAngle = self.setLatLonForDistanceAndAngle(newLocation)
        marker.position = newLocation.coordinate
    }

    func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!) {
        var direction = -newHeading.trueHeading as Double
        marker.icon = self.imageRotatedByDegrees(CGFloat(direction), image: UIImage(named: "arrow.png")!)
    }


    func imageRotatedByDegrees(degrees: CGFloat, image: UIImage) -> UIImage{
        var size = image.size

        UIGraphicsBeginImageContext(size)
        var context = UIGraphicsGetCurrentContext()

        CGContextTranslateCTM(context, 0.5*size.width, 0.5*size.height)
        CGContextRotateCTM(context, CGFloat(DegreesToRadians(Double(degrees))))

        image.drawInRect(CGRect(origin: CGPoint(x: -size.width*0.5, y: -size.height*0.5), size: size))
        var newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }

    func setLatLonForDistanceAndAngle(userLocation: CLLocation) -> Double {
        var lat1 = DegreesToRadians(userLocation.coordinate.latitude)
        var lon1 = DegreesToRadians(userLocation.coordinate.longitude)

        var lat2 = DegreesToRadians(37.7833);
        var lon2 = DegreesToRadians(-122.4167);

        var dLon = lon2 - lon1;

        var y = sin(dLon) * cos(lat2);
        var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
        var radiansBearing = atan2(y, x);
        if(radiansBearing < 0.0)
        {
            radiansBearing += 2*M_PI;
        }

        return radiansBearing;
    }

The key step is to change image based on the degree come from the func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!) method.

You also need to make sure to add NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription in your info.plist file.

enter image description here

Biotype answered 11/3, 2015 at 20:52 Comment(2)
Thank you very much for this comprehensive response. I have just 3 problems. I have edit my post. Do you know where these problems ?Angy
My arrow is able to shown, not sure why yours is cut off. Seems you have solved yours 2nd and 3rd problem, the code I wrote definitely need some improvement, you might refer this post for different but similar approaches: #7174425Biotype
S
0

The default blue icon of Google maps in iOS can be hide by setting

mapView.myLocationEnabled = FALSE;
Soper answered 1/9, 2015 at 8:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.