在mapview iOS 6中绘制折线
Posted
技术标签:
【中文标题】在mapview iOS 6中绘制折线【英文标题】:Draw polyline in mapview iOS 6 【发布时间】:2013-04-23 10:42:30 【问题描述】:您好,我正在做一个应用程序,它必须显示带有路线的地图。我解析了一个 Json 以获得绘制折线的点。我在网上找到了一个代码来绘制这条折线。我在这个链接上找到的代码:http://iosguy.com/2012/05/22/tracing-routes-with-mapkit/
上面写着“创建 MKPolyline 注释”我试图在我的应用程序中导入它,但是我在创建坐标数组时遇到了问题。我的方法是这样的:
- (void)createMKpolylineAnnotation
NSInteger numberOfSteps = self.path.count;
CLLocationCoordinate2D *coords = malloc(sizeof(CLLocationCoordinate2D) * numberOfSteps);
for (NSInteger index = 0; index < numberOfSteps; index++)
CLLocation *location = [self.path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coords[index] = coordinate;
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coords count:numberOfSteps];
[self.mapView addOverlay:polyLine];
当我尝试查看 coords 的值仅在第一次设置时,这是为什么呢? 你能帮我解决这个问题还是我应该换一种模式?
我在这里发布处理地图视图的视图控制器的代码。
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MapViewController : UIViewController <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (nonatomic, strong) NSString *fromCity;
@property (nonatomic, strong) NSString *toCity;
- (IBAction)chooseKindOfMap:(id)sender;
@end
MapViewController.m
#import "MapViewController.h"
#import "AppDelegate.h"
#import "PlaceAnnotation.h"
@interface MapViewController ()
@property (nonatomic, strong)NSMutableArray *mapAnnotation;
@property (nonatomic) BOOL needUpdateRegion;
@property (nonatomic, strong)NSMutableArray *path;
@end
@implementation MapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
[self parseGoogleJsonToObtainPointsForPolyline];
[self.mapView setDelegate:self];
self.needUpdateRegion = YES;
//[self centerMap];
self.mapAnnotation = [[NSMutableArray alloc]initWithCapacity:2];
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
NSLog(@"%d", appDelegate.dataForMap.count);
NSArray* coords = [self getCoords:appDelegate.dataForMap];
NSLog(@"coords = %@", coords);
PlaceAnnotation *fromPlace = [[PlaceAnnotation alloc] initWithCoordinateAndName:coords[0] andLong:coords[1] andName:self.fromCity];
PlaceAnnotation *toPlace = [[PlaceAnnotation alloc] initWithCoordinateAndName:coords[2] andLong:coords[3] andName:self.toCity];
[self.mapAnnotation insertObject:fromPlace atIndex:0];
[self.mapAnnotation insertObject:toPlace atIndex:1];
NSLog(@"mapAnnotation.count: %d", self.mapAnnotation.count);
if (self.mapAnnotation)
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView addAnnotation:self.mapAnnotation[0]];
[self.mapView addAnnotation:self.mapAnnotation[1]];
NSLog(@"MapAnnotation = %@", self.mapView.annotations);
[self updateRegion];
[self createMKpolylineAnnotation];
//- (void)viewDidAppear:(BOOL)animated
// [super viewDidAppear:animated];
// if (self.needUpdateRegion) [self updateRegion];
//
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
pin.pinColor = MKPinAnnotationColorRed;
return pin;
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
MKPinAnnotationView *ulv = [mapView viewForAnnotation:mapView.userLocation];
ulv.hidden = YES;
- (NSArray*)getCoords:(NSDictionary*)data
NSArray *legs = [data objectForKey:@"legs"];
NSDictionary *firstZero = [legs objectAtIndex:0];
NSDictionary *endLocation = [firstZero objectForKey:@"end_location"];
NSDictionary *startLocation = [firstZero objectForKey:@"start_location"];
NSString *latFrom = [startLocation objectForKey:@"lat"];
NSString *lngFrom = [startLocation objectForKey:@"lng"];
NSString *latTo = [endLocation objectForKey:@"lat"];
NSString *lngTo = [endLocation objectForKey:@"lng"];
return @[latFrom,lngFrom,latTo,lngTo];
- (void)centerMap
MKCoordinateRegion region;
region.center.latitude = 41.178654;
region.center.longitude = 11.843262;
region.span.latitudeDelta = 11.070406;
region.span.longitudeDelta = 12.744629;
[self.mapView setRegion:region];
- (IBAction)chooseKindOfMap:(id)sender
if ([sender tag] == 0)
self.mapView.mapType = MKMapTypeStandard;
if ([sender tag] == 1)
self.mapView.mapType = MKMapTypeSatellite;
if ([sender tag] == 2)
self.mapView.mapType = MKMapTypeHybrid;
- (void)updateRegion
self.needUpdateRegion = NO;
CGRect boundingRect;
BOOL started = NO;
for (id <MKAnnotation> annotation in self.mapView.annotations)
CGRect annotationRect = CGRectMake(annotation.coordinate.latitude, annotation.coordinate.longitude, 0, 0);
if (!started)
started = YES;
boundingRect = annotationRect;
else
boundingRect = CGRectUnion(boundingRect, annotationRect);
if (started)
boundingRect = CGRectInset(boundingRect, -0.2, -0.2);
if ((boundingRect.size.width < 20) && (boundingRect.size.height < 20))
MKCoordinateRegion region;
region.center.latitude = boundingRect.origin.x + boundingRect.size.width / 2;
region.center.longitude = boundingRect.origin.y + boundingRect.size.height / 2;
region.span.latitudeDelta = boundingRect.size.width;
region.span.longitudeDelta = boundingRect.size.height;
[self.mapView setRegion:region animated:YES];
- (void)parseGoogleJsonToObtainPointsForPolyline
NSDictionary *polyline;
NSMutableArray *points = [[NSMutableArray alloc]init];;
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
NSArray *legs = [appDelegate.dataForMap objectForKey:@"legs"];
NSDictionary *firstZero =[legs objectAtIndex:0];
NSArray *steps = [firstZero objectForKey:@"steps"];
for (int i = 0; i < steps.count; i++)
polyline = [steps[i] objectForKey:@"polyline"];
[points addObject:polyline[@"points"]];
NSLog(@"POINTS = %@", polyline[@"points"]);
self.path = [self decodePolyLine:points[i]];
NSLog(@"path = %@", self.path);
-(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;
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor redColor];
polylineView.lineWidth = 1.0;
return polylineView;
- (void)createMKpolylineAnnotation
NSInteger numberOfSteps = self.path.count;
CLLocationCoordinate2D *coords = malloc(sizeof(CLLocationCoordinate2D) * numberOfSteps);
for (NSInteger index = 0; index < numberOfSteps; index++)
CLLocation *location = [self.path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coords[index] = coordinate;
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coords count:numberOfSteps];
[self.mapView addOverlay:polyLine];
@end
我使用 AppDelegate 来拥有 Json(我在另一个类中解析它)
【问题讨论】:
【参考方案1】:Here 是一个教程如何将折线添加到 mapView。希望这会有所帮助!
编辑:
很遗憾,上面提供的链接现已损坏,我无法找到所指的教程。
【讨论】:
【参考方案2】:简单,只需复制粘贴我的代码并修改一些变量
- (IBAction)traceRoute:(UIButton *)sender
double latDouble = 39.7540615;
double lngDouble = -8.8059587;
// double latDouble = [self.sheetDetail.data.locationLat doubleValue];
// double lngDouble = [self.sheetDetail.data.locationLng doubleValue];
CLLocationCoordinate2D c2D = CLLocationCoordinate2DMake(latDouble, lngDouble);
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:c2D addressDictionary:nil];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem setName:@"Mobile Edge"];
MKPlacemark *placemark2;
MKMapItem *mapItem2;
if(kIS_OS_8_OR_LATER)
placemark2 = [[MKPlacemark alloc] initWithCoordinate:_userLoc addressDictionary:nil];
mapItem2 = [[MKMapItem alloc] initWithPlacemark:placemark2];
[mapItem2 setName:@"Me"];
else
placemark2 = [[MKPlacemark alloc] initWithCoordinate:_mapView.userLocation.coordinate addressDictionary:nil];
mapItem2 = [[MKMapItem alloc] initWithPlacemark:placemark2];
[mapItem2 setName:@"Me"];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = mapItem2;
request.destination = mapItem;
request.requestsAlternateRoutes = NO;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error)
if (error)
// Handle error
[[NSNotificationCenter defaultCenter] postNotificationName:@"finishedLocationRoute" object:nil];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: NSLocalizedString(@"Route error title", nil)
message: NSLocalizedString(@"Route error", nil)
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
else
for (MKRoute *route in response.routes)
//MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];
//[self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint) andRoute:route];
[self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
//notifies parent menu
//[[NSNotificationCenter defaultCenter] postNotificationName:@"finishedLocationRoute" object:nil];
];
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay
if (![overlay isKindOfClass:[MKPolygon class]])
MKPolyline *route = overlay;
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
renderer.strokeColor = [UIColor blueColor];
renderer.lineWidth = 5.0;
return renderer;
else
return nil;
【讨论】:
以上是关于在mapview iOS 6中绘制折线的主要内容,如果未能解决你的问题,请参考以下文章
MapView 地图未在运行时呈现 Screenshot Attached