在iPhone上的MapKit上找到两点之间的路径/路径

时间:2012-08-17 08:16:25

标签: iphone objective-c ios mapkit

我正在尝试在Mapkit上找到两个位置之间的路径。我只有两个地方。现在我必须找到这些点之间的确切路径,并使用MapKit在这些点之间画一条线。我已经通过几个他们使用.csv文件的例子。在该.csv文件中,他们根据这些值存储了完整路径和绘图线的纬度和经度值。

但是在这里我试图在不知道路径的情况下绘制一条线。那么有没有办法动态地找到路径并画一条线?

2 个答案:

答案 0 :(得分:13)

以下是查找路径和代码的代码。在两个地点之间画线。

要在下面的课程中实现:

_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

起点的样本地图路线 - “41.967659,-87.627869”和目的地点 - “41.574361,-91.083069

Map Route

答案 1 :(得分:7)

这里我可以在两点(位置)之间绘制方向。


  
    

首先从this链接下载GoogleMap sdk并集成到您的应用程序中。

  

现在需要API密钥,您可以在this链接上创建指定的指南。

以下是在两个位置之间的谷歌地图上绘制方向的代码。


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


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

NSError *error=nil;

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;

[request setURL:url];
[request setHTTPMethod:@"POST"];

NSURLResponse *response = nil;

NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: &error];

NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONWritingPrettyPrinted error:nil];

return [self decodePolyLine:[self parseResponse:dic]];
}
- (NSString *)parseResponse:(NSDictionary *)response {
NSArray *routes = [response objectForKey:@"routes"];
NSDictionary *route = [routes lastObject];
if (route) {
    NSString *overviewPolyline = [[route objectForKey:
                                   @"overview_polyline"] objectForKey:@"points"];
    return overviewPolyline;
}
return @"";
}
-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {
NSMutableString *encoded = [[NSMutableString alloc]
                            initWithCapacity:[encodedStr length]];
[encoded appendString:encodedStr];
[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];
    CLLocation *location = [[CLLocation alloc] initWithLatitude:
                            [latitude floatValue] longitude:[longitude floatValue]];
    [array addObject:location];
}
return array;
}
- (void)loadMapViewWithDirection {

float lat = 23.050671;
float lng = 72.541351;

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:lat
                                                        longitude:lng
                                                             zoom:10];

GMSMapView  * mapView = [GMSMapView mapWithFrame:CGRectMake(0, 75, 320, self.view.frame.size.height-kHeaderRect.size.height) camera:camera];
self.mapView.myLocationEnabled = YES;


float sourceLatitude = 23.050671;
float sourceLongitude = 72.541351;

float destLatitude = 23.036138;
float destLongitude = 72.603836;

GMSMarker *sourceMarker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude);
marker.map = self.mapView;

GMSMarker *destMarker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(destLatitude, destLongitude);
marker.map = self.mapView;

self.mapView.delegate = self;

   [self drawDirection:CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude) and:CLLocationCoordinate2DMake(destLatitude, destLongitude)];


[self.view addSubview:self.mapView];
}
- (void) drawDirection:(CLLocationCoordinate2D)source and:(CLLocationCoordinate2D) dest {


GMSPolyline *polyline = [[GMSPolyline alloc] init];
GMSMutablePath *path = [GMSMutablePath path];

NSArray * points = [self calculateRoutesFrom:source to:dest];

NSInteger numberOfSteps = points.count;

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

polyline.path = path;
polyline.strokeColor = [UIColor redColor];
polyline.strokeWidth = 2.f;
polyline.map = self.mapView;

// Copy the previous polyline, change its color, and mark it as geodesic.
polyline = [polyline copy];
polyline.strokeColor = [UIColor greenColor];
polyline.geodesic = YES;
polyline.map = self.mapView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadMapViewWithDirection];   
}