2016-04-23 4 views
0

Я знаю, как использовать API привязки к дороге и проанализировать ответ, показать его на карте и т. Д. Однако API привязки к дороге имеет ограничение в 100 координат /запрос.iOS - API-интерфейс Snap To Road с более чем 100 координатами

Предположим, у меня есть массив из 100+ координат и вы хотите, чтобы все они привязались к дороге.

Привязка к дороге API docs описать обходной путь при работе с более чем 100 + координатами, однако это Java-код (я думаю), и я его действительно не понимаю.

Как я могу сделать это в Objective-C?

В моей реализации я вызываю привязку к дорогам api несколько раз, беря диапазоны из 100 координат из моего массива. Однако это приводит к странным ломаных, когда ничья на карте: enter image description here

Вот мой код:

-(void)getDirectionsFrom:(CLLocation*)startLocation to:(CLLocation*)endLocation{ 

    //Create placemarks from the passed in locations 
    MKPlacemark *start = [[MKPlacemark alloc] initWithCoordinate:locManager.location.coordinate addressDictionary:NULL]; 
    MKPlacemark *finsih = [[MKPlacemark alloc] initWithCoordinate:endLocation.coordinate addressDictionary:NULL]; 

    //Create direction request 
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc]init]; 
    [request setSource:[[MKMapItem alloc] initWithPlacemark:start]]; 
    [request setDestination:[[MKMapItem alloc] initWithPlacemark:finsih]]; 
    [request setTransportType:MKDirectionsTransportTypeAutomobile]; 

    //Calculate directions 
    MKDirections *direction = [[MKDirections alloc]initWithRequest:request]; 

    [direction calculateDirectionsWithCompletionHandler: ^(MKDirectionsResponse *response, NSError *error) { 

     if (error) { 
      NSLog(@"Error is %@",error); 
     } 

     else { 

      MKRoute *route = [response.routes firstObject]; 

      NSUInteger pointCount = route.polyline.pointCount; 

      //Allocate a C array to hold this many points/coordinates... 
      CLLocationCoordinate2D *routeCoordinates = malloc(pointCount * sizeof(CLLocationCoordinate2D)); 

      //Get the coordinates (all of them)... 
      [route.polyline getCoordinates:routeCoordinates range:NSMakeRange(0, pointCount)]; 

      NSMutableArray *locationsArray = [[NSMutableArray alloc] init]; 

      CLLocation *lastLocation = [[CLLocation alloc] init]; 


      //Call snap to road with 100 locations at a time 
      for (int start = 0; start < pointCount; start += 99) { 
       [locationsArray removeAllObjects]; 
       NSInteger length = MIN(99, pointCount-start); 
       if(start != 0){ 
        [locationsArray addObject:lastLocation]; 
       } 
       for(int i = start;i<start+length;i++){ 
        CLLocationCoordinate2D loc2D = routeCoordinates[i]; 
        CLLocation *location = [[CLLocation alloc] initWithLatitude:loc2D.latitude longitude:loc2D.longitude]; 
        [locationsArray addObject:location]; 
       } 

       lastLocation = [locationsArray lastObject]; 
       [self snapPathToRoad:locationsArray]; 
      } 

      //Free the memory used by the C array 
      free(routeCoordinates); 

     } 
    }]; 

} 


-(void)snapPathToRoad:(NSMutableArray*)passedInArray{ 

    //Create string to store coordinates in for the URL 
    NSString *tempcoordinatesForURL = @""; 

    //Append tempcoordinatesForURL string by the coordinates in the right format 
    for(int i = 0;i<[passedInArray count];i++){ 

     CLLocationCoordinate2D coordinates = [[passedInArray objectAtIndex:i] coordinate]; 

     NSString *coordinatesString = [NSString stringWithFormat:@"|%f,%f|",coordinates.latitude,coordinates.longitude]; 

     tempcoordinatesForURL = [tempcoordinatesForURL stringByAppendingString:coordinatesString]; 
    } 

    //Remove unnecessary charchters from tempcoordinatesForURL 
    NSString *coordinatesForURL = [[tempcoordinatesForURL substringToIndex:[tempcoordinatesForURL length]-1] stringByReplacingOccurrencesOfString:@"||" withString:@"|"]; 

    //Create url by removing last charachter from coordinatesForURL string 
    NSString *urlPath = [NSString stringWithFormat:@"https://roads.googleapis.com/v1/snapToRoads?path=%@&interpolate=true&key=AIzaSyDrtHA-AMiVVylUPcp46_Vf1eZJJFBwRCY",[coordinatesForURL substringFromIndex:1]]; 

    //Remove unsupproted charchters from urlPath and create an NSURL 
    NSString *escapedUrlPath = [urlPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 
    NSURL *url = [NSURL URLWithString:escapedUrlPath]; 

    //Create request 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

    //Send request to server 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 

     //If response, parse JSON 
     if(response){ 

      //Dictionary with the whole JSON file 
      NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 

      //Array of snapped points from the JSON 
      NSArray *snappedPoints = [result objectForKey:@"snappedPoints"]; 

      //Loop through the snapped points array and add each coordinate to the path 
      for (int i = 0; i<[snappedPoints count]; i++) { 
       NSDictionary *location = [[snappedPoints objectAtIndex:i] objectForKey:@"location"]; 

       double latitude = [[location objectForKey:@"latitude"] doubleValue]; 
       double longitude = [[location objectForKey:@"longitude"] doubleValue]; 

       [pathToDraw addCoordinate:CLLocationCoordinate2DMake(latitude, longitude)]; 

      } 

      //As this method is called multiple times, clear the previous polylines so only the final one will be visible on the map 
      [self.mapView clear]; 

      //Draw polyline with path 
      GMSPolyline *polyline = [GMSPolyline polylineWithPath:pathToDraw]; 
      polyline.map = self.mapView; 
      polyline.strokeColor = [UIColor darkGrayColor]; 
      polyline.strokeWidth = 6; 

     } 

     //If error, log it 
     else if(connectionError){ 
      NSLog(@"%@",connectionError); 
     } 

    }]; 

} 

"patToDraw является GMSMutablePath Ивар"

ответ

0

В конце концов, я нашел проблему.

Если несколько запросов называются асинхронно, не все из них будут завершены одновременно. Поскольку каждый из них добавляет координаты к одному и тому же пути, запросы с меньшими координатами, например, завершатся раньше, несмотря на то, что они были вызваны позже. Это приводит к тому, что координаты добавляются к пути в неправильном порядке.