How to rotate car marker image in Mapbox 3.6?

1.8k views Asked by At

I want to rotate marker image as per the route direction.I had implemented map using Map box SDK. Coordinates & directions are fetched through webservice. I tried imageForMarker but it didnt work. Implemetation is as follow

func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {

    let img = imageRotatedByDegrees(oldImage: UIImage(named: "car")!, deg: CGFloat(self.bearing))

    return MGLAnnotationImage(image: img, reuseIdentifier: "car")
}
func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage
{
    let size = oldImage.size

    UIGraphicsBeginImageContext(size)

    let bitmap: CGContext = UIGraphicsGetCurrentContext()!
    //Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: size.width / 2, y: size.height / 2)
    //Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat(Double.pi / 180)))
    //Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)

    let origin = CGPoint(x: -size.width / 2, y: -size.width / 2)

    bitmap.draw(oldImage.cgImage!, in: CGRect(origin: origin, size: size))

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
}
2

There are 2 answers

1
Nikolay Derkach On

Try using a custom reuse identifier, like this:

func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
    let annotation = annotation as! CustomMapAnnotation

    var annotationImage = mapView.dequeueReusableAnnotationImage(withIdentifier: annotation.id)

    if annotationImage == nil {
        var image = UIImage(named: "taxi")!

        if let heading = annotation.heading {
            image = image.imageRotatedByDegrees(degrees: heading)
        }
        image = image.withAlignmentRectInsets(UIEdgeInsets(top: 0, left: 0, bottom: image.size.height/2, right: 0))

        annotationImage = MGLAnnotationImage(image: image, reuseIdentifier: annotation.id)
    }

    return annotationImage
}
0
Jake T. On

It appears that the proper way to do this is using an MGLSymbolStyleLayer with your annotation, instead of adding the annotation directly and using the mapview delegate method: https://www.mapbox.com/ios-sdk/api/3.6.2/Classes/MGLSymbolStyleLayer.html#/c:objc(cs)MGLSymbolStyleLayer(py)iconRotation

There is an iconRotation property you can use, which takes the degrees.

This is unfortunate as my use case has several of the same image but different headers, so I've got to add a layer for each one.