iphone開發之繪製地圖線路

地圖應用經常會涉及到線路的繪製問題,ios下可以使用MKMapView進行地圖開發,使用

MKOverlayView進行線路的繪製。

使用MKMapView添加MKMap.framework 和CoreLocation.framework並導入

MapKit.h頭文件。

新建一個基於視圖的工程,修改頭文件:

//
//  CloViewController.h
//  LocationMapTest
//
//  Created by Cloay on 12-6-18.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "CloMKAnnotation.h"
@interface CloViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate, UIActionSheetDelegate>{
    MKMapView *cloMapView;
    MKPolyline *routeLine;
}

@property (nonatomic, strong)  NSMutableArray *locations;
@end

修改實現代碼,在.m中添加如下代碼:

//
//  CloViewController.m
//  LocationMapTest
//
//  Created by Cloay on 12-6-18.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "CloViewController.h"

@interface CloViewController ()

@end

@implementation CloViewController
@synthesize locations;

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    cloMapView = [[MKMapView alloc] initWithFrame:[self.view bounds]];
    [cloMapView setMapType:MKMapTypeHybrid];  //設置地圖類型 地圖/衛星/兩者結合
    [cloMapView setShowsUserLocation:YES];      //顯示當前位置
    [cloMapView setDelegate:self];
    
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    //設置CLLocationManager實例委託和精度
    [locationManager setDelegate:self];
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    //設置距離篩選器,表示至少移動100米才通知委託更新
    [locationManager setDistanceFilter:100.f];
    //啓動更新請求
//    [locationManager startUpdatingLocation];
    
    locations = [[NSMutableArray alloc] init];
    float latitude = 39.8127;    //維度
    float longitude = 116.2967;  //經度
    for (int i = 0; i < 10; i++) {
        
        [locations addObject:[NSString stringWithFormat:@"%f,%f", latitude + 0.01*i, longitude + 0.01*i]];
//            NSLog(@"locations:%i",locations.count);
    }
    
    //地圖初始
    CLLocationCoordinate2D coords;
    coords.latitude = 39.9127;
    coords.longitude = 116.3967;
    float zoomlevel = 0.22;
    MKCoordinateRegion region = MKCoordinateRegionMake(coords, MKCoordinateSpanMake(zoomlevel, zoomlevel));
    [cloMapView setRegion:[cloMapView regionThatFits:region] animated:YES];
    
    [cloMapView addOverlay:[self makePolylineWithLocations:locations]];
    [self.view addSubview:cloMapView];
    
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    cloMapView = nil;
}

- (void)dealloc{
    [cloMapView release];
    [super dealloc];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}


//顯示菜單選項
- (void)showActionSheet :(id)sender{
	UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:nil 
															  delegate:self 
													 cancelButtonTitle:@"取消"
												destructiveButtonTitle:@"添加足跡"
													 otherButtonTitles:@"分享",@"詳細",@"刪除", nil];
    [actionSheet setDelegate:self];
	[actionSheet showInView:self.view];
	[actionSheet release];
}

//根據座標點生成線路
- (MKPolyline *)makePolylineWithLocations:(NSMutableArray *)newLocations{
    MKMapPoint *pointArray = malloc(sizeof(CLLocationCoordinate2D)* newLocations.count);
    for(int i = 0; i < newLocations.count; i++)  
    {  
        // break the string down even further to latitude and longitude fields.   
        NSString* currentPointString = [newLocations objectAtIndex:i];  
        NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];
        CLLocationDegrees latitude  = [[latLonArr objectAtIndex:0] doubleValue];  
        //        NSLog(@"latitude-> %f", latitude);
        CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];  
        CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);  
        //        NSLog(@"point-> %f", point.x);
        
        if (i == 0 || i == locations.count - 1) {//這裏只添加起點和終點作爲測試
            CloMKAnnotation *ann = [[CloMKAnnotation alloc] init];
			[ann setCoordinate:coordinate];
            [ann setTitle:[NSString stringWithFormat:@"緯度:%f", latitude]];
            [ann setSubtitle:[NSString stringWithFormat:@"經度:%f", longitude]];
			[cloMapView addAnnotation:ann];
        }
        pointArray[i] = MKMapPointForCoordinate(coordinate);
    }  
    
    routeLine = [MKPolyline polylineWithPoints:pointArray count:newLocations.count];
    free(pointArray);
    return routeLine;
}
#pragma mark-
#pragma CLLocationManager delegate method
//位置變化後會調用
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    //可在此處更新用戶位置信息
//    cloMapView.userLocation
    NSLog(@"oldLocation:%@", [oldLocation description]);
    NSLog(@"newLocation:%@", [newLocation description]);
    NSLog(@"distance:%@", [newLocation distanceFromLocation:oldLocation]);
    //位置變化添加新位置點
    [locations addObject:[NSString stringWithFormat:@"%f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude]];
    //刪除進線路,更新新軌跡
    [cloMapView removeOverlay:routeLine];
    [cloMapView addOverlay:[self makePolylineWithLocations:locations]];

}

#pragma MKMapView delegate method
//添加座標點大頭針
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    if (![annotation isKindOfClass:[CloMKAnnotation class]]) {
        return nil;
    }
    static NSString *identifier = @"Annotation";
    MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    if (pinAnnotationView == nil) {
        pinAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
    }
    pinAnnotationView.animatesDrop = YES;
    pinAnnotationView.canShowCallout = YES;
    pinAnnotationView.draggable = YES;
    UIButton *detailBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [detailBtn addTarget:self action:@selector(showActionSheet:) forControlEvents:UIControlEventTouchUpInside];
    pinAnnotationView.rightCalloutAccessoryView = detailBtn;
    
    return pinAnnotationView;
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState{
    
}

//畫線
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{
    NSLog(@"return overLayView...");
    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineView *routeLineView = [[[MKPolylineView alloc] initWithPolyline:routeLine] autorelease];
        routeLineView.strokeColor = [UIColor blueColor];
        routeLineView.lineWidth = 3;
        return routeLineView;
    }
    return nil;
}

@end

這裏主要是爲了測試,初始時 locations座標點自定義的,實際中是根據用戶的位置動態生成的一系列座標點。具體可在

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
函數中實現,如上代碼。

另外用戶的實時位置可用

cloMapView.userLocation = newLocation進行設置,然後顯示在地圖上。

效果圖如下:


有問題請留言,大家一起交流學習!
說明:轉載請註明出處!


發佈了55 篇原創文章 · 獲贊 84 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章