EDIT: Creo que mi problema es que este código funciona para niveles enteros de zoom, pero me gustaría que funcione para niveles de zoom flotante.Coincidir con el zoom/límites de un mapa MapKit con el zoom/límites de un mapa RouteMe
Tengo una aplicación iOS en la que el usuario puede alternar entre un mapa basado en RouteMe y un mapa basado en MapKit.
Cuando cambian de fuente, me gustaría poder mostrar exactamente la misma área en una que en la otra. Sin embargo, no puedo encontrar la manera de hacer que coincidan porque RouteMe y MapKit usan diferentes estructuras de datos para describir los límites del mapa.
Aquí hay un código que lo acerca un poco, pero no es exacto. Este código viene de: http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview/
No estoy seguro de si este código debe ser reparado, o posiblemente estoy pasando por alto una solución mucho más fácil. El código se ejecuta comenzando por el último método que figura:
#define MERCATOR_OFFSET 268435456
#define MERCATOR_RADIUS 85445659.44705395
#pragma mark -
#pragma mark Map conversion methods
- (double)longitudeToPixelSpaceX:(double)longitude {
return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI/180.0);
}
- (double)latitudeToPixelSpaceY:(double)latitude {
return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI/180.0))/(1 - sinf(latitude * M_PI/180.0)))/2.0);
}
- (double)pixelSpaceXToLongitude:(double)pixelX {
return ((round(pixelX) - MERCATOR_OFFSET)/MERCATOR_RADIUS) * 180.0/M_PI;
}
- (double)pixelSpaceYToLatitude:(double)pixelY {
return (M_PI/2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET)/MERCATOR_RADIUS))) * 180.0/M_PI;
}
- (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView
centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
andZoomLevel:(NSInteger)zoomLevel {
// convert center coordiate to pixel space
double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];
// determine the scale value from the zoom level
NSInteger zoomExponent = 20 - zoomLevel;
double zoomScale = pow(2, zoomExponent);
// scale the map’s size in pixel space
CGSize mapSizeInPixels = mapView.bounds.size;
double scaledMapWidth = mapSizeInPixels.width * zoomScale;
double scaledMapHeight = mapSizeInPixels.height * zoomScale;
// figure out the position of the top-left pixel
double topLeftPixelX = centerPixelX - (scaledMapWidth/2);
double topLeftPixelY = centerPixelY - (scaledMapHeight/2);
// find delta between left and right longitudes
CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
CLLocationDegrees longitudeDelta = maxLng - minLng;
// find delta between top and bottom latitudes
CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];
CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
// create and return the lat/lng span
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
return span;
}
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel
animated:(BOOL)animated {
// use the zoom level to compute the region
MKCoordinateSpan span = [self coordinateSpanWithMapView:self
centerCoordinate:centerCoordinate
andZoomLevel:zoomLevel];
MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);
// set the region like normal
[self setRegion:region animated:animated];
}
Una cosa que he notado sobre MKMapView es que si configura la región y luego la vuelve a leer inmediatamente, obtendrá valores diferentes. En nuestra aplicación, establezco el valor que desencadena una devolución de llamada de delegado y luego leo el nuevo valor y lo uso para determinar dónde colocar nuestras superposiciones. No estoy seguro si esto ayuda. :-( – EricS