Iphone 如何自定义MKPolyLineView以绘制不同的样式线
我想自定义在MKMapView上绘制的线,以显示路线,从而使这些线具有边框颜色和填充颜色。与此类似,它有一个黑色边框,并用另一种颜色填充: 我目前正在从Iphone 如何自定义MKPolyLineView以绘制不同的样式线,iphone,ios,cocoa-touch,mkmapview,overlay,Iphone,Ios,Cocoa Touch,Mkmapview,Overlay,我想自定义在MKMapView上绘制的线,以显示路线,从而使这些线具有边框颜色和填充颜色。与此类似,它有一个黑色边框,并用另一种颜色填充: 我目前正在从mapView:viewForOverlay:返回MKPolyLineView对象,这对普通线很有效。文档说MKPolyLineView不是子类化的,所以我应该子类化MKOverlayView并实现我自己的drawMapRect吗?或者我应该将MKOverlayPathView子类化?还是为MKPolylineView创建替换 编辑-我想问的是
mapView:viewForOverlay:
返回MKPolyLineView对象,这对普通线很有效。文档说MKPolyLineView不是子类化的,所以我应该子类化MKOverlayView并实现我自己的drawMapRect吗?或者我应该将MKOverlayPathView子类化?还是为MKPolylineView创建替换
编辑-我想问的是:为了绘制自己的注释/覆盖,在哪里放置自己的石英绘图代码?目前,我已经创建了MKOverlayView的一个子类,并实现了我自己的drawMapRect:zoomScale:inContext:以这种方式绘制覆盖非常容易,但这是最好的解决方案吗?我知道这可能与您想要的纯方法不匹配,但为什么不使用
MKPolygon
而不是MKPolyLine
?创建一个表示路线周围某种道路的
MKPolygon
实例,然后在创建与已创建的MKPolygon/道路相对应的MKPolygonView
时,设置MKPolygonView
的属性以获得不同的填充颜色和笔划颜色
myPolygonView.lineWidth=3;
myPolygonView.fillColor=[UIColor blueColor];
myPolygonView.strokeColor=[UIColor darkGrayColor];
我自己没试过,但这应该行得通。唯一的缺点是,当您放大/缩小时,“路线”的“宽度”将改变……: 只需添加两个坐标相同但厚度不同的MKPolyLineView对象即可 添加一个线宽为10(或任意值)且strokeColor设置为黑色的 然后添加另一个线宽为6且strokeColor设置为其他所需颜色的颜色
您可以对两个MKPolyLineView对象使用相同的MKPolyLine。
MKPolyLineView
只能用于笔划指定路径。您可以使用MKOverlayPathView
中的某些属性来更改它们的外观,但只有其中一些属性适用,例如fillColor
,strokeColor
如果要绘制更复杂的图形,可以使用MKOverlayPathView
。它更通用,因此不仅仅适用于笔划路径。对于绘制简单直线,结果将与MKPolylineView
相同(至少根据文档)
如果要进行更复杂的绘图,请使用子类
MKOverlayPathView
。您试图做的事情并不简单。您可以通过实现自己的MKOverlayPathView子类来实现这一点,该子类在map rect中绘制两次路径。一次用黑色加厚,一次用另一种颜色加薄
我已经创建了一个简单的MKPolylineView插入式替换,它允许您这样做:
如果您想自己动手,则需要实现的两个主要方法如下所示:
- (void)drawMapRect:(MKMapRect)mapRect
zoomScale:(MKZoomScale)zoomScale
inContext:(CGContextRef)context
{
UIColor *darker = [UIColor blackColor];
CGFloat baseWidth = self.lineWidth / zoomScale;
// draw the dark colour thicker
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, darker.CGColor);
CGContextSetLineWidth(context, baseWidth * 1.5);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
// now draw the stroke color with the regular width
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
CGContextSetLineWidth(context, baseWidth);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
[super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}
- (void)createPath
{
// turn the polyline into a path
CGMutablePathRef path = CGPathCreateMutable();
BOOL pathIsEmpty = YES;
for (int i = 0; i < self.polyline.pointCount; i++) {
CGPoint point = [self pointForMapPoint:self.polyline.points[i]];
if (pathIsEmpty) {
CGPathMoveToPoint(path, nil, point.x, point.y);
pathIsEmpty = NO;
} else {
CGPathAddLineToPoint(path, nil, point.x, point.y);
}
}
self.path = path;
}
-(void)drawMapRect:(MKMapRect)mapRect
zoomScale:(MKZoomScale)zoomScale
inContext:(CGContextRef)上下文
{
UIColor*深色=[UIColor blackColor];
CGFloat baseWidth=self.lineWidth/zoomScale;
//把深色画得更浓些
CGContextAddPath(上下文,self.path);
CGContextSetStrokeColorWithColor(上下文,深色.CGColor);
CGContextSetLineWidth(上下文,baseWidth*1.5);
CGContextSetLineCap(上下文,self.lineCap);
CGContextStrokePath(上下文);
//现在绘制具有规则宽度的笔划颜色
CGContextAddPath(上下文,self.path);
CGContextSetStrokeColorWithColor(上下文,self.strokeColor.CGColor);
CGContextSetLineWidth(上下文,baseWidth);
CGContextSetLineCap(上下文,self.lineCap);
CGContextStrokePath(上下文);
[super-drawMapRect:mapRect-zoomScale:zoomScale-inContext:context];
}
-(void)创建路径
{
//将多段线转换为路径
CGMutablePathRef path=CGPathCreateMutable();
BOOL pathIsEmpty=是;
对于(int i=0;i
我使用一个子类namedverlay来保存覆盖名称:
名字多佛莱
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface NamedOverlay : NSObject <MKOverlay>
@property (strong, readonly, nonatomic) NSString *name;
@property (strong, readonly, nonatomic) id<MKOverlay> overlay;
-(id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name;
@end
嗯,好主意,只需确保较宽的多段线位于较薄的多段线之下。好主意,也许您可以将较薄的多段线添加为较宽多段线的子视图?由于MKPolyLineView是从UIView扩展而来的,理论上这是可能的……您可以这样做,但是您需要偏移子视图的坐标,这意味着不共享MKPolyLine。如果希望它们一起变换,最好将它们都设置为父UIView对象的子对象。这主意不错,但从任意一组路线坐标计算多边形的边界非常复杂。基本方法可能是将道路上部的纬度增加0.000001,然后下部的纬度增加-0.000001,然后用一个由上下两部分组成的多边形建造一条走廊。。。只是一个想法……只有当路线朝东/西方向运行时,这才有效。这些可以在任何方向上运行,因此多边形需要基于每个线段的标题。侧边需要与路线航向成直角,使用计算从lat/lon对计算航向是一项昂贵的操作。在GIS中,这可以通过使用ST_缓冲区来实现。如果您的iPhone上有spatialite,还可以使用1个调用计算它:。但我同意,这是一项昂贵的手术。
#import "NamedOverlay.h"
@implementation NamedOverlay
- (id)initWithOverlay:(id<MKOverlay>)overlay andName:(NSString *)name
{
_name = name;
_overlay = overlay;
return self;
}
- (MKMapRect)boundingMapRect
{
return [_overlay boundingMapRect];
}
- (CLLocationCoordinate2D)coordinate
{
return [_overlay coordinate];
}
-(BOOL)intersectsMapRect:(MKMapRect)mapRect
{
return [_overlay intersectsMapRect:mapRect];
}
@end
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay
{
NamedOverlay *namedOverlay = (NamedOverlay *) overlay;
MKPolyline *polyline = namedOverlay.overlay;
if ([namedOverlay.name isEqualToString:@"top"]) {
MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline];
view1.strokeColor = [UIColor whiteColor];
view1.lineWidth = 25.0;
return view1;
} else {
MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:polyline];
view1.strokeColor = [UIColor blueColor];
view1.lineWidth = 15.0;
return view1;
}
}