The main feature of the Sygic iOS SDK is mapping. The key concepts covered in this section include adding a map to an iOS application, changing the location displayed by the map, and modifying its properties. The primary component of the mapping API is the SYMapView, which is integrated with the Cocoa Touch framework as a UIView subclass. SYMapView represents the view to display map and various properties. The SYMapView is derived from UIView and part of iOS Cocoa Touch framework.

The first step to integrate a map into an application is to insert a SYMapView to your view controller. Do not forget to set your default camera position.

class MapViewController: UIViewController {
    func viewDidLoad () {
        let mapView = SYMapView()
        mapView.delegate = self
        mapView.frame = self.view.bounds // or use AutoLayout to setup map dimensions
        mapView.geocenter = SYGeoCoordinate(latitude: 48.147, longitude: 17.101878)
        view.addSubview(mapView)
    }
}

You do not see the roads, POIs, buildings etc? Yes, since the current version of the SDK works just with offline maps, you have to download them to see all these beautiful details. Please follow to Offline Maps section for more details!

The SYMapView class handles all user interactions in the form of touch gestures. More details about the supported gesture types can be found in the Map Gestures section.

Map Handling

Once the SYMapView is initialized, it can be manipulated and interacted in a variety of ways. Some key attributes of the SYMapView are its orientation, tilt, geographical center (geoCenter), and zoom level (zoom). These properties may be used to customize the SYMapView display.

Zoom Level
The size of the geographical area displayed by the map can be controlled by changing the zoom level. Current view zoom level <0,1>

mapView.zoom = 0.000124117648996820

Rotation
The rotation determines which cardinal direction corresponds with which screen direction of the SyMapView. The valid range is from 0 to 360 degrees. The default value of 0 orients the map so that true north is toward the top of the view. The following code shows how to set the orientation to south-up:

    mapView.rotation = 180
    mapView.rotation = 180;

    Tilt
    The tilt value represents the angle at which the map is viewed. By default, the map tilt value is 0. This provides a top-down two-dimensional view of the map. You can set a tilt value using the tilt property in SYMapView, but since the valid range of tilt values is dependent on the current zoom level, this tilt property is converted before it is used on screen.

    // set tilt for 2D to 0, for 3D to 60
    let tiltFor2D: SyAngle = 0
    let tiltFor3D: SYAngle = 60
    
    mapView.tilt = mapView.tiltFor2D
    2D tilt 3D tilt

    FPS Limitter
    In order to save battery, setFpsLimitMode method of SYMapView class enables you to set the maximum FPS performance of your App. There are 2 modes available:

    • SYFpsLimitModePerformance - Always try to run at maximum fps.
    • SYFpsLimitModeBalanced - Try to achieve smooth camera movement with minimum performance requirements.
    mapView.setFpsLimitMode(.balanced, withFpsLimit: 15.0)

    Animations
    The SYMapView supports some special animation settings to be used while changing properties, defined by the SYAnimation. Common properties for all animations are:

    • duration - Animation duration in seconds
    • completion - Animation completition block.
    • curve - Animation curve.

    Here are the available SYMapAnimationCurve types:

    • SYMapAnimationCurveLinear - A linear animation curve causes an animation to occur evenly over its duration.
    • SYMapAnimationCurveAccelerate - This curve causes the animation to accelerate.
    • SYMapAnimationCurveDecelerate - This curve causes the animation to slow down.
    • SYMapAnimationCurveAccelerateDecelerate - This curve causes the animation to accelerate first and decelerate at the end.
    • SYMapAnimationCurveBounce - This curve will toggle the animation to bounce.

    rotateView
    Provides a rotation of a selected View by offset in degrees.

    [mapView rotateView:addRotation withDuration:1.0 curve:SYMapAnimationCurveDecelerate completion:nil];

    dragView
    Drag current view camera by offset in screen points.

    [mapView dragView:ptMove withDuration:0.8 curve:SYMapAnimationCurveDecelerate completion:nil];

    zoomView
    Provides a zoom of the application to the wanted zoom scale.

    CGFloat fWantedScale = 1.0 + clamp(float(gr.velocity*0.1f), -0.3f, 2.0f);
    [mapView zoomView:fWantedScale withDuration:0.3 curve:SYMapAnimationCurveDecelerate completion:nil];

    animate
    Animation block containing properties changes. Animable properties are geoCenter, transformCenter, rotation, tilt, and zoom.

    CGFloat fWantedScale = 1.0 + clamp(float(gr.velocity*0.1f), -0.3f, 2.0f);
    [mapView animate:
                    ^{
                        mapView.tilt = fTargetTilt;
                        mapView.zoom = 3.0/50000.0;
                        mapView.rotation = 100;
                        mapView.geocenter = [[SYGeoCoordinate alloc] initWithLatitude:48.147 longitude:17.101878]];
                        mapView.transformCenter = CGPointMake(0.5, 0.3);
                    } withDuration:0.25 curve:SYMapAnimationCurveDecelerate completion:nil];

    Handling Map Inputs

    Sygic iOS SDK enables to handle all map inputs the application user makes. This is important to setting map markers or to choose the waypoints directly from the map. The following code shows, how to get GPS Coordinates or point in MapView from taping on a map.

    class MapViewController: UIViewController {
        let mapView: SYMapView
    
        func viewDidLoad() {
            setupGestureRecognizer()
        }
    
        func setupGestureRecognizer () {
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:)))
            mapView.addGestureRecognizer(tapGestureRecognizer)
        }
    
        func tapped (_ recognizer: UITapGestureRecognizer) {
            let point = recognizer.location(in: mapView)
            let coordinate = mapView.geoCoordinate(fromScreenPoint: point)
    
            // now handle the coordinate, as you wish
        }      
    }

    Map Schemes

    There are some map schemes available to offer your application users a choice among different kinds of map appearance. Currently we support day and night skin.

    // Set map scheme
    mapView.activeSkin = .day // or .night
    Day skin & Night skin

    Sygic SDK does not automatically switch map schemes during navigation mode. Before starting car or pedestrian navigation, be sure to save the current map scheme and switch to the appropriate navigation map scheme.

    Gestures

    The SYMapView class responds to a number of predefined touch gestures. The default behavior of the map for each gesture type may be used as-is, supplemented, or replaced entirely. The following table is a summary of the available gestures and their default behavior.

    Gesture Description Following gestures
    Rotate Rotate: Two-finger press, simultaneously orbit both fingers around the center point, lift Pinch, Spread, Move
    Zoom out Pinch: Two-finger press, move inwards, lift Spread, Rotate, Move
    Zoom in Spread: Two-finger press, move outwards, lift
    Move Swipe: One-finger press, move, lift/don't lift
    Tilt Tilt: Two fingers press, move up (increase the tilt angle) or move down (decrease the tilt angle)
    Short touch Short touch: One-finger press, lift 

    These are the basic camera settings, which are default turned on. If you want to edit them, change the "fly distance" etc, you can disable these gestures with SYMapView mapInteractionEnabled property.

    BOOL mapInteractionEnabled = NO;

    Objects and Interaction

    The Sygic Mobile SDK allows the addition of a variety of objects, each with a specific purpose, to a map view. The types of available object include map markers, routes, polylines, circles. To see all the objects check the SYMapObjectType API reference. Some objects are described in more detail below.

    The SYMapObject class provides a generic base class from which most types of specialized map object inherit. The following is a list of the important properties and methods in SYMapObject.

    • type - contains the type of the map object, such as marker, polyline, circle our route. For the full list, see the SYMapObject API reference.
    • zIndex - determines the objects stacking order, which controls how the object is displayed on the map relative to other objects that may overlap it. Objects with the highest value are placed at the top of the stacking order.
    • visible - determines whether or not the object is drawn when the map is rendered.

    In order to display the map object on the map, the object needs to be added to an SYMapView by calling addMapObject:.Following example shows how to display a finish marker on a map.

    SYMapMarker* markerFinish = [[SYMapMarker alloc] initWithCoordinate:coord icon:SYMapMarkerIconFinish];
    [self.mapMarkers addObject:markerFinish];
    [self.mapView addMapObject:markerFinish];

    SYMapCircle
    Enables you to draw a circle on the map at a fixed geographical location. You can customize you circle's color, radius, lineColor - see the SYMapCircle API reference for more information.

    Circle on the map

    SYMapPolyline
    Enables you can draw one or more connected line segments on the map. The segment vertices are specified by a series of SYGeoCoordinates. The visual appearance of the polyline can be customized. See the SYMapPolyline API reference for more information.

    Polyline on the map

    SYMapMarker

    With Sygic Mobile SDK you can display a icon at a fixed geographical position on the map.

    You can choose from these icons types:

    • Start
    • Via
    • Finish
    Marker on the map

    Each of these objects could be selected by either tapping on the map, which returns the objects from the mapView:didSelectObjects: callback method in SYMapViewDelegate, or by calling the objectsAtPoint: method in SYMapView.

    Offline Maps

    The Sygic iOS SDK is able to pre-load map data, allowing the use of maps, search, routing, and other features without an active data connection. Interfaces involved with providing offline maps functionality include SYMapLoader, SYMapLoaderDelegate and SYMapPackage.

    SYMapLoaderMapGroup
    SYMapLoaderMapGroup is a collection of map packages representing a particular region (continent). Following example shows how to load a list of available continents.

    {
        // Loading list of continents
        SYMapLoader.shared().delegate = self
        SYMapLoader.shared().getMapGroups()
    }

    SYMapLoaderMapPackage
    SYMapLoaderMapPackage represents a particular country. Map data packages can be selectively installed or uninstalled . Installing a package makes its data available for offline usage.

    Offline maps capabilities are enabled through the use of SYMapLoader and its associated classes. The SYMapLoader API provides a set of methods which allow manipulation of the map data stored on the device:

    • getMapPackages - To retrieve the current state of the map data on the device through a delegate callback.
    • installMapPackages: - To request the specified list of SYMapPackage to be installed.
    • uninstallMapPackages: - To request the specified list of SYMapPackage to be uninstalled.
    • checkForMapDataUpdate - To check whether a new map data version is available.
    • updateMapPackages - To perform a map data version update, if available.
    • performMapDataUpdate - To perform a map data version update, if available.
    • loadMapPackages - To load the installed map.
    • unloadMapPackages - To unload the installed map.
    • getMapInfo - To get additional map info, like country iso code.

    SYMapLoader is a singleton which must be obtained using the shared() method. The following code example shows basic SYMapLoader use. To load the maps, you have to choose exactly which one you want to download. They are not loaded all of them automatically.

    You have to list the MapGroup and the relevant MapPackages in a tableview to be able to choose which map you want to download.

    class MapsViewController: UIViewController, SYMapLoaderDelegate {
        var mapGroups: [SYMapLoaderMapGroup]()
        var mapPackages: [SYMapLoaderMapPackage]()
    
        func viewDidLoad() {
    // Loading list of continents
    SYMapLoader.shared().delegate = self
    SYMapLoader.shared().getMapGroups()
        }
    
     //get MapPackages
        func getMapPackages(for mapGroup: SYMapLoaderMapGroup) { // after tapping on a continent cell for example
            SYMapLoader.shared().getMapPackages(for: self.mapGroup)
        }
    
     //download and istall the selected mapPackage
        func downloadAndInstall(#mapPackage: SYMapLoaderMapPackage) { // after tapping on a country cell for example
            SYMapLoader.shared().installMapPackage(mapPackage)
        }
    
        // MARK: - SYMapLoaderDelegate
    
        func mapLoader(_ mapLoader: SYMapLoader, didGet groups: [SYMapLoaderMapGroup], from task: SYTask) {
            mapGroups = groups
            // reload the table with continents for example
        }
    
        func mapLoader(_ mapLoader: SYMapLoader, didGetMapPackagesFor mapGroup: SYMapLoaderMapGroup, packages: [SYMapLoaderMapPackage], from task: SYTask) {
            mapPackages = packages
            // reload the table with countries for example
        }
    
        func mapLoader(_ maploader: SYMapLoader, didInstallMapPackage package: SYMapLoaderMapPackage, result: SYPackageInstallResult, from task: SYTask) {
            SYMapLoader.shared().load([package]) // load it to make it visible on a map
        }
    }

    SYMapLoader operations are performed asynchronously. When available, the results of these operations are passed on to the map loader's delegate. The delegate is accessed via the SYMapLoader delegate property, and it must implement the SYMapLoaderDelegate protocol.

    To uninstall the downloaded map, use following code:

    func mapLoader(_ maploader: SYMapLoader, didUninstallMapPackage package: SYMapLoaderMapPackage, result: SYPackageInstallResult, from task: SYTask) {
           SYMapLoader.shared().load([package]) // load it to make it visible on a map
       }