在MKMapView上用图案图像画线

我尝试用一​​个模式图像在MKMapView上绘制一条线。 通过添加自定义的MKMapOverlay视图完成绘图。

我能够画出线条,但是似乎只使用了图案图像的左侧最上面的像素,而不是整个图像。

这是我的绘图程序:

 void drawPatternCellCallback(void *info, CGContextRef cgContext) { UIImage *patternImage = [UIImage imageNamed:@"tmpLine"]; CGContextDrawImage(cgContext, CGRectMake(0, 0, patternImage.size.width, patternImage.size.height), patternImage.CGImage); } - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { float alpha = 1; float tileW = 6.0f; float tileH = 4.0f; CGFloat lineWidth = MKRoadWidthAtZoomScale(zoomScale)*2; CGMutablePathRef path = CGPathCreateMutable(); if (path != nil) { //setup styles CGContextSetRGBStrokeColor(context, 0.0f, 0.0f, 1.0f, 0.5f); const CGPatternCallbacks kPatternCallbacks = {0, drawPatternCellCallback, NULL}; CGPatternRef strokePattern = CGPatternCreate( NULL, CGRectMake(0, 0, tileW, tileH), CGAffineTransformIdentity, tileW, // horizontal spacing tileH,// vertical spacing kCGPatternTilingConstantSpacing, true, &kPatternCallbacks); //color sapce CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL); CGContextSetStrokeColorSpace(context, patternSpace); //pattern CGContextSetStrokePattern(context, strokePattern, &alpha); //joins/ends CGContextSetLineJoin(context, kCGLineJoinMiter); CGContextSetLineCap(context, kCGLineCapButt); CGContextSetLineWidth(context, lineWidth); //OK, let's draw it CGPoint firstCGPoint = [self pointForMapPoint:self.point1]; CGPoint lastCGPoint = [self pointForMapPoint:self.point2]; CGPathMoveToPoint(path, NULL, lastCGPoint.x, lastCGPoint.y); CGPathAddLineToPoint(path, NULL, firstCGPoint.x, firstCGPoint.y); CGContextAddPath(context, path); CGContextStrokePath(context); //house hold CGPathRelease(path); CGPatternRelease(strokePattern); CGColorSpaceRelease(patternSpace); } } 

任何想法有什么不对?

感谢名单!

我结束了一个完全不同的策略。 我现在依靠MKPolyLine而不是自己的叠加。

使用下面的代码,我可以在MKMapView上添加一个从点A到点B的伪animation线。

该代码稍微延迟添加几个覆盖到MKMapViews,给人一种animation的印象

不是最美丽的解决scheme! – 但它看起来相当不错:-)

 /*start the animation*/ -(void)plotRouteOnMap { [self.mapView removeOverlays:self.mapView.overlays]; //calculate a number locations between the two locations self.points = [self getPointsOnRouteFrom:<FROM_LOCATION> to:<TO_LOCATION> onMapView:self.mapView]; [self addOverlaysFromPointsWithStartFrom:[NSNumber numberWithInt:1]]; } /*convert a CGPoint to a CLLocation according to a mapView*/ - (CLLocation*)pointToLocation:(MKMapView *)mapView fromPoint:(CGPoint)fromPoint { CLLocationCoordinate2D coord = [mapView convertPoint:fromPoint toCoordinateFromView:mapView]; return [[[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude] autorelease]; } /*get a list of Location objects between from and to*/ -(NSArray*)getPointsOnRouteFrom:(CLLocation*)from to:(CLLocation*)to onMapView:(MKMapView*)mapView { int NUMBER_OF_PIXELS_TO_SKIP =10; //lower number will give a more smooth animation, but will result in more layers NSMutableArray *ret = [NSMutableArray array]; CGPoint fromPoint = [mapView convertCoordinate:from.coordinate toPointToView:mapView]; CGPoint toPoint = [mapView convertCoordinate:to.coordinate toPointToView:mapView]; NSArray *allPixels = [self getAllPointsFromPoint:fromPoint toPoint:toPoint]; for (int i = 0 ; i < [allPixels count] ; i+=NUMBER_OF_PIXELS_TO_SKIP) { NSValue *pointVal = [allPixels objectAtIndex:i]; [ret addObject:[self pointToLocation:mapView fromPoint:[pointVal CGPointValue]]]; } [ret addObject:[self pointToLocation:mapView fromPoint:toPoint]]; return ret; } /*calulate alle pixels from point to toPint*/ -(NSArray*)getAllPointsFromPoint:(CGPoint)fPoint toPoint:(CGPoint)tPoint { /*Simplyfied implementation of Bresenham's line algoritme */ NSMutableArray *ret = [NSMutableArray array]; float deltaX = fabsf(tPoint.x - fPoint.x); float deltaY = fabsf(tPoint.y - fPoint.y); float x = fPoint.x; float y = fPoint.y; float err = deltaX-deltaY; float sx = -0.5; float sy = -0.5; if(fPoint.x<tPoint.x) sx = 0.5; if(fPoint.y<tPoint.y) sy = 0.5; do { [ret addObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]]; float e = 2*err; if(e > -deltaY) { err -=deltaY; x +=sx; } if(e < deltaX) { err +=deltaX; y+=sy; } } while (round(x) != round(tPoint.x) && round(y) != round(tPoint.y)); [ret addObject:[NSValue valueWithCGPoint:tPoint]];//add final point return ret; } /*add a poly line overlay to mapview which start at position 0 and end in 'end' in the array points*/ -(void)addOverlaysFromPointsWithStartFrom:(NSNumber*)end { int intEnd = [end intValue]; //construct polyline view from start CLLocationCoordinate2D *locations = malloc(sizeof(CLLocationCoordinate2D)*2); CLLocation *loc1 = (CLLocation*)[points objectAtIndex:0]; CLLocation *loc2= (CLLocation*)[points objectAtIndex:intEnd]; locations[0] = loc1.coordinate; locations[1] = loc2.coordinate; MKPolyline *line = [MKPolyline polylineWithCoordinates:locations count:2]; [self.mapView addOverlay:line]; if((intEnd+1) < [points count])//add more overlays after delays unless this is the endpoint { [self performSelector:@selector(addOverlaysFromPointsWithStartFrom:) withObject:[NSNumber numberWithInt:intEnd + 1] afterDelay:0.01]; } }