iosobjective-cmapkitmapboxmkpolyline

How to get MKPolyline (Mapkit) using MBRoute (Mapbox)


I am developing two apps similar to Ola/Uber, a driver app and the other one is a rider app. The driver app uses mapbox for navigation while the rider app uses simple mapkit and google APIs. My problem starts when the driver re-routes while undergoing a ride and the rider app has to trace the driver's new path also. Right now the logic applied is as following: in didRerouteAlongRoute delegate of mapbox the driver app informs the server that it has re-routed along this particular MBRoute route. The server in turn informs and passes this information to the rider app. Problem is that this MBRoute data type is not usable at the rider end as it uses mapkit and not mapbox and I have to convert this information somehow so that I can make the same new route as the driver app using MKPolyline at the rider end. Any help is appreciated.

This api is being used at the rider end for making the route polyline originally: https://maps.googleapis.com/maps/api/directions/json


Solution

  • Finally I managed a way to accomodate the requirements. It includes the following 3 steps:

    1. At the driver app (using the mapbox framework), in the didRerouteAlongRoute delegate, create an array containing the new route's latitude/longitude dictionaries like this:

      -(void)navigationViewController:(MBNavigationViewController*)navigationViewController didRerouteAlongRoute:(MBRoute*)route{
      
      CLLocationCoordinate2D *routeCoordinates = malloc(route.coordinateCount *sizeof(CLLocationCoordinate2D));
      [route getCoordinates:routeCoordinates];
      
      NSMutableArray *routeArray = [NSMutableArray new];
      for (NSValue *value in route.coordinates) {
      CLLocationCoordinate2D coordinate;
      [value getValue:&coordinate];
      NSDictionary *coDic = @{@"latitude" : [NSNumber numberWithDouble: coordinate.latitude],
                              @"longitude": [NSNumber numberWithDouble: coordinate.longitude]};
      [routeArray addObject:coDic];
                                            }
      }
      
    2. Then send this new route's information to the server through an API after serialising this array (reRouteJSONString) as following:

      NSError *error;
      NSString *reRouteJSONString = @"";
      NSData *reRouteJSONData = [NSJSONSerialization dataWithJSONObject: routeArray options:NSJSONWritingPrettyPrinted error:&error];
      reRouteJSONString = [[NSString alloc] initWithData: reRouteJSONData encoding:NSUTF8StringEncoding] ;
      
    3. And now at the rider app, manipulate this information as following and form your new route polyline:

      -(void)makeReroutePolyline:(NSString*)serialisedString{
      
      MKMapView *mapView;
      mapView.delegate = self;
      
      NSError *jsonError;
      NSData *objectData = [serialisedString dataUsingEncoding:NSUTF8StringEncoding];
      NSArray *json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&jsonError];
      
      CLLocationCoordinate2D coordinates[json.count];
      for (NSInteger index = 0; index < json.count; index++) {
      CLLocationCoordinate2D coordinate = { [[json objectAtIndex:index][@"latitude"] doubleValue], [[json objectAtIndex:index][@"longitude"] doubleValue] };
      coordinates[index] = coordinate;
      }
      
      MKPolyline *routeLine;
      routeLine = [MKPolyline polylineWithCoordinates:coordinates count:json.count];
      [mapView addOverlay:routeLine];
      [mapView setVisibleMapRect:[routeLine boundingMapRect] edgePadding:UIEdgeInsetsZero animated:YES];
      
      }