Finding Path/Route Between two points on MapKit in iPhone

空扰寡人 提交于 2019-11-26 07:35:56

问题


I am trying to find the path between two locations on Mapkit. All I have is two locations. Now I have to find the exact path between these points and draw a line between these points using MapKit. I have gone through several examples in which they are using .csv files. In that .csv file they have stored the latitude and longitude values of the full path and drawing line based on those values.

But here I am trying to draw a line without knowing the path. So is there any way to find the path dynamically and draw a line?


回答1:


Below is the code to finds path & draws line between two locations.

To implement below class:

_mapRecord = [[PSMapDirection alloc] initWithFrame:CGRectMake(0.0, 49.0, 320.0, 411.0)];
[self.view addSubview:_mapRecord];

MapDirection.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "RegexKitLite.h"

@interface MapDirection : UIView<MKMapViewDelegate> 
{    
    MKMapView* mapView;
    NSArray* routes;    
    BOOL isUpdatingRoutes;
}

-(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t;

@end

MapDirection.m

#import "MapDirection.h"

@interface MapDirection()
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) from to: (CLLocationCoordinate2D) to;
-(void) centerMap;

@end

- (id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame:frame];
    if (self != nil) 
    {
        mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        mapView.showsUserLocation = NO;
        [mapView setDelegate:self];
        [self addSubview:mapView];      
    }
    return self;
}

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

-(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.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr];
    NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
    //NSLog(@"api url: %@", apiUrl);
    NSError* error = nil;
    NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
    NSString *encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L];   
    return [self decodePolyLine:[encodedPoints mutableCopy]];
}

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

-(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t 
{   
    if(routes) 
    {
    [mapView removeAnnotations:[mapView annotations]];
    }

    [mapView addAnnotation:f];
    [mapView addAnnotation:t];

    routes = [self calculateRoutesFrom:f.coordinate to:t.coordinate];
    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;
    }
    MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
    [mapView addOverlay:polyLine];
    [self centerMap];
}

#pragma mark MKPolyline delegate functions
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay 
{
    MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
    polylineView.strokeColor = [UIColor purpleColor];
    polylineView.lineWidth = 5.0;
    return polylineView;
}

@end

Sample Map Route for starting points - "41.967659,-87.627869" and destination points - "41.574361,-91.083069"




回答2:


You can refer this code, it does exactly what you want.
EDIT: and this also




回答3:


I don't think you can do this locally. Implementing an algoritm for finding a path between two gps points requires a lot of input data (data from the maps) and you don't have this. Only a map provider can afford to implement such algoritm and expose an API for using it. I think Google have routing API, but I haven't played around with it...




回答4:


https://developers.google.com/maps/documentation/directions/

Note that the TOS say that you have to display the results on a Google map, so you'll have to disable the functionality on the next iOS release



来源:https://stackoverflow.com/questions/12002179/finding-path-route-between-two-points-on-mapkit-in-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!