3

In 3.1 I've been using an "offscreen" MKMapView to create map images that I can rotate, crop and so forth before presenting them the user. In 3.2 and 4.0 this technique no longer works quite right. Here's some code that illustrates the problem, followed by my theory.

     // create map view

     _mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, MAP_FRAME_SIZE, MAP_FRAME_SIZE)];
     _mapView.zoomEnabled = NO;   
     _mapView.scrollEnabled = NO;
     _mapView.delegate = self;    
     _mapView.mapType = MKMapTypeSatellite;

     // zoom in to something enough to fill the screen
     MKCoordinateRegion region;    
     CLLocationCoordinate2D center = {30.267222, -97.763889};

     region.center = center;    
     MKCoordinateSpan span = {0.1, 0.1 };    
     region.span = span;    
     _mapView.region = region;

     // set scrollview content size to full the imageView  
     _scrollView.contentSize = _imageView.frame.size;

     // force it to load

#ifndef __IPHONE_3_2

     // in 3.1 we can render to an offscreen context to force a load    
     UIGraphicsBeginImageContext(_mapView.frame.size);    
     [_mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
     UIGraphicsEndImageContext();

#else

     // in 3.2 and above, the renderInContext trick doesn't work...    
     // this at least causes the map to render, but it's clipped to what appears to be    
     // the viewPort size, plus some padding    
     [self.view addSubview:_mapView];          

#endif

when the map is done loading, I snap picture of it and stuff it in my scrollview

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {    
     NSLog(@"[MapBuilder] mapViewDidFinishLoadingMap");

     // render the map to a UIImage
     UIGraphicsBeginImageContext(mapView.bounds.size);

     // the first sub layer is just the map, the second is the google layer, this sublayer structure might change of course

     [[[mapView.layer sublayers] objectAtIndex:0] renderInContext:UIGraphicsGetCurrentContext()];

     // we are done with the mapView at this point, we need its ram!    
     _mapView.delegate = nil;     

     [_mapView release];
     [_mapView removeFromSuperview];    
     _mapView = nil;

     UIImage* mapImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
     UIGraphicsEndImageContext();     

     _imageView.image = mapImage;
     [mapImage release], mapImage = nil;  
}

The first problem is that in 3.1 rendering to a context would trigger the map to begin loading. This no longer works in 3.2, 4.0. The only thing I have found would trigger the load is to temporarily add the map to the view (i.e. make it visible). The problem being that the map only renders to the visible area of the screen, plus a little padding. The frame/bounds are fine, but it appears to be "helpfully" optimizes the loading to limit the tiles to those visible on the screen or close to it.

Any ideas how to force the map to load at full size? Anyone else have this issue?

Duane Fields
  • 1,331
  • 12
  • 20
  • u shouldnt post about 4.0 here...3.2 is ok – Daniel May 28 '10 at 20:24
  • Completely off topic, but that is pretty clever. However why didn't you just use the static maps API? – Jonathan Jun 01 '10 at 22:54
  • There are commercial restrictions and license issues. Believe me, that would have been much easier. – Duane Fields Jun 02 '10 at 21:44
  • Did you find a fix to this issue? I seem to have run into the same problem and thinking of using MKOverlay on iOS 4. But that leaves out 3.2.. MKOverlay ref: http://developer.apple.com/iPhone/library/documentation/MapKit/Reference/MKOverlay_protocol/Reference/Reference.html – ento Jul 12 '10 at 04:25
  • Update: I've worked around this problem by just overlaying an OpenGL view over the MKMapView. iOS4 seems to handle mixed OpenGL/UIFramework apps rather nicely. Not exactly answers your original question but I thought others may find the information useful. Also, I filed a bug report to Apple at Bug ID #8234305 / radr://problem/8234305 – ento Jul 26 '10 at 16:10
  • I'm voting to close this question as off-topic because the problem is obsolete. iOS 3/4 are not supported any longer for apps on the App Store and there's a new API (`MKSnaphotter`) since iOS 7. – Ortwin Gentz Apr 20 '15 at 21:41

0 Answers0