【问题标题】:Drawing a route on Apple map (iOS 6+)在 Apple 地图上绘制路线 (iOS 6+)
【发布时间】:2013-01-04 10:48:37
【问题描述】:

我正在寻找许多关于如何在MKMapView 上绘制polyline 的代码示例,就像this link 中的第二个答案(从上面)一样。但是,该解决方案是否适用于 iOS 6 Apple 地图?如果没有,您能否提供一个在 Apple 地图上绘制路线的示例代码的链接?

【问题讨论】:

    标签: iphone objective-c ios mkmapview ios6-maps


    【解决方案1】:

    是的,它会起作用的。

    谷歌地图和苹果地图略有不同,可能有一些不准确的地方。 所有的 API 几乎都是一样的。

    附:我从 iOS5 开始在我的应用中使用谷歌路由,并且在为 iOS6 更新应用时没有遇到任何问题。

    【讨论】:

    • 但这会违反谷歌地图的服务条款吗?
    • 条款说你不能用它来导航。否则没关系。
    • 这是怎么回事:使用 Google Maps API Web Services 的应用程序必须与 Google Map 上的信息显示相关。禁止在不显示 Google 地图的应用程序中使用该服务。
    • 或者,我们可以在iOS6中使用谷歌地图。我很确定我在 cocoacontrols.com 上看到过框架
    • 是的,没错。 MapKit 没有用于路由的内部工具。
    【解决方案2】:
    -(void)load_mapView{
    
        Place* home = [[[Place alloc] init] autorelease];
        home.name = strAdd;
        CLLocationCoordinate2D loc=[self geoCodeUsingAddress:strAdd Status:1];
    
        home.latitude =loc.latitude;
        home.longitude =loc.longitude;
    
        Place* office = [[[Place alloc] init] autorelease];
        office.name = endAdd;
    
        CLLocationCoordinate2D  loc2=[self geoCodeUsingAddress:endAdd Status:2];;
        office.latitude = loc2.latitude;
        office.longitude = loc2.longitude;
    
    
       //*******
    
        routeView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, mapView.frame.size.width, mapView.frame.size.height)];
        routeView.userInteractionEnabled = NO;
        [mapView addSubview:routeView];
    
        lineColor = [UIColor colorWithWhite:0.2 alpha:0.5];
    
    
    
    
    
    
        [self showRouteFrom:home to:office];
        [activityIndicator stopAnimating];
    }
    
    
    
    - (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address Status:(NSInteger )sts
    {
        double latitude = 0, longitude = 0;
        NSString *esc_addr =  [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];
        NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
        if (result) {
            NSScanner *scanner = [NSScanner scannerWithString:result];
            if ([scanner scanUpToString:@"\"lat\" :" intoString:nil] && [scanner scanString:@"\"lat\" :" intoString:nil]) {
                [scanner scanDouble:&latitude];
                if ([scanner scanUpToString:@"\"lng\" :" intoString:nil] && [scanner scanString:@"\"lng\" :" intoString:nil]) {
                    [scanner scanDouble:&longitude];
                }
            }
        }
    
        CLLocationCoordinate2D center;
        center.latitude = latitude;
        center.longitude = longitude;
        return center;
    }
    
    
    -(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] autorelease];
        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] autorelease];
            NSNumber *longitude = [[[NSNumber alloc] initWithFloat:lng * 1e-5] autorelease];
            //                  printf("[%f,", [latitude doubleValue]);
            //                  printf("%f]", [longitude doubleValue]);
            CLLocation *loc = [[[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] autorelease];
            [array addObject:loc];
        }
    
        return array;
    }
    
    -(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
        NSString* saddr = [NSString stringWithFormat:@"%f,%f", f.latitude, f.longitude];
        NSString* daddr = [NSString stringWithFormat:@"%f,%f", t.latitude, t.longitude];
    
    
        Reachability *reachability = [Reachability reachabilityForInternetConnection];
        NetworkStatus internetStatus = [reachability currentReachabilityStatus];
        if (internetStatus != NotReachable){
    
    
        NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr];
        NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
        //  NSLog(@"api url: %@", apiUrl);
        NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl];
        NSString* encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L];
        //    NSLog(@"encodedPoints.....%@",encodedPoints);
        //    NSLog(@"self decodePolyLine:[encodedPoints mutableCopy].....%@",[self decodePolyLine:[encodedPoints mutableCopy]]);
    
         NSLog(@"return %@ ",[encodedPoints mutableCopy]);
    
        return [self decodePolyLine:[encodedPoints mutableCopy]];
        }else{
    
    
    
            [activityIndicator stopAnimating];
            UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"Oops!" message:@"Railway server is either busy or not responding at the moment. Try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
    
            return 0;
        }
    
    
    }
    
    -(void) centerMap {
        MKCoordinateRegion region;
    
        CLLocationDegrees maxLat = -90;
        CLLocationDegrees maxLon = -180;
        CLLocationDegrees minLat = 90;
        CLLocationDegrees minLon = 180;
        for(int idx = 0; idx < routes.count; idx++)
        {
            CLLocation* currentLocation = [routes objectAtIndex:idx];
            if(currentLocation.coordinate.latitude > maxLat)
                maxLat = currentLocation.coordinate.latitude;
            if(currentLocation.coordinate.latitude < minLat)
                minLat = currentLocation.coordinate.latitude;
            if(currentLocation.coordinate.longitude > maxLon)
                maxLon = currentLocation.coordinate.longitude;
            if(currentLocation.coordinate.longitude < minLon)
                minLon = currentLocation.coordinate.longitude;
        }
        region.center.latitude     = (maxLat + minLat) / 2;
        region.center.longitude    = (maxLon + minLon) / 2;
        region.span.latitudeDelta  = maxLat - minLat;
        region.span.longitudeDelta = maxLon - minLon;
    
        [mapView setRegion:region animated:YES];
    }
    
    -(void) showRouteFrom: (Place*) f to:(Place*) t {
        if(routes) {
            [mapView removeAnnotations:[mapView annotations]];
            [routes release];
        }
        PlaceMark* from = [[[PlaceMark alloc] initWithPlace:f] autorelease];
        PlaceMark* to = [[[PlaceMark alloc] initWithPlace:t] autorelease];
        [mapView addAnnotation:from];
        [mapView addAnnotation:to];
    
    
        Reachability *reachability = [Reachability reachabilityForInternetConnection];
        NetworkStatus internetStatus = [reachability currentReachabilityStatus];
        if (internetStatus != NotReachable){
    
        routes = [[self calculateRoutesFrom:from.coordinate to:to.coordinate] retain];
        [self drawRoute];
        [self centerMap];
    
        }else{
            [activityIndicator stopAnimating];
            UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"Oops!" message:@"Railway server is either busy or not responding at the moment. Try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
    }
    
    - (void)drawRoute
    {
        int numPoints = [routes count];
        if (numPoints > 1)
        {
            CLLocationCoordinate2D* coords = malloc(numPoints * sizeof(CLLocationCoordinate2D));
            for (int i = 0; i < numPoints; i++)
            {
                CLLocation* current = [routes objectAtIndex:i];
                coords[i] = current.coordinate;
            }
    
            objPolyline = [MKPolyline polylineWithCoordinates:coords count:numPoints];
    
            free(coords);
    
            [mapView addOverlay:objPolyline];
            [mapView setNeedsDisplay];
        }
    }
    
    
    - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
    {
        MKPolylineView *thePolylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
        thePolylineView.strokeColor =  [UIColor colorWithRed:((float) 204.0 / 255.0f)green:((float) 7.0 / 255.0f)blue:((float) 40.0 / 255.0f)alpha:1.0f]; // <-- So important stuff here
        thePolylineView.lineWidth = 5.0;
        return thePolylineView;
    }
    

    【讨论】:

    • 你能解释一下发生了什么吗?
    • @mahendra,我不打算“建议删除”这个答案,但是请(正如 Rahil 建议的那样)添加一些解释。
    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2016-10-29
    相关资源
    最近更新 更多