2012-08-17 43 views
9

我正在嘗試在Mapkit上的兩個位置之間找到路徑。我只有兩個地點。現在我必須找到這些點之間的確切路徑,並使用MapKit在這些點之間繪製一條線。我已經通過幾個使用.csv文件的例子。在.csv文件中,他們已經存儲了基於這些值的完整路徑和繪製線的經度和緯度值。在iPhone上的MapKit上找到兩個點之間的路徑/路線

但我在這裏試圖畫出一條線,而不知道路徑。那麼有什麼方法可以動態地找到路徑並繪製一條線?

回答

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

+2

找到它。這個google API不能用來提供一步一步的導航。它也不能用於在任何不是Google的地圖上打印路線,所以這對iOS6版本不再有效。無論如何,這是最好的方法。我爲了相同的目的而使用了非常相似的東西。 –

+0

HI iApple ..它不適合我,它在這一行顯示錯誤NSString * encodedPoints = [apiResponse stringByMatching:@「points:\\\」([^ \\\「] *)\\\」「capture: 1L]; ...我的api網址:http://maps.google.com/maps?output=dragdir&saddr=41.967659,-87.627869&daddr=41.574361,-91.083069 –

+0

my apiResponse is {tooltipHtml:「(210 mi/3 hours 41分鐘)「,多義線:[{id:」route0「,points:」} cc_Gra {uOc | AnA | @JZGbA ?? dDrB ?? uApM ?? bAb @ ZZn @ hARl @ Hn @ hC'b @ Av @ '@'G ?? l @ E ?? PWhF {@JKtBC | Fo @ dHyA | FoBtBa @'EWzOGdASjBq @ na @ yRhPeHbA –

1

我不認爲你可以在本地做到這一點。在兩個GPS點之間尋找路徑的算法需要大量的輸入數據(來自地圖的數據),並且你沒有這個。只有地圖提供者才能負擔得起實現這種算法並公開使用它的API。我認爲Google已經路由API,但我還沒有與它玩耍了......

+0

謝謝@Graver .. –

2

您可以參考this code,它確實如您所願。
編輯:和this also

+1

是啊我看到兩個..他們使用谷歌API ..但我試圖做到這一點不使用谷歌API。有沒有可能? –

+0

我可以在哪裏獲得Google API文件? –

+0

你可以從http://code.google.com/p/gdata-objectivec-client/ – Ankur

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]; 
} 
+0

集成什麼? SDKDemo源文件或包 – chandru

+0

您需要添加GoogleMaps.framework和SDKDemos是演示應用程序以供參考。 – Dhaval

相關問題