MapQuest iOS SDK

The MapQuest Maps SDK for iOS provides two different ways to draw a polyline or polygon. You can simply add them on top of the map as annotations or as a more performant option as a layer within the map.

Annotations

Put a Polyline on the Map

iOS with Map and Polyline
@import Mapbox;
@import MapQuestMaps;

@interface ViewController() <MGLMapViewDelegate>

@property (nonatomic, weak) IBOutlet MQMapView *mapView;

@end

@implementation ViewController

- (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {

    //create polyline, add it to the map, then center on it using showAnnotations
    CLLocationCoordinate2D coordinates[] = {
        CLLocationCoordinate2DMake( 39.74335, -105.01135),
        CLLocationCoordinate2DMake( 39.7468, -105.00709),
        CLLocationCoordinate2DMake(39.74391, -105.00794),
        CLLocationCoordinate2DMake(39.7425, -105.0047),
        CLLocationCoordinate2DMake(39.74634, -105.00478),
        CLLocationCoordinate2DMake(39.74734, -104.99984)
    };
    NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
    MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coordinates count:numberOfCoordinates];
    [self.mapView addAnnotation:polyline];
    [self.mapView showAnnotations:@[polyline] animated:YES];
    
}

@end
import MapQuestMaps
import Mapbox

class ViewController: UIViewController, MGLMapViewDelegate, UIActionSheetDelegate {

    @IBOutlet fileprivate weak var mapView: MQMapView?

    func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {

        //create polyline, add it to the map, then center on it using showAnnotations
        var coordinates = [
            CLLocationCoordinate2DMake(39.744465080845458,-105.02038957961648),
            CLLocationCoordinate2DMake(39.744460864711129,-105.01981090977684),
            CLLocationCoordinate2DMake(39.744379574636383,-105.01970518778262),
            CLLocationCoordinate2DMake(39.743502042120781,-105.01970874744497),
            CLLocationCoordinate2DMake(39.743419794549339,-105.01977839958302),
            CLLocationCoordinate2DMake(39.74341214360723,-105.02038412442006),
            CLLocationCoordinate2DMake(39.74349726029007,-105.02049233399056),
            CLLocationCoordinate2DMake(39.744393745651706,-105.0204836274754)
        ]

        let polygon = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
        mapView?.addAnnotation(polygon)
        mapView?.showAnnotations([polygon], animated: true)
    }
}

Put a Polygon on the Map

iOS with Map and Polygon
//create polyline, add it to the map, then center on it using showAnnotations
CLLocationCoordinate2D coordinates[] = {
    CLLocationCoordinate2DMake(39.744465080845458,-105.02038957961648),
    CLLocationCoordinate2DMake(39.744460864711129,-105.01981090977684),
    CLLocationCoordinate2DMake(39.744379574636383,-105.01970518778262),
    CLLocationCoordinate2DMake(39.743502042120781,-105.01970874744497),
    CLLocationCoordinate2DMake(39.743419794549339,-105.01977839958302),
    CLLocationCoordinate2DMake(39.74341214360723,-105.02038412442006),
    CLLocationCoordinate2DMake(39.74349726029007,-105.02049233399056),
    CLLocationCoordinate2DMake(39.744393745651706,-105.0204836274754)
};
NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
MGLPolygon *polygon  = [MGLPolygon polygonWithCoordinates:coordinates count:numberOfCoordinates];
[self.mapView addAnnotation:polygon];

//create polyline, add it to the map, then center on it using showAnnotations
var coordinates = [
    CLLocationCoordinate2DMake(39.744465080845458,-105.02038957961648),
    CLLocationCoordinate2DMake(39.744460864711129,-105.01981090977684),
    CLLocationCoordinate2DMake(39.744379574636383,-105.01970518778262),
    CLLocationCoordinate2DMake(39.743502042120781,-105.01970874744497),
    CLLocationCoordinate2DMake(39.743419794549339,-105.01977839958302),
    CLLocationCoordinate2DMake(39.74341214360723,-105.02038412442006),
    CLLocationCoordinate2DMake(39.74349726029007,-105.02049233399056),
    CLLocationCoordinate2DMake(39.744393745651706,-105.0204836274754)
]

let polygon = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
mapView?.addAnnotation(polygon)
mapView?.showAnnotations([polygon], animated: false)
mapView?.setZoomLevel(15, animated: true)

Layer Based Polylines and Polygons

While sources hold the data, layers are used to style and display the information. Several layer types are offered depending on your source geometry. Except for layers of the background type, each layer needs to refer to a source. You can optionally filter features and then define how those features are styled. Each layer offers a setProperties API which can be used to style the layer in many different ways. Note that instead of creating different layers depending on certain cases inside your source data, it's recommended to use data-driven styling to reduce the number of layers that the map needs to render.

Make sure to re-add custom layer in the event when map style is changed. This can be captured by overriding the method func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle)

@import Mapbox;
@import MapQuestMaps;

static NSString *polylineLayerIdentifier = @"polyline";

@interface ViewController() 

@property (nonatomic, weak) IBOutlet MQMapView *mapView;

//flag to make sure we add layer annotations when we change styles
@property (nonatomic, assign) BOOL showingPolylineLayer;

@end

@implementation ViewController

- (void)addLayerPolyline {
    self.showingPolylineLayer = YES;

    if ([self.mapView.style layerWithIdentifier:polylineLayerIdentifier]) {
        return;
    }
    
    CLLocationCoordinate2D coordinates[] = {
        CLLocationCoordinate2DMake( 39.74335, -105.01135),
        CLLocationCoordinate2DMake( 39.7468, -105.00709),
        CLLocationCoordinate2DMake(39.74391, -105.00794),
        CLLocationCoordinate2DMake(39.7425, -105.0047),
        CLLocationCoordinate2DMake(39.74634, -105.00478),
        CLLocationCoordinate2DMake(39.74734, -104.99984)
    };
    
    NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
    //create polyline with coordinate array
    MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coordinates count:numberOfCoordinates];
    
    //create a shape source with the polyline
    MGLSource *source = [[MGLShapeSource alloc] initWithIdentifier:polylineLayerIdentifier shape:polyline options:nil];
    [self.mapView.style addSource:source];
    
    // Create new layer for the line.
    MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:polylineLayerIdentifier source:source];
    
    // Set the line join and cap to a rounded end.
    layer.lineJoin = [NSExpression expressionForConstantValue:[NSValue valueWithMGLLineCap:MGLLineCapRound]];
    
    // Set the line color to a constant blue color.
    layer.lineColor = [NSExpression expressionForConstantValue:[UIColor greenColor]];
    
    // Use `NSExpression` to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. The `interpolationBase` parameter allows the values to interpolate along an exponential curve
    layer.lineWidth = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
                       @{@14: @2, @18: @20}];
    
    //add layer to map's style
    [self.mapView.style addLayer:layer];

        //move the camera to the area where you are adding polyline with animation
    MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake( 39.74335, -105.01135) fromDistance:1000 pitch:65 heading:0];
    [self.mapView flyToCamera:camera withDuration:1.0 completionHandler:nil];
        
}

//if you change style to show different kind of map types, you will have to add polyline error again.
-(void) mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
    if (self.showingPolylineLayer) {
        [self addLayerPolyline];
    }
}

@end
class ViewController: UIViewController, MGLMapViewDelegate {
    let polylineLayerIdentifier:String = "polyline"
    var shouldShowPolyline:Bool = false

    fileprivate func addLayerPolyline() {

        shouldShowPolyline = true
        if mapView?.style?.layer(withIdentifier: polylineLayerIdentifier) != nil {
            return
        }

        //create polyline, add it to the map, then center on it using showAnnotations
        let coordinates = [
            CLLocationCoordinate2D(latitude: 39.74335, longitude: -105.01135),
            CLLocationCoordinate2D(latitude: 39.7468, longitude: -105.00709),
            CLLocationCoordinate2D(latitude: 39.74391, longitude: -105.00794),
            CLLocationCoordinate2D(latitude: 39.7425, longitude: -105.0047),
            CLLocationCoordinate2D(latitude: 39.74634, longitude: -105.00478),
            CLLocationCoordinate2D(latitude: 39.74734, longitude: -104.99984)
        ]
        
        // MGLMapView.style is optional, so you must guard against it not being set.
        guard let style = self.mapView?.style else { return }
        
        let shapeFromGeoJSON = MGLPolyline(coordinates: coordinates, count: UInt(coordinates.count))
        let source = MGLShapeSource(identifier:self.polylineLayerIdentifier, shape: shapeFromGeoJSON, options: nil)
        style.addSource(source)
        
        // Create new layer for the line.
        let layer = MGLLineStyleLayer(identifier:self.polylineLayerIdentifier, source: source)
        
        // Set the line join and cap to a rounded end.
        layer.lineJoin = NSExpression(forConstantValue: "round")
        layer.lineCap = NSExpression(forConstantValue: "round")
        // Set the line color to a constant blue color.
        layer.lineColor = NSExpression(forConstantValue: UIColor(red: 59/255, green:178/255, blue:208/255, alpha:1))
        // Use `NSExpression` to smoothly adjust the line width from 2pt to 20pt between zoom levels 14 and 18. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
        layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
                                       [14: 2, 18: 20])
        style.addLayer(layer)

        //move the camera to where anotation is added
        let camera:MGLMapCamera = MGLMapCamera(lookingAtCenter:CLLocationCoordinate2D(latitude: 39.74391, longitude: -105.00794), fromDistance: 1000, pitch: 65, heading: 0)
        
        mapView?.fly(to: camera, completionHandler: {})
    }

    //capture event when style was loaded and show layer polyline again
    func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
        if shouldShowPolyline {
            addLayerPolyline()
        }
    }
}