我正在使用自定義MKOverlay通過MKMapView繪製天氣數據。該繪圖正在CoreGraphics中完成。對於這種特殊情況,由於它處理平鋪的方式,在drawMapRect:zoomScale:inContext:方法中執行繪製是不夠的。我需要一次繪製整個圖像,而不是像drawMapRect方法那樣平鋪。在自定義MKOverlay上繪圖
之前,我有一個.gif的雷達圖像,所以我只是添加了一個imageView,並調整了drawMapRect中的imageView框的大小。
我的計劃是對此做類似的事情。在drawMapRect中添加一個自定義UIView並在其上調用setNeedsDisplay。
這裏是相關的代碼。
的MKOverlay對象的屬性boundingMapRect:
- (MKMapRect)boundingMapRect
{
CLLocationCoordinate2D upperLeftCoord =
CLLocationCoordinate2DMake(weatherData.radarArray.connectedRadar.latitude + 2.5,
weatherData.radarArray.connectedRadar.longitude - 2.5);
MKMapPoint upperLeft = MKMapPointForCoordinate(upperLeftCoord);
CLLocationCoordinate2D lowerRightCoord =
CLLocationCoordinate2DMake(weatherData.radarArray.connectedRadar.latitude - 2.5,
weatherData.radarArray.connectedRadar.longitude + 2.5);
MKMapPoint lowerRight = MKMapPointForCoordinate(lowerRightCoord);
double width = lowerRight.x - upperLeft.x;
double height = lowerRight.y - upperLeft.y;
MKMapRect bounds = MKMapRectMake(upperLeft.x, upperLeft.y, width, height);
return bounds;
}
工作drawMapRect:zoomScale:inContext的:代碼(即太慢)。
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
int numPaths = parser.dataPaths.size();
// We have to pad the map rect a lot to allow for visibility testing that works well.
MKMapRect testMapRect = MKMapRectMake(mapRect.origin.x - 40000, mapRect.origin.y - 40000, mapRect.size.width + 40000, mapRect.size.height + 40000);;
// Only draw inside the area we are suppose to
//CGRect rect = [self rectForMapRect:mapRect];
//CGContextClipToRect(context, rect);
// How see through is the radar data. 1 = opaque, 0 = completely transparent
CGContextSetAlpha(context, 1);
for (int i = 0; i < numPaths; i++) {
// Make sure the bin is actually visible in this region before drawing it
if (MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[0]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[1]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[2]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[3])) {
CGMutablePathRef path = CGPathCreateMutable();
CGPoint currentP = [self pointForMapPoint:parser.dataPaths[i]->points[0]];
CGContextBeginPath(context);
CGPathMoveToPoint(path, NULL, currentP.x, currentP.y);
currentP = [self pointForMapPoint:parser.dataPaths[i]->points[1]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [self pointForMapPoint:parser.dataPaths[i]->points[2]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [self pointForMapPoint:parser.dataPaths[i]->points[3]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [self pointForMapPoint:parser.dataPaths[i]->points[0]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
CGPathCloseSubpath(path);
CGContextSetFillColorWithColor(context, colors[parser.dataPaths[i]->dataVal]);
CGContextAddPath(context, path);
CGContextFillPath(context);
CGPathRelease(path);
}
}
新drawMapRect:zoomScale:inContext的:代碼
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
// We have to pad the map rect a lot to allow for visibility testing that works well.
radarImageView.testMapRect = MKMapRectMake(mapRect.origin.x - 40000, mapRect.origin.y - 40000, mapRect.size.width + 40000, mapRect.size.height + 40000);
radarImageView.frame = [self rectForMapRect:self.overlay.boundingMapRect];
[radarImageView setNeedsDisplay];
}
自定義的UIView的drawRect方法。
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
int numPaths = parser.dataPaths.size();
CGContextSetAlpha(context, 1);
for (int i = 0; i < numPaths; i++) {
// Make sure the bin is actually visible in this region before drawing it
if (MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[0]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[1]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[2]) ||
MKMapRectContainsPoint(testMapRect, parser.dataPaths[i]->points[3])) {
CGMutablePathRef path = CGPathCreateMutable();
CGPoint currentP = [(RadarImageOverlayView *)self.superview pointForMapPoint:parser.dataPaths[i]->points[0]];
CGContextBeginPath(context);
CGPathMoveToPoint(path, NULL, currentP.x, currentP.y);
currentP = [(RadarImageOverlayView *)self.superview pointForMapPoint:parser.dataPaths[i]->points[1]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [(RadarImageOverlayView *)self.superview pointForMapPoint:parser.dataPaths[i]->points[2]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [(RadarImageOverlayView *)self.superview pointForMapPoint:parser.dataPaths[i]->points[3]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
currentP = [(RadarImageOverlayView *)self.superview pointForMapPoint:parser.dataPaths[i]->points[0]];
CGPathAddLineToPoint(path, NULL, currentP.x, currentP.y);
CGPathCloseSubpath(path);
CGContextSetFillColorWithColor(context, colors[parser.dataPaths[i]->dataVal]);
CGContextAddPath(context, path);
CGContextFillPath(context);
CGPathRelease(path);
}
}
}
謝謝!
編輯
我想,這個問題有事情做與RadarImageView的情況下。我在drawRect:方法中獲取上下文的方式有問題嗎?
啊這是個好主意。我會給它一個鏡頭,讓你知道它是如何工作的。 –
我嘗試過這種方式,但表現仍然不夠好。典型的路徑數量約爲30,000。雷達域中的每個數據點都有一個路徑(零點不計算在內)。這個數字理論上可以達到165000. –
路徑總數是多少?可見路徑的數量是多少?用戶可以更改縮放嗎?你能看到所有的路徑嗎? – FKDev