我正在尝试使用叠加层在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
答案 0 :(得分:0)
首先,您尝试在设置self
之前调用设置器(即self.delegate = self
[super init...]
之前的<{1}}。这在任何对象中都不起作用。
但更重要的是,您打算设置哪个delegate
?您的UCRouteView
类是MKOverlayView
的子类,它没有delegate
属性(也没有超类)。实际上,您的方法来自<MKMapViewDelegate>
,建议您打算设置mapView
的委托。因此,正确的调用将是[[self mapView] setDelegate:self]
(或者,如果您更喜欢点语法,self.mapView.delegate = self
。
我还没有详细介绍其余的代码......看看上述更改是否至少会导致调用您的方法。 (我不完全确定你的班级架构在这里是最优的,但我们现阶段不需要处理它。)