2

I was looking for many code samples of how to draw a polyline on MKMapView like the second answer (from above) in this link. However, will that solution work on iOS 6 Apple maps? If not, can you provide a link to a sample code that draws the route on Apple maps?

Community
  • 1
  • 1
JAHelia
  • 6,934
  • 17
  • 74
  • 134

2 Answers2

1

Yes, it'll work.

Google maps and apple maps are different a little bit, could be some little inaccuracies. All the API's are almost same.

P.S. I use google routes in my app since iOS5 and haven't got any problems when updated app for iOS6.

Shmidt
  • 16,436
  • 18
  • 88
  • 136
  • but will it be against Google Map's terms of service ? – JAHelia Jan 04 '13 at 11:02
  • Terms say that you can't use it for navigation. Otherwise it's OK. – Shmidt Jan 04 '13 at 11:03
  • what about this: applications using Google Maps API Web Services must relate to the display of information on a Google Map. Use of the service in an application that doesn't display a Google map is prohibited. – JAHelia Jan 04 '13 at 11:03
  • Yes, we need to find other routes provider. – Shmidt Jan 04 '13 at 11:07
  • 1
    Or, we can use Google Maps in iOS6. I'm pretty sure I have seen framework for that on cocoacontrols.com – Shmidt Jan 04 '13 at 11:09
  • this opens a side (general) question: it's impossible to draw the route between two points (they maybe dynamically generated) without the need of an external api like google's one to provide the points (and thus you need an internet connection on the device), is that right ? – JAHelia Jan 04 '13 at 11:12
  • 1
    Yes, that's right. MapKit doesn't have internal tools for routing. – Shmidt Jan 04 '13 at 11:22
  • so an App that draws routes via parsing JSON values from google maps will work almost acuurately in ios 6+ also ? – nr5 Jan 08 '13 at 11:54
-1
-(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
  • 55
  • 1