3

我正在使用 GoogleMap API 来显示 GoogleMap 上两点之间的绘制方向。

我想在 iOS 6.1 上提供支持,所以我使用 GoogleMap 我知道 iOS7 来恢复这个。

使用以下代码进行解析并获取坐标的步骤以在地图上绘制折线:

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_;
    }

它只给出 24 个步骤意味着只有 24 个坐标用于在地图上创建点和绘制线,如下图所示:

在地图上画线并缩放到几级后

你可以看到这条线不在正确的道路上,所以我能做些什么来解决这个问题?我也想在地图上显示方向。

4

2 回答 2

9

下面的答案是在@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;
}

此代码的屏幕截图您可以将其与我在询问问题时使用的先前屏幕截图进行比较: 在此处输入图像描述

于 2014-03-03T05:11:17.647 回答
1

我确实将 GMSMarker 添加到步骤数组上的每个点,并且我确定使用步骤数组 start_location 和 end_location 不足以在地图中显示方向。这是我从您的代码中编辑的代码

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]);

NSMutableDictionary *stopLegs=[[[latestRoutes objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0];
endLoc=CLLocationCoordinate2DMake([[[stopLegs objectForKey:@"end_location"] objectForKey:@"lat"] doubleValue], [[[stopLegs objectForKey:@"end_location"] objectForKey:@"lng"] doubleValue]);

NSMutableDictionary *tempDict;

if ([steps count]!=0) {
    // add marker
    NSDictionary *step;
    for (int i= 0; i < steps.count; i++) {
        step = [steps objectAtIndex:i];
        NSDictionary *location = [step objectForKey:@"start_location"];
        double lat = [[location objectForKey:@"lat"] doubleValue];
        double lng = [[location objectForKey:@"lng"] doubleValue];
        GMSMarker *marker = [[GMSMarker alloc] init];
        marker.position = CLLocationCoordinate2DMake(lat, lng);
        marker.snippet = [NSString stringWithFormat:@"point (%d)", i+1];
        marker.map = mapView_;
    }
    NSDictionary *location = [step objectForKey:@"end_location"];
    double lat = [[location objectForKey:@"lat"] doubleValue];
    double lng = [[location objectForKey:@"lng"] doubleValue];
    GMSMarker *marker = [[GMSMarker alloc] init];
    marker.position = CLLocationCoordinate2DMake(lat, lng);
    marker.snippet = [NSString stringWithFormat:@"point (%d)", steps.count];
    marker.map = mapView_;

    // continue draw map
    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_;
}

您可以看到点 12 和点 13 之间的距离很远(60.2 公里)。但它只是一条路。我确实发现如果你想显示结果方向的近似(平滑)路径。您需要使用“overview_polyline”字段。overview_polyline:包含一个对象,该对象包含一个编码点数组,这些编码点表示结果方向的近似(平滑)路径。这个链接谷歌地图对你有帮助。因此,为您工作的是找到从“overview_polyline”解码数据以获得两点之间正确路径的方法。我绝对是解决您的问题的真正方法,因为我确实检查了在编码折线算法格式 此图像中解码“overview_polyline”的工具,我从解码中得到: 解码折线

要解码多边形字符串,您可以在此块http://objc.id.au/post/9245961184/mapkit-encoded-polylines

  • 继续,来自@jayraj mg 的代码 下面的答案是两个位置之间的平滑路径
-(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;
}

此代码的屏幕截图您可以将其与我在询问问题时使用的先前屏幕截图进行比较: 在此处输入图像描述

谢谢@jayraj mg

于 2014-02-28T10:56:21.887 回答