2016-04-23 6 views
0

Ich weiß, wie man das Snap-to-Road-API verwendet und die Antwort analysiert, es auf der Karte usw. zeigt. Allerdings hat die Snap to Road-API eine Beschränkung von 100 Koordinaten /anfordern.iOS - Snap To Road API mit mehr als 100 Koordinaten

Sagen wir, ich habe ein Array von 100+ Koordinaten und möchte, dass alle auf der Straße rasten.

Die Snap to Road API docs beschreiben eine Problemumgehung, wenn Sie mit mehr als 100 Koordinaten arbeiten, aber es ist Java-Code (ich denke) und ich verstehe es nicht wirklich.

Wie könnte ich das in Objective-C tun?

In meiner Implementierung rufe ich den Snap to Straßen api mehrere Male, indem Sie Bereiche von 100 Koordinaten aus meinem Array nehmen. Jedoch führt dies zu seltsamen Polylinien, wenn Unentschieden auf der Karte: enter image description here

Hier ist mein Code:

-(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 ist ein GMSMutablePath Ivar"

Antwort

0

Schließlich habe ich das Problem gefunden.

Wenn mehrere Anforderungen asynchron aufgerufen werden, werden nicht alle gleichzeitig ausgeführt. Da jeder von ihnen die Koordinaten zu demselben Pfad hinzufügt, werden Anfragen mit weniger Koordinaten beispielsweise früher beendet, obwohl sie später aufgerufen wurden. Dies führt dazu, dass die Koordinaten dem Pfad in der falschen Reihenfolge hinzugefügt werden.