Getting started with routing

In this part we take a look at how a route from point A to point B on the map can be created. To do this we create two members for our example view: startPoint and endPoint.

We also need to know if we already have set a start point once we want to create a route. Finally, if we want to draw a route to another location, we have to remove the previous route. We must therefore store the ID of the routing line as well.

Swift

// ViewController.swift
class ViewController: HDMMapViewController, HDMMapViewControllerDelegate {
    var startPoint : HDMMapCoordinate?
    ...
}

Objective-C

// ViewController.m
@interface ViewController (){
    @private
    BOOL _startPointSet;
    HDMMapCoordinate _startPoint;
}
@end

To create a route, we need to determine start and end points on the map. In this tutorial, we will do this with two interaction methods: tappedAtCoordinate and longPressedAtCoordinate.

First lets take a look at how to set our start point for the route. This is quite simple, we just use the point provided by our longPressedAtCoordinate callback:

Swift

// ViewController.swift

func mapViewController(_ controller: HDMMapViewController, longPressedAt coordinate: HDMMapCoordinate, features: [HDMFeature]){
    print("Set routing start point!")
    self.startPoint = coordinate
}

Objective-C

// ViewController.m
- (void)mapViewController:(HDMMapViewController *)controller longPressedAtCoordinate:(HDMMapCoordinate)coordinate features:(NSArray<HDMFeature *> *)features {
    NSLog(@"Set routing start point!");
    _startPoint = coordinate;
}

Next, we must create the route. In this tutorial we just create a route from our start point (set by long-press) to the end point which we now set with the tappedAtCoordinate callback:

Swift

// ViewController.swift
func mapViewController(_ controller: HDMMapViewController, tappedAt coordinate: HDMMapCoordinate, features: [HDMFeature]) {

    guard let startPoint = self.startPoint else {return}
    //1

    guard let routing = controller.routing else {return}
    //2
    guard let route = routing.calculateRoute(from: startPoint, to: coordinate) else {return}

    self.mapView.navigate(withPath:route, using: HDMUserTrackingModeNone)
}

Objective-C

// ViewController.m
-(void)mapViewController:(HDMMapViewController *)controller tappedAtCoordinate:(HDMMapCoordinate)coordinate features:(NSArray *)featureRefs {
    if(_startPoint) {
        HDMLocation *start = [HDMLocation locationWithCoordinate:_startPoint];
        HDMLocation *dest = [HDMLocation locationWithCoordinate:coordinate];

        HDMRoutingPathFeature *routeInfo = [self.mapViewController.routing calculateRouteFromLocation:start toDestination:dest];
        [self.mapViewController.mapView navigateWithPath:routeInfo usingTrackingMode:HDMUserTrackingModeFollow];
    }
}

That’s it!

In order to create a route on the map, hold your finger down on a point, then tap somewhere else on the map. You should now see a routing line appear that will look like this:

../../_images/routing1.png

Routing instructions and localization

In case you also would like to provide step-by-step routing instructions to your users you can find them in returned HDMMapRouteInfo instance. More details are available here.

Swift

guard let route = routing.calculateRoute(from: startPoint, to: coordinate) else {return}
if let pointsDescriptions = route.routeInfo?.pointsDescription {
    for point in pointsDescriptions {
        print("\(point)")
    }
}

Objective-C

HDMRoutingPathFeature *route = [self.mapViewController.routing calculateRouteFromLocation:start toDestination:dest];
for (NSString *point in route.routeInfo.pointsDescription) {
    NSLog(@"%@", point);
};

To localize routing instructions DeepMap SKD uses standard iOS approach. Developer just need to add following keys to Localizable.strings:

Routing phrases

"hdm.routing.describer.PartFromat" = "%@. ";
"hdm.routing.describer.TurnLeft" = "Turn left";
"hdm.routing.describer.TurnRight" = "Turn right";
"hdm.routing.describer.GoUp" = "Go up to the floor %d";
"hdm.routing.describer.GoUp.Stair" = "Go up the stair to the floor %d";
"hdm.routing.describer.GoUp.Lift" = "Go up the lift to the floor %d";
"hdm.routing.describer.GoDown" = "Go down to the floor %d";
"hdm.routing.describer.GoDown.Stair" = "Go down the stair to the floor %d";
"hdm.routing.describer.GoDown.Lift" = "Go down the lift to the floor %d";
"hdm.routing.describer.Walk" = "Walk %.0f meters";
"hdm.routing.describer.WalkToStand" = "Walk %.0f meters to Stand %@";
"hdm.routing.describer.LeavingHall" = "Leaving %@";
"hdm.routing.describer.EnteringHall" = "Entering %@";

It’s also possible use another Bundle and Table Name for localization by setting corresponding properties:

Custom Bundle and Table

self.mapViewController.routing.localizationTableName = "Routing"
self.mapViewController.routing.localizationBundle = Bundle.main