Search code examples
iosswiftmapboxmapbox-ios

Mapbox marker personalisation


Does anybody know how I can create personalised mapbox markers like these using different annotation images. At the moment I can only figure out how to get one annotation into my project. Is there a way to add multiple annotations?

enter image description here

I have started here https://docs.mapbox.com/ios/maps/examples/annotation-view-image/ but am unsure as where to go next.

thanks


Solution

  • First you must add some point annotations to your map and then display image or view for each annotation. Annotation will be placed on coordinate, so you must create some random coordinates.

    You can add point annotations to the map like this:

    // Specify coordinates for our annotations.
    let coordinates = [
        CLLocationCoordinate2D(latitude: 0, longitude: 33),
        CLLocationCoordinate2D(latitude: 0, longitude: 66),
        CLLocationCoordinate2D(latitude: 0, longitude: 99)
    ]
    
    // Fill an array with point annotations and add it to the map.
    var pointAnnotations = [MGLPointAnnotation]()
    for coordinate in coordinates {
        let point = MGLPointAnnotation()
        point.coordinate = coordinate
        point.title = "\(coordinate.latitude), \(coordinate.longitude)"
        pointAnnotations.append(point)
    }
    
    mapView.addAnnotations(pointAnnotations)
    

    This code is taken from this example: Annotation views

    Then you must conform to MGLMapViewDelegate in order to call mapView(_:imageFor:) delegate method:

    // MGLMapViewDelegate method for adding static images to point annotations
    func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
        
        let annotationImage: MGLAnnotationImage
        let annotationImageCocktail = mapView.dequeueReusableAnnotationImage(withIdentifier: "cocktail")
        let annotationImageSushi = mapView.dequeueReusableAnnotationImage(withIdentifier: "sushi")
        
        switch annotation.coordinate.longitude {
        case 33:
            annotationImage = annotationImageCocktail ?? MGLAnnotationImage(image: UIImage(named: "cocktail")!, reuseIdentifier: "cocktail")
        case 66:
            annotationImage = annotationImageSushi ?? MGLAnnotationImage(image: UIImage(named: "sushi")!, reuseIdentifier: "sushi")
        case 99:
            annotationImage = annotationImageCocktail ??  MGLAnnotationImage(image: UIImage(named: "cocktail")!, reuseIdentifier: "cocktail")
        default:
            annotationImage = annotationImageSushi ?? MGLAnnotationImage(image: UIImage(named: "sushi")!, reuseIdentifier: "sushi")
        }
        
        return annotationImage
    }
    

    And here is the whole code:

    import Mapbox
    
    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Method for displaying map view
            let mapView = MGLMapView(frame: view.bounds)
            mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            mapView.styleURL = MGLStyle.darkStyleURL
            mapView.tintColor = .lightGray
            mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 66)
            mapView.zoomLevel = 2
            mapView.delegate = self
            view.addSubview(mapView)
    
            // Specify coordinates for our annotations.
            let coordinates = [
                CLLocationCoordinate2D(latitude: 0, longitude: 33),
                CLLocationCoordinate2D(latitude: 0, longitude: 66),
                CLLocationCoordinate2D(latitude: 0, longitude: 99)
            ]
    
            // Fill an array with point annotations and add it to the map.
            var pointAnnotations = [MGLPointAnnotation]()
            for coordinate in coordinates {
                let point = MGLPointAnnotation()
                point.coordinate = coordinate
                point.title = "\(coordinate.latitude), \(coordinate.longitude)"
                pointAnnotations.append(point)
            }
    
            mapView.addAnnotations(pointAnnotations)
        }
    
    }
    
    extension ViewController: MGLMapViewDelegate {
        
        // MGLMapViewDelegate method for adding static images to point annotations
        func mapView(_ mapView: MGLMapView, imageFor annotation: MGLAnnotation) -> MGLAnnotationImage? {
    
            let annotationImage: MGLAnnotationImage
            let annotationImageCocktail = mapView.dequeueReusableAnnotationImage(withIdentifier: "cocktail")
            let annotationImageSushi = mapView.dequeueReusableAnnotationImage(withIdentifier: "sushi")
    
            switch annotation.coordinate.longitude {
            case 33:
                annotationImage = annotationImageCocktail ?? MGLAnnotationImage(image: UIImage(named: "cocktail")!, reuseIdentifier: "cocktail")
            case 66:
                annotationImage = annotationImageSushi ?? MGLAnnotationImage(image: UIImage(named: "sushi")!, reuseIdentifier: "sushi")
            case 99:
                annotationImage = annotationImageCocktail ??  MGLAnnotationImage(image: UIImage(named: "cocktail")!, reuseIdentifier: "cocktail")
            default:
                annotationImage = annotationImageSushi ?? MGLAnnotationImage(image: UIImage(named: "sushi")!, reuseIdentifier: "sushi")
            }
    
            return annotationImage
        }
    }
    

    Of course you project must contation images named cocktail and sushi.