Replace blue dot in GMSMapView with arrow - Swift

I am using google SDK for iOS8 (Swift) app. I want to replace the blue dot (my location) in the GMSMapView with an arrow that rotates according to the orientation of the smartphone. How can i do this?

EDIT:

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

enter image description here

1: the arrow is cut out and I can't see how to increase the area

2: The position of the arrow is not quite at my location I solve this problem by removing the "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 can these problems be solved?

+1


source to share


2 answers


If you are using the Google Maps iOS SDK, there seems to be no option to replace the default user icon. However, the default icon already has an arrow indicating the direction the user is traveling (just call mapView.myLocationEnabled = true

).

A workaround is to place the marker at the user's current position and change the image of the marker based on the title.

Sample code ( 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 the image depending on the degree coming from the method func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!)

.

You also need to add NSLocationAlwaysUsageDescription

and NSLocationWhenInUseUsageDescription

to your info.plist

file.

enter image description here

+4


source


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



mapView.myLocationEnabled = FALSE;

      

0


source







All Articles