UPDATE:
I'm still struggeling with this problem, although I may have some leads. Maybe it has something to do in what way the images are projected on the MKMapView, Google Maps uses the Mercator projection to project it's images onto a map.
If you compare the above image to that of the previous uploaded images, then it looks like the image is displayed on a Mercator projection while the image isn't. Can somebody help me any further with this problem?
UPDATE END
I'm currently working on a project which displays a rainfall radar over some part of the world. The radar image is provided by EUMETSTAT, they offer a KML file which can be loaded into Google Earth or Google Maps. If I load the KML file in Google Maps it displays perfectly, but if I draw the image using a MKOverlayView on a MKMapView, the image is slightly of.
For example, on the left side, Google Maps and on the right side the same image is displayed at a MKMapView.
The surface that the image covers can be viewed on Google Maps, the satellite that is used for the image is the "Meteosat 0 Degree" satellite.
The surface that both images cover is of the same size, this is the LatLonBox from the KML file, it specifies where the top, bottom, right, and left sides of a bounding box for the ground overlay are aligned.
<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>
I create a new custom MKOverlay object called RadarOverlay with these parameters,
[[RadarOverlay alloc] initWithImageData:[[self.currentRadarData objectAtIndex:0] valueForKey:@"Image"] withLowerLeftCoordinate:CLLocationCoordinate2DMake(-57.4922, -57.4922) withUpperRightCoordinate:CLLocationCoordinate2DMake(57.4922, 57.4922)];
The implementation of the custom MKOverlay object; 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;
}
The implementation of the custom 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];
}
When I download the image, I flip the image so it can be easily drawn in the 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);
After I flipped the image, I manipulate it and then store it in memory as a NSData object.
It looks like the image got stretched, but it looks allright at the center of the image, which is at the equator.