Search code examples
iosgoogle-mapsgoogle-maps-sdk-iosios6.1ios6-maps

GoogleMap API Gives Wrong Coordinates for Direction between two Points


I am using GoogleMap API for showing draw direction between two points on GoogleMap.

i want to give support on iOS 6.1 so i use GoogleMap i know about iOS7 recover this.

using below code for parsing and get Steps for coordinates to draw polyline on Map:

NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=bharuch,gujarat&destination=vadodara,gujarat&sensor=false";

NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
     NSError* error;

NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

NSArray* latestRoutes = [json objectForKey:@"routes"];

NSMutableDictionary *legs=[[[latestRoutes objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0];

NSArray *steps=[legs objectForKey:@"steps"];

NSString *startLocation,*endLocation,*totalDistance,*totalDuration;
     CLLocationCoordinate2D startLoc,endLoc;
     startLocation = [legs  objectForKey:@"start_address"];
     endLocation = [legs objectForKey:@"end_address"];
     totalDistance = [[legs objectForKey:@"distance"] objectForKey:@"text"];
     totalDuration = [[legs objectForKey:@"duration"] objectForKey:@"text"];
     startLoc=CLLocationCoordinate2DMake([[[legs objectForKey:@"start_location"] objectForKey:@"lat"] doubleValue], [[[legs objectForKey:@"start_location"] objectForKey:@"lng"] doubleValue]);
     endLoc=CLLocationCoordinate2DMake([[[legs objectForKey:@"end_location"] objectForKey:@"lat"] doubleValue], [[[legs objectForKey:@"end_location"] objectForKey:@"lng"] doubleValue]);

     NSMutableDictionary *tempDict;
     if ([steps count]!=0) {
         GMSMutablePath *path = [GMSMutablePath path];
         for(int idx = 0; idx < [steps count]+2; idx++){

            CLLocationCoordinate2D workingCoordinate;

            if (idx==0) {

                workingCoordinate=startLoc;

                [path addCoordinate:workingCoordinate];

            }
            else if (idx==[steps count]+1){

                workingCoordinate=endLoc;

                [path addCoordinate:workingCoordinate];
            }
            else{

                workingCoordinate=CLLocationCoordinate2DMake([[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lat"] floatValue], [[[[steps objectAtIndex:idx-1] objectForKey:@"start_location"] objectForKey:@"lng"] floatValue]);

                [path addCoordinate:workingCoordinate];

            }
            tempDict = nil;
        }
        // create the polyline based on the array of points.

        GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];

        rectangle.strokeWidth=5.0;

        rectangle.map = mapView_;
    }

its gives only 24 steps means only 24 Coordinates for create point and draw Line on Map which is shown as below image:

after drawing line on map and zoom to few level

you can see that line is not on proper road so what can i do to solve this? i also want to show direction on map too.


Solution

  • Below answer is for smooth path between two location with help of @A Báo:

    -(void)viewDidLoad {
    
        // Create a GMSCameraPosition that tells the map to display the
    
        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:21.718472 longitude:73.030422 zoom:6];
        mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
        mapView_.delegate=self;
        mapView_.myLocationEnabled = YES;
        mapView_.settings.myLocationButton=YES;
        mapView_.settings.indoorPicker=NO;
        mapView_.settings.compassButton=YES;
    
        self.view = mapView_;
    
        NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=Bharuch,gujarat&destination=vadodara,gujarat&sensor=false";
    
        NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    
        NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
        NSError* error;
        NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    
        NSArray* latestRoutes = [json objectForKey:@"routes"];
    
        NSString *points=[[[latestRoutes objectAtIndex:0] objectForKey:@"overview_polyline"] objectForKey:@"points"];
    
        @try {
            // TODO: better parsing. Regular expression?
    
            NSArray *temp= [self decodePolyLine:[points mutableCopy]];
    
            GMSMutablePath *path = [GMSMutablePath path];
    
            for(int idx = 0; idx < [temp count]; idx++)
            {
               CLLocation *location=[temp objectAtIndex:idx];
    
                [path addCoordinate:location.coordinate];
    
            }
            // create the polyline based on the array of points.
    
            GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
    
            rectangle.strokeWidth=5.0;
    
            rectangle.map = mapView_;
    
        }
        @catch (NSException * e) {
            // TODO: show error
        }
    }
    
    -(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded {
      [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                  options:NSLiteralSearch
                                    range:NSMakeRange(0, [encoded length])];
      NSInteger len = [encoded length];
      NSInteger index = 0;
      NSMutableArray *array = [[NSMutableArray alloc] init] ;
      NSInteger lat=0;
      NSInteger lng=0;
      while (index < len) {
          NSInteger b;
          NSInteger shift = 0;
          NSInteger result = 0;
          do {
              b = [encoded characterAtIndex:index++] - 63;
              result |= (b & 0x1f) << shift;
              shift += 5;
          } while (b >= 0x20);
          NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
          lat += dlat;
          shift = 0;
          result = 0;
          do {
              b = [encoded characterAtIndex:index++] - 63;
              result |= (b & 0x1f) << shift;
              shift += 5;
          } while (b >= 0x20);
          NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
          lng += dlng;
          NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5] ;
          NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5] ;
          printf("[%f,", [latitude doubleValue]);
          printf("%f]", [longitude doubleValue]);
          CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] ;
          [array addObject:loc];
      }
    
      return array;
    }
    

    Screenshot of this code you can compare it with previous screenshot which i used in asking Question: enter image description here