Wie wird ein Bild auf einem MKOverlayView angezeigt?

AKTUALISIEREN

Bilder, die mit MKOverlayView auf MKMapView projiziert werden, verwenden dasMercator Projektion, während das Bild, das ich als Eingabedaten verwende, eine WGS84-Projektion verwendet. Gibt es eine Möglichkeit, das Eingabebild in die richtige Projektion WGS84 -> Mercator umzuwandeln, ohne das Bild zu kacheln, und kann dies im laufenden Betrieb erfolgen?

Normalerweise können Sie ein Bild mit dem Programm @ in die richtige Projektion konvertiere gdal2tiles. Die Eingabedaten ändern sich jedoch alle fünfzehn Minuten, sodass das Bild alle fünfzehn Minuten konvertiert werden muss. Die Konvertierung muss also im laufenden Betrieb erfolgen. Ich möchte auch, dass die Kacheln von Mapkit und nicht von mir selbst mit gdal2tiles oder dem GDAL-Framework erstellt werden.

UPDATE END

Ich arbeite derzeit an einem Projekt, bei dem ein Regenradar über einem Teil der Welt angezeigt wird. Das Radar wird von EUMETSAT zur Verfügung gestellt und bietet eine KML-Datei, die in Google Earth oder Google Maps geladen werden kann. Wenn ich die KML-Datei in Google Maps lade, wird sie perfekt angezeigt, aber wenn ich das Bild mit einem MKOverlayView auf einem MKMapView zeichne, ist das Bild ein wenig von.

Zum Beispiel wird auf der linken Seite Google Maps und auf der rechten Seite dasselbe Bild auf einer MKMapView angezeigt.

Die Oberfläche, die das Bild abdeckt, kann auf @ angezeigt werdeGoogle Map, der Satellit, der für das Bild verwendet wird, ist der Satellit "Meteosat 0 Degree".

Die Oberfläche, die beide Bilder abdecken, hat dieselbe Größe. Dies ist die LatLonBox aus der KML-Datei. Sie gibt an, wo die oberen, unteren, rechten und linken Seiten eines Begrenzungsrahmens für die Bodenüberlagerung ausgerichtet sind.

  <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>

Ich erstelle ein neues benutzerdefiniertes MKOverlay-Objekt namens RadarOverlay mit diesen Parametern.

[[RadarOverlay alloc] initWithImageData:[[self.currentRadarData objectAtIndex:0] valueForKey:@"Image"] withLowerLeftCoordinate:CLLocationCoordinate2DMake(-57.4922, -57.4922) withUpperRightCoordinate:CLLocationCoordinate2DMake(57.4922, 57.4922)];

Die Implementierung des benutzerdefinierten MKOverlay-Objekts. 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;
}

Die Implementierung des benutzerdefinierten 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]; 
}

Wenn ich das Bild herunterlade, drehe ich es um, damit es einfach in MKOverlayView gezeichnet werden kann

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);

Nachdem ich das Bild gespiegelt habe, bearbeite ich es und speichere es im Speicher als NSData-Objekt.

Es sieht so aus, als wäre das Bild gestreckt worden, aber in der Mitte des Bildes, die sich am Äquator befindet, sieht es in Ordnung aus.

Antworten auf die Frage(12)

Ihre Antwort auf die Frage