2015-04-29 46 views
3

我知道这已经在几年前问过了,但所有涉及使用Google Maps API解决此问题的答案。我想知道是否有适当的方法来解决这个问题,因为iOS8已经出来,并且它为本地MapKit带来了许多改进。平滑的MKPolyline可以沿着路走

基本上我在道路上画了一条折线,它由许多中间点组成。

var locations = [CLLocation]() 
    for item in list { 
     locations.append(CLLocation(latitude: CLLocationDegrees(item["location"]["coordinate"]["x"].doubleValue), longitude: CLLocationDegrees(item["location"]["coordinate"]["y"].doubleValue))) 
    } 
    var coordinates = locations.map({(location: CLLocation!) -> CLLocationCoordinate2D in return location.coordinate}) 
    var polyline = MKPolyline(coordinates: &coordinates, count: locations.count) 
    mapView.addOverlay(polyline) 

一次有5到30点在地图上。当多段线连接它们时,我会得到或多或少的公平表示。问题是:它不会坚持到路上。

enter image description here

所以我越来越从时间“粗糙”边缘时间。即使如果我使用Google方向API,它也只限于8个方向点,并且基本上决定了如何从A点到B点,沿途绘制平滑的折线。此外,Directions API仅限于每24小时2500次使用。所有我需要做的是调整我目前的折线到最近的公路

非常感谢

+1

你从哪里得到目前的道路坐标('list')? iOS 8在7个月前发布,我不确定你指的是“它为本地MapKit带来了许多改进”。你知道在iOS 6中添加的MKDirectionsRequest类吗? – Anna

+0

@Anna''list''来自JSON响应。它是从A点到B点的中途巴士站的列表。因此,指定这些点对于遵循巴士路线至关重要。看起来像''MKDirectionsRequest''类似于谷歌方向,它自己计算从A点到B点的路线。它看起来不像它允许你自己指定中间点......除非我可以喂食它与所有30点,并执行它们之间的迷你方向计算:) – kernelpanic

+0

格式是无关紧要的。 JSON响应来自哪里?我的观点是:数据的来源是什么?如果该来源不使用与Apple相同的路线图,则无法避免(MapKit不能直接访问道路数据)。解决方法可能是您的建议(从每个坐标之间的MapKit获取路线)。但是,如果你的任何坐标不在MapKit公路上,你将会遇到同样的问题。 – Anna

回答

6

一些挖我设法找到了这个问题的答案后,虽然我真的不知道事情的影响就整体表现而言,这是否会让苹果开心,因为它发出了很多小小的MKDirectionsRequest。对我来说,30+分工作得很好。

var myRoute : MKRoute? 
    var directionsRequest = MKDirectionsRequest() 
    var placemarks = [MKMapItem]() 
    for item in list { 
     var placemark = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(item["location"]["coordinate"]["x"].doubleValue), longitude: CLLocationDegrees(item["location"]["coordinate"]["y"].doubleValue)), addressDictionary: nil) 
     placemarks.append(MKMapItem(placemark: placemark)) 
    } 
    directionsRequest.transportType = MKDirectionsTransportType.Automobile 
    for (k, item) in enumerate(placemarks) { 
     if k < (placemarks.count - 1) { 
      directionsRequest.setSource(item) 
      directionsRequest.setDestination(placemarks[k+1]) 
      var directions = MKDirections(request: directionsRequest) 
      directions.calculateDirectionsWithCompletionHandler { (response:MKDirectionsResponse!, error: NSError!) -> Void in 
       if error == nil { 
        self.myRoute = response.routes[0] as? MKRoute 
        self.mapView.addOverlay(self.myRoute?.polyline) 
       } 
      } 
     } 
    } 

特别感谢去Anna指向我在正确的方向。

enter image description here

+0

刚刚搜索整个互联网这样的答案。令人惊叹的是,非常感谢你!我找不到与问题有关的其他内容。 –

+0

与此唯一的问题是,苹果不会允许一次计算太多的方向。 –

1

我用递归块得到的路线72分。总是它的工作,直到50请求然后api把我错误。我猜50是一分钟的限制。 50后,我必须等待一段时间才能完成api工作。

我已经使用谷歌地图来绘制折线。所以下面的代码需要一个lat,long的数组并获取方向并将路径转换为一组点并在Google地图上呈现。

// Pathstr is |分开 //让我知道这是否需要改进。 //我正在使用递归块,因为错误计算可能会在计算方向时产生错误,因此使用递归进行顺序块。

NSArray *arr = [pathStr componentsSeparatedByString:@"|"]; 
    int pointsCount = (int)[arr count]; 
    NSMutableArray* pointsToUse = [[NSMutableArray alloc] init]; 

    for(NSString* locationStr in arr) 
    { 
     NSArray *locArr = [locationStr componentsSeparatedByString:@","]; 

     CLLocation *trackLocation = [[CLLocation alloc] initWithLatitude:[[locArr objectAtIndex:0] doubleValue] longitude:[[locArr objectAtIndex:1] doubleValue]]; 
     [pointsToUse addObject:trackLocation]; 
    } 


    // __block declaration of the block makes it possible to call the block from within itself 
    __block void (^urlFetchBlock)(); 


    __block int urlIndex = 0; 

    // the 'recursive' block 
    urlFetchBlock = [^void() { 

     MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init]; 
     NSLog(@"Index Value:::%d", urlIndex); 
     if(urlIndex < (pointsCount - 5)) 
     { 
      MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:((CLLocation*)pointsToUse[urlIndex]).coordinate addressDictionary:nil]; 
      MKMapItem *sourceMapItem = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark]; 
      [request setSource:sourceMapItem]; 

      MKPlacemark *destPlacemark = [[MKPlacemark alloc] initWithCoordinate:((CLLocation*)pointsToUse[urlIndex + 5]).coordinate addressDictionary:nil]; 
      MKMapItem *destMapItem = [[MKMapItem alloc] initWithPlacemark:destPlacemark]; 

      [request setDestination:destMapItem]; 
      //   NSLog(@"Source:%f ::%f, Dest: %f :: %f", ((CLLocation*)pointsToUse[i]).coordinate.latitude,((CLLocation*)pointsToUse[i]).coordinate.longitude, ((CLLocation*)pointsToUse[i+1]).coordinate.latitude, ((CLLocation*)pointsToUse[i+1]).coordinate.longitude); 

      [request setTransportType:MKDirectionsTransportTypeAny]; 

      request.requestsAlternateRoutes = NO; 

      MKDirections *directions = [[MKDirections alloc] initWithRequest:request]; 
      [directions calculateDirectionsWithCompletionHandler: 
      ^(MKDirectionsResponse *response, NSError *error) { 
       if (error) { 
        // Handle Error 
        NSLog(@"Error for this particular call"); 
        urlIndex +=5; 
        urlFetchBlock(); 
       } else { 

        for (MKRoute * route in response.routes) { 

         NSUInteger pointCount = route.polyline.pointCount; 

         NSLog(@"%lu", (unsigned long)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)]; 

         GMSMutablePath *path = [GMSMutablePath path]; 

         //this part just shows how to use the results... 
         for (int c=0; c < pointCount; c++) 
         { 
          [path addLatitude:routeCoordinates[c].latitude longitude:routeCoordinates[c].longitude]; 

         } 
         GMSPolyline *polyline = [GMSPolyline polylineWithPath: path]; 

         polyline.tappable = YES; 
         polyline.strokeWidth = width; 

         //      polyline.strokeColor = [UIColor redColor]; 
         polyline.geodesic = YES; 
         // polyline.title = @"Driving route"; 
         polyline.map = gMapView; 
         polyline.spans = @[[GMSStyleSpan spanWithColor:[UIColor redColor]]]; 
        } 
        urlIndex +=5; 
        urlFetchBlock(); 

       } 
      }]; 

     } 
    } copy]; 

    // initiate the url requests 
    urlFetchBlock();