我正在尝试使用叠加层在 MKMapView 上绘制路线。这是我的代码:
创建视图(在按下按钮时调用):
NSArray *route = [UCGeoConverter generateCoordinatesFromKML:self.kmlResponse];
if (!self.routeView) {
NSLog(@"create route");
self.routeView = [[UCRouteView alloc] initWithRoute:route mapView:self.mapview];
[self.mapview addOverlay:self.routeView];
}
现在这是我的 UCRouteView.h 文件。它继承自 MKOverlayView 并实现了 MKOverlay。
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "UCLocation.h"
@interface UCRouteView : MKOverlayView <MKOverlay>
{
MKMapView* _mapView;
NSArray* _points;
UIColor* _lineColor;
}
-(id) initWithRoute:(NSArray*)routePoints mapView:(MKMapView*)mapView;
@property (strong, nonatomic) id delegate;
@property (nonatomic) MKCoordinateRegion region;
@property (nonatomic, retain) NSArray* points;
@property (nonatomic, retain) MKMapView* mapView;
@property (nonatomic, retain) UIColor* lineColor;
@end
现在进行实施。在这里我有很大的麻烦。首先,似乎委托不起作用,因为没有调用任何方法(除了 init .. 显然)我将委托设置为 self。我很难理解这是如何工作的,所以如果你们能在这里帮助我,我将不胜感激,这非常重要!非常感谢
#import "UCRouteView.h"
@implementation UCRouteView
@synthesize mapView = _mapView;
@synthesize points = _points;
@synthesize lineColor = _lineColor;
@synthesize delegate = _delegate;
@synthesize region = _region;
-(id) initWithRoute:(NSArray*)routePoints mapView:(MKMapView*)mapView
{
self.delegate = self;
self = [super initWithFrame:CGRectMake(0, 0, mapView.frame.size.width, mapView.frame.size.height)];
[self setMapView:mapView];
[self setPoints:routePoints];
// determine the extents of the route points and zoom to that area.
CLLocationDegrees maxLat = -90;
CLLocationDegrees maxLon = -180;
CLLocationDegrees minLat = 90;
CLLocationDegrees minLon = 180;
for(int idx = 0; idx < self.points.count; idx++)
{
UCLocation* currentLocation = [self.points objectAtIndex:idx];
if(currentLocation.coordinates.latitude > maxLat)
maxLat = currentLocation.coordinates.latitude;
if(currentLocation.coordinates.latitude < minLat)
minLat = currentLocation.coordinates.latitude;
if(currentLocation.coordinates.longitude > maxLon)
maxLon = currentLocation.coordinates.longitude;
if(currentLocation.coordinates.longitude < minLon)
minLon = currentLocation.coordinates.longitude;
}
_region.center.latitude = (maxLat + minLat) / 2;
_region.center.longitude = (maxLon + minLon) / 2;
_region.span.latitudeDelta = maxLat - minLat;
_region.span.longitudeDelta = maxLon - minLon;
[self.mapView setRegion:_region];
return self;
}
- (MKMapRect)boundingMapRect
{
// 1. Problem: this returns the MapRect where the overlay is in, right?
// So why not just return the MapRect which is visible right now?
return self.mapView.visibleMapRect;
}
-(BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale
{
// 2. just return YES to make sure it draws
return YES;
}
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
// 3. this never gets called? what's wrong?
NSLog(@"mapview viewForOverlay");
return self;
}
-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
// does not get called either. I know the drawing code as is works to draw a route,
// but I think I'm missing something here aswell..
NSLog(@"draw route");
// only draw lines if not in the middle of a transition and we
// acutally have some points to draw.
if(self.points && self.points.count > 0)
{
// set the color to draw the route
if(nil == self.lineColor)
self.lineColor = [UIColor blueColor];
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width
CGContextSetLineWidth(context, 2.0);
for(int idx = 0; idx < self.points.count; idx++)
{
UCLocation* location = [self.points objectAtIndex:idx];
CGPoint point = [_mapView convertCoordinate:location.coordinates toPointToView:self];
// set starting point and 'move' to it
if(idx == 0)
{
// TODO: set special annotation for start/endpoint
CGContextMoveToPoint(context, point.x, point.y);
}
else
{
CGContextAddLineToPoint(context, point.x, point.y);
}
}
CGContextStrokePath(context);
}
}
@end