ACTUALIZACIÓN:¿Cómo mostrar una imagen en un MKOverlayView?
imágenes que se proyectan en la MKMapView utilizando un MKOverlayView utilizar el Mercator projection, mientras que la imagen que utilizo como datos de entrada utiliza una proyección WGS84. ¿Hay alguna manera de convertir la imagen de entrada, a la proyección correcta WGS84 -> Mercator, sin instalar la imagen y puede hacerlo sobre la marcha?
Normalmente, puede convertir una imagen a la proyección derecha con el programa gdal2tiles. Sin embargo, los datos de entrada cambian cada quince minutos, por lo que la imagen debe convertirse cada quince minutos. Entonces la conversión tiene que hacerse sobre la marcha. También quiero que el mosaico sea hecho por Mapkit y no por mí mismo usando gdal2tiles o el framework GDAL.
ACTUALIZACIÓN FIN
Actualmente estoy trabajando en un proyecto que muestra un radar de precipitación sobre alguna parte del mundo. La imagen del radar es proporcionada por EUMETSAT, ofrecen un archivo KML que se puede cargar en Google Earth o Google Maps. Si cargo el archivo KML en Google Maps, se muestra perfectamente, pero si dibujo la imagen con MKOverlayView en un MKMapView, la imagen es un poco.
Por ejemplo, en el lado izquierdo, Google Maps y en el lado derecho, la misma imagen se muestra en un MKMapView.
La superficie que las cubiertas de imagen se pueden ver en Google Maps, el satélite que se utiliza para la imagen es el satélite "Meteosat 0 Grado".
La superficie que ambas imágenes cubren es del mismo tamaño, esta es la LatLonBox del archivo KML, especifica dónde se alinean los lados superior, inferior, derecho e izquierdo de un recuadro delimitador para la superposición de suelo.
<LatLonBox id="GE_MET0D_VP-MPE-latlonbox">
<north>57.4922</north>
<south>-57.4922</south>
<east>57.4922</east>
<west>-57.4922</west>
<rotation>0</rotation>
</LatLonBox>
creo un nuevo encargo MKOverlay objeto llamado RadarOverlay con estos parámetros,
[[RadarOverlay alloc] initWithImageData:[[self.currentRadarData objectAtIndex:0] valueForKey:@"Image"] withLowerLeftCoordinate:CLLocationCoordinate2DMake(-57.4922, -57.4922) withUpperRightCoordinate:CLLocationCoordinate2DMake(57.4922, 57.4922)];
La implementación de la costumbre MKOverlay objeto; RadarOverlay
- (id) initWithImageData:(NSData*) imageData withLowerLeftCoordinate:(CLLocationCoordinate2D)lowerLeftCoordinate withUpperRightCoordinate:(CLLocationCoordinate2D)upperRightCoordinate
{
self.radarData = imageData;
MKMapPoint lowerLeft = MKMapPointForCoordinate(lowerLeftCoordinate);
MKMapPoint upperRight = MKMapPointForCoordinate(upperRightCoordinate);
mapRect = MKMapRectMake(lowerLeft.x, upperRight.y, upperRight.x - lowerLeft.x, lowerLeft.y - upperRight.y);
return self;
}
- (CLLocationCoordinate2D)coordinate
{
return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(mapRect), MKMapRectGetMidY(mapRect)));
}
- (MKMapRect)boundingMapRect
{
return mapRect;
}
La implementación de la costumbre MKOverlayView, RadarOverlayView
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
RadarOverlay* radarOverlay = (RadarOverlay*) self.overlay;
UIImage *image = [[UIImage alloc] initWithData:radarOverlay.radarData];
CGImageRef imageReference = image.CGImage;
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
CGRect clipRect = [self rectForMapRect:mapRect];
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
CGContextSetAlpha(context, [preferences floatForKey:@"RadarTransparency"]);
CGContextAddRect(context, clipRect);
CGContextClip(context);
CGContextDrawImage(context, theRect, imageReference);
[image release];
}
Al descargar la imagen, me tapa la imagen para que pueda ser fácilmente dibuja en el MKOverlayView
size_t width = (CGImageGetWidth(imageReference)/self.scaleFactor);
size_t height = (CGImageGetHeight(imageReference)/self.scaleFactor);
// Calculate colorspace for the specified image
CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageReference);
// Allocate and clear memory for the data of the image
unsigned char *imageData = (unsigned char*) malloc(height * width * 4);
memset(imageData, 0, height * width * 4);
// Define the rect for the image
CGRect imageRect;
if(image.imageOrientation==UIImageOrientationUp || image.imageOrientation==UIImageOrientationDown)
imageRect = CGRectMake(0, 0, width, height);
else
imageRect = CGRectMake(0, 0, height, width);
// Create the imagecontext by defining the colorspace and the address of the location to store the data
CGContextRef imageContext = CGBitmapContextCreate(imageData, width, height, 8, width * 4, imageColorSpace, kCGImageAlphaPremultipliedLast);
CGContextSaveGState(imageContext);
// Scale the image to the opposite orientation so it can be easylier drawn with CGContectDrawImage
CGContextTranslateCTM(imageContext, 0, height);
CGContextScaleCTM(imageContext, 1.0, -1.0);
if(image.imageOrientation==UIImageOrientationLeft)
{
CGContextRotateCTM(imageContext, M_PI/2);
CGContextTranslateCTM(imageContext, 0, -width);
}
else if(image.imageOrientation==UIImageOrientationRight)
{
CGContextRotateCTM(imageContext, - M_PI/2);
CGContextTranslateCTM(imageContext, -height, 0);
}
else if(image.imageOrientation==UIImageOrientationDown)
{
CGContextTranslateCTM(imageContext, width, height);
CGContextRotateCTM(imageContext, M_PI);
}
// Draw the image in the context
CGContextDrawImage(imageContext, imageRect, imageReference);
CGContextRestoreGState(imageContext);
Después Volteé la imagen, la manipulo y luego la almaceno en la memoria como un objeto NSData.
Parece que la imagen se estiró, pero se ve bien en el centro de la imagen, que está en el ecuador.
Estoy completamente fuera de mi alcance aquí, pero podría este problema tener algo que ver con el hecho de que mientras la distancia latitudinal es constante (~ 111km/grado) en todas partes, la distancia longitudinal varía como cos (phi) * R_e? –
Este sería el caso si dibuja la imagen en un objeto esférico, pero de acuerdo con la documentación; http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/MapKit/MapKit.html todo se debe dibujar correctamente porque es una superficie plana – Jeroen
Me estoy encontrando con el mismo problema, solo con diferentes datos de radar. Google Maps está dibujando el archivo KML a la perfección, pero cuando lo dibujo con un MKOverlayRenderer no funciona, tanto en lat como en long. – sethdeckard