在多个位置之间绘制地图路径

Hir*_*iya 2 iphone ipad ios6.1

我是iphone开发的新手,我想绘制5个位置之间的路径我如何在谷歌地图中绘制路径.我想要从location1到location2,location2到location3,location3到location4和location4到location5的路径.

这是我的代码

- (void)viewDidLoad {
[super viewDidLoad];

NSDictionary *d1,*d2,*d3,*d4,*d5;

d1=[NSDictionary dictionaryWithObjectsAndKeys:@"location1",@"comments",@"1",@"id",@"23.02941395",@"latitude",@"72.54620655",@"longitude",nil];
d2=[NSDictionary dictionaryWithObjectsAndKeys:@"location2",@"comments",@"2",@"id",@"23.028359049999995",@"latitude",@"72.54537318333334",@"longitude",nil];
d3=[NSDictionary dictionaryWithObjectsAndKeys:@"location3",@"comments",@"3",@"id",@"23.029545",@"latitude",@"72.546036",@"longitude",nil];
d4=[NSDictionary dictionaryWithObjectsAndKeys:@"location4",@"comments",@"4",@"id",@"23.030050",@"latitude",@"72.546226",@"longitude",nil];
d5=[NSDictionary dictionaryWithObjectsAndKeys:@"location5",@"comments",@"5",@"id",@"23.030050",@"latitude",@"72.546022",@"longitude",nil];


self.reports=[NSArray arrayWithObjects:d1,d2,d3,d4,d5,nil];


for (NSDictionary *d in self.reports) {
    float latitude=[[d valueForKey:@"latitude"] floatValue];
    float longitude=[[d valueForKey:@"longitude"] floatValue];

    Place* home = [[[Place alloc] init] autorelease];
    home.name = [d valueForKey:@"comments"];
    home.latitude = latitude;
    home.longitude = longitude;

    PlaceMark *from = [[[PlaceMark alloc] initWithPlace:home] autorelease];             
    [mapView addAnnotation:from];

}


[self centerMap];

   }

   -(void) centerMap 

   {
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90;
CLLocationDegrees maxLon = -180;
CLLocationDegrees minLat = 120;
CLLocationDegrees minLon = 150;
NSMutableArray *temp=[NSArray arrayWithArray:self.reports];
NSLog(@"%@",temp);
for (int i=0; i<[temp count];i++) {
    Place* home = [[[Place alloc] init] autorelease];
    home.latitude = [[[temp objectAtIndex:i] valueForKey:@"latitude"]floatValue];
    home.longitude =[[[temp objectAtIndex:i] valueForKey:@"longitude"]floatValue];

    PlaceMark* from = [[[PlaceMark alloc] initWithPlace:home] autorelease];     

    CLLocation* currentLocation = (CLLocation*)from ;
    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];

    }
     - (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id  <MKAnnotation>)annotation
   {

if (annotation == mapView.userLocation) 
    return nil;

MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: @"asdf"];

if (pin == nil)
    pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: @"asdf"] autorelease];
else
    pin.annotation = annotation;
pin.userInteractionEnabled = YES;
UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
[disclosureButton setFrame:CGRectMake(0, 0, 30, 30)];

pin.rightCalloutAccessoryView = disclosureButton;
pin.pinColor = MKPinAnnotationColorRed;
//pin.animatesDrop = YES;
[pin setEnabled:YES];
[pin setCanShowCallout:YES];
return pin;

   }

    - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view  calloutAccessoryControlTapped:(UIControl *)control
    {
NSString *strTitle = [NSString stringWithFormat:@"%@",[view.annotation title]];
NSMutableDictionary *d;
NSMutableArray *temp=[NSArray arrayWithArray:self.reports];


for (int i = 0; i<[temp count]; i++)
{
    d = (NSMutableDictionary*)[temp objectAtIndex:i];
    NSString *strAddress = [NSString stringWithFormat:@"%@",[d valueForKey:@"comments"]];

    if([strAddress isEqualToString:strTitle]) {
        [self presentModalViewController:self.nxtDetailsVCtr animated:YES];
        [self.nxtDetailsVCtr.lblDetail setText:strAddress];     
        break;
    }


}
    }
Run Code Online (Sandbox Code Playgroud)

小智 6

您可以使用NVPlolineAnnotation在地图内绘制线条.这是源代码.


War*_*olf 5

框架需要

QuartzCore.framework
CoreLocation.framework
MapKit.framework

需要的文件

JSONKit.h
JSONKit.m

在ARC的情况下,在JSON的编译源中设置-fno-objc-arc.

在头文件中

__block IBOutlet MKMapView *__mapView;
NSArray* routes;

MKPointAnnotation *startLocation;
MKPointAnnotation *endLocation;

MKPolyline *polyLine;
Run Code Online (Sandbox Code Playgroud)

实现一段代码......

- (void)viewDidLoad
{
//    [__mapView setShowsUserLocation:YES];
    [__mapView setZoomEnabled:YES];
    [__mapView setScrollEnabled:YES];
    [__mapView setMapType:MKMapTypeStandard];
    [__mapView setDelegate:self];

    routes=[[NSArray alloc] init];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)drawPath:(id)sender {

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        //Background Thread
        [self showRouteFrom:startLocation to:endLocation];
        dispatch_async(dispatch_get_main_queue(), ^(void){
            //Run UI Updates

            if (polyLine) {
                [__mapView setVisibleMapRect:[polyLine boundingMapRect]];
                [__mapView addOverlay:polyLine];

                [self centerMap];
            }

            NSLog(@"drawing path completed");
        });
    });
}


-(void) showRouteFrom: (id<MKAnnotation>)source to:(id<MKAnnotation>)destination;
{
    if(routes)
    {
        [__mapView removeAnnotations:[__mapView annotations]];
    }

    [__mapView addAnnotation:source];
    [__mapView addAnnotation:destination];

    NSLog(@"source title is %@",source.title);
    NSLog(@"destination title is %@",destination.title);

    routes = [self calculateRoutesFrom:source.coordinate to:destination.coordinate];
    NSLog(@"routes are %@",routes);

    NSInteger numberOfSteps = routes.count;

    CLLocationCoordinate2D coordinates[numberOfSteps];
    for (NSInteger index = 0; index < numberOfSteps; index++)
    {
        CLLocation *location = [routes objectAtIndex:index];
        CLLocationCoordinate2D coordinate = location.coordinate;
        coordinates[index] = coordinate;
    }

    polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];

    NSLog(@"poly line to be added as ovelay is %@",polyLine);
}

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

    NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&sensor=false&avoid=highways&mode=",saddr,daddr];

    NSLog(@"Fired API %@",apiUrlStr);

    NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];

    NSError* error = nil;
    NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];

    NSDictionary *dic=[apiResponse objectFromJSONString];

    if (dic!=nil) {
        NSArray *routPoints=[[NSArray alloc] initWithArray:[dic valueForKey:@"routes"]];

        NSDictionary *polylineOverview=[[routPoints objectAtIndex:0] valueForKey:@"overview_polyline"];
        NSString *polylinePoints = [polylineOverview objectForKey:@"points"];
        return [self decodePolyLine:[polylinePoints mutableCopy]];
    }

    return nil;
}


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

#pragma mark- MKMapView delegate method

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
    polylineView.strokeColor = [UIColor purpleColor];
    polylineView.lineWidth = 5.0;

    NSLog(@"polyline in viewFor overlay: %@",polylineView);
    return polylineView;
}

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    NSLog(@"did update user location called ");
    MKCoordinateRegion region;

    region.span.latitudeDelta = .005;
    region.span.longitudeDelta = .005;
    region.center = userLocation.coordinate;

    [mapView setRegion:region animated:YES];
}

-(void) centerMap
{
    MKCoordinateRegion region;
    CLLocationDegrees maxLat = -90.0;
    CLLocationDegrees maxLon = -180.0;
    CLLocationDegrees minLat = 90.0;
    CLLocationDegrees minLon = 180.0;

    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.0;
    region.center.longitude    = (maxLon + minLon) / 2.0;
    region.span.latitudeDelta = 0.01;
    region.span.longitudeDelta = 0.01;

    region.span.latitudeDelta  = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat);
    region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon);
    [__mapView setRegion:region animated:YES];
}

#pragma mark-  UITextField delegate method

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    [self.view bringSubviewToFront:textField];

    CGRect rect=textField.frame;

    [[NSUserDefaults standardUserDefaults] setValue:NSStringFromCGRect(rect) forKey:@"textFieldRect"];

    rect.origin.y=self.view.frame.size.height-260;

    [UIView animateWithDuration:0.3 animations:^{
        [textField setFrame:rect];
    }];

    return YES;
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSString *rectStr=[[NSUserDefaults standardUserDefaults] valueForKey:@"textFieldRect"];
    NSArray *rectArray=[rectStr componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"{,} "]];

    CGRect rect;

    rect.origin.x=[[rectArray objectAtIndex:2] floatValue];
    rect.origin.y=[[rectArray objectAtIndex:4] floatValue];
    rect.size.width=[[rectArray objectAtIndex:8] floatValue];
    rect.size.height=[[rectArray objectAtIndex:10] floatValue];

    [UIView animateWithDuration:0.3 animations:^{
        [textField setFrame:rect];
    }];
    [textField resignFirstResponder];
    return YES;
}


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    NSDictionary *locationDic=[self getLatLongOfPlace:[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
    NSDictionary *latLongDic=[[[[[locationDic valueForKey:@"results"] objectAtIndex:0] valueForKey:@"geometry"]valueForKey:@"viewport"] valueForKey:@"northeast"];

    if (textField.tag==0) {
        startLocation=[[MKPointAnnotation alloc] init];
        [startLocation setCoordinate:CLLocationCoordinate2DMake([[latLongDic valueForKey:@"lat"] floatValue], [[latLongDic valueForKey:@"lng"] floatValue])];
        startLocation.title=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    }else{
        endLocation=[[MKPointAnnotation alloc] init];
        [endLocation setCoordinate:CLLocationCoordinate2DMake([[latLongDic valueForKey:@"lat"] floatValue], [[latLongDic valueForKey:@"lng"] floatValue])];
        endLocation.title=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    }

    NSLog(@"object at index is viewport %@",[[[[[locationDic valueForKey:@"results"] objectAtIndex:0] valueForKey:@"geometry"]valueForKey:@"viewport"] valueForKey:@"northeast"]);
}

#pragma mark Getting lat long from place name.

-(NSDictionary*)getLatLongOfPlace:(NSString*)place
{
    NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=true",place];

    NSLog(@"Fired URL:- %@",apiUrlStr);

    NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];

    NSError* error = nil;
    NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];

    NSDictionary *dic=[apiResponse objectFromJSONString];
    return dic;
}
Run Code Online (Sandbox Code Playgroud)

这是我制作的SampleCode

注意:--- 如果在viewDidLoad方法中,样本不适用于此jsut这一行

// [__ mapView setShowsUserLocation:YES];

截图

在此输入图像描述