Estoy usando una MKOverlay personalizada para dibujar datos meteorológicos sobre un MKMapView. El dibujo se está haciendo en CoreGraphics. Para este caso particular, no es suficiente hacer el dibujo en el método drawMapRect: zoomScale: inContext: debido a cómo maneja el mosaico. Necesito que la imagen completa se dibuje de una vez en vez de mosaico como el método drawMapRect.Dibujo en MKOverlay personalizado
Antes, tenía la imagen de radar en un archivo .gif así que acabo de agregarle un imageView y cambiar el tamaño del marco de imageView en drawMapRect.
Mi plan era hacer algo similar con esto. Agregue una UIView personalizada y llame a setNeedsDisplay sobre ella en drawMapRect.
Aquí está el código relevante.
La propiedad boundingMapRect del objeto MKOverlay:
- (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;
}
El drawMapRect de trabajo: zoomScale: InContext: código (que es demasiado lento).
- (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);
}
}
El nuevo drawMapRect: zoomScale: InContext: Código
- (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];
}
El método drawRect de la UIView personalizado.
- (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);
}
}
}
Gracias!
EDITAR
Pienso que el problema tiene que ver con el contexto de la RadarImageView. ¿Hay algún problema con la forma en que obtengo el contexto en el método drawRect: tal vez?
Ahh esta es una buena idea. Le daré una oportunidad y le dejaré saber cómo funciona. –
Intenté esto y el rendimiento aún no era lo suficientemente bueno. El número típico de rutas es de alrededor de 30,000. Hay una ruta para cada punto de datos en el dominio del radar (los ceros no se cuentan). En teoría, este número podría llegar a 165000. –
¿Cuál es el número total de rutas? ¿Cuál es el número de caminos visibles? ¿Puede el usuario cambiar el zoom? ¿Puedes tener todos los caminos visibles? – FKDev