2011-02-18 14 views
11

Estoy tratando de establecer la región del mapa (centro y tramo) para que el mapa muestre todas las anotaciones pin al mismo tiempo.iPhone MKMapView: establece la región del mapa para mostrar todos los pines en el mapa

Tengo problemas para convertir las coordenadas long/lat de NSString a double, resp. hacer cálculos con ellos. Aquí está el código que estoy usando:

- (void)updateMemberPins{ 

//calculate new region to show on map 
double center_long = 0.0f; 
double center_lat = 0.0f; 
double max_long = 0.0f; 
double min_long = 0.0f; 
double max_lat = 0.0f; 
double min_lat = 0.0f; 

for (Member *member in members) { 

    //find min and max values 
    if ([member.locLat doubleValue] > max_lat) {max_lat = [member.locLat doubleValue];} 
    if ([member.locLat doubleValue] < min_lat) {min_lat = [member.locLat doubleValue];} 
    if ([member.locLong doubleValue] > max_long) {max_long = [member.locLong doubleValue];} 
    if ([member.locLong doubleValue] < min_long) {min_long = [member.locLong doubleValue];} 

    //sum up long and lang to get average later 
    center_lat = center_lat + [member.locLat doubleValue]; 
    center_long = center_long + [member.locLong doubleValue]; 
} 

//calculate average long/lat 
center_lat = center_lat/[members count]; 
center_long = center_long/[members count]; 

NSLog(@"center long: %d, center lat: %d", center_long, center_lat); 
NSLog(@"max_long: %d, min_long: %d, max_lat: %d, min_lat: %d", max_long, min_long, max_lat, min_lat); 

//create new region and set map 
CLLocationCoordinate2D coord = {latitude: center_lat, longitude: center_long}; 
MKCoordinateSpan span = MKCoordinateSpanMake(abs(max_lat) + abs(min_lat), abs(max_long) + abs(min_long)); 
MKCoordinateRegion region = {coord, span}; 
[resultMapView setRegion:region]; 

//remove all pins from map 
[resultMapView removeAnnotations:resultMapView.annotations]; 

//show member pins 
for (id member in members) { 
    [resultMapView addAnnotation:(Member *) member]; 
} 

}

El resultado del logaritmo de la salida es:

centro larga: -1946827116, centro Latitud: 1075651472

max_long: -6267216, min_long: 1076018553, max_lat: 0, min_lat: 0

I thin k el problema proviene (incorrectamente) de convertir valores de NSString a double, sin embargo no puedo encontrar una manera de hacerlo funcionar ... El formato de las cadenas de ubicación es como '43 .5686473 '.

¿Alguna pista? Cheerz

+0

sus valores de inicio para min max lat lon son incorrectos. Pruebe estos: double max_long = -360.0f; doble min_long = 360.0f; doble max_lat = -360.0f; doble min_lat = 360.0f; – igrek

+0

y cálculos de rango? ¿por qué agregarlos? Y también ABS devuelve int no doble así que deben ser fabs: MKCoordinateSpan span = MKCoordinateSpanMake (fabs (max_lat - min_lat), fabs (max_long - min_long)); – igrek

+0

gracias de todos modos, +1 me salvó un poco de tiempo – igrek

Respuesta

5

Para mostrar valor doble en NSLog(), debe utilizar %f, en lugar de %d Cambio NSLog() parte así:

NSLog(@"center long: %f, center lat: %f", center_long, center_lat); 
NSLog(@"max_long: %f, min_long: %f, max_lat: %f, min_lat: %f", max_long, min_long, max_lat, min_lat); 

Además, el uso región desde MKMapView es mucho más simple que hacer su propio. Una vez que se establece con la relación de zoom, todo lo que necesita es moverse dinámicamente alrededor del mapa con diferentes coordenadas.

MKCoordinateRegion region = self.mapView.region; 
region.center = centerCoordinate; 
region.span.longitudeDelta /= ratioZoomMax; // Bigger the value, closer the map view 
region.span.latitudeDelta /= ratioZoomMax; 
[self.mapView setRegion:region animated:YES]; // Choose if you want animate or not 
+0

¡Hola Peter! Gracias por su respuesta. Tiene razón con la declaración de NSLog. Sin embargo, esta conjetura de que esto no está causando mis cálculos erróneos ... La variante de ratioZoom es agradable, pero no sé esta relación. Tengo 'las mejores coordinadoras' que tienen que ser visibles en el mapa ... – pawi

+0

Bueno, resultó que estaba confundido con los números malos que la declaración de registro incorrecta me dio. Luego cometí algunos errores en mis cálculos, y también datos erróneos (coordenadas 0, 0). – pawi

+0

Puede cambiar 'ratioZoomMax' para que sea más pequeño para mostrar un área mucho más amplia, mostrando pines que están lejos el uno del otro. Leyendo tu código nuevamente, descubrí que hiciste una adición innecesaria para encontrar el valor del centro.Como ya has descubierto, para encontrar el centro, solo tienes que hacer '(lowestValue + highestValue)/2.0', sin dividirlo por' [members count] ' – petershine

22

El, código de trabajo final para aquellos que buscan algo similar:

- (void)updateMemberPins{ 

    //remove all pins from map 
    [resultMapView removeAnnotations:resultMapView.annotations]; 

    if ([members count] > 0) { 

     @try { 
      //calculate new region to show on map   
      Member *firstMember = [members objectAtIndex:0]; 
      double max_long = [firstMember.locLong doubleValue]; 
      double min_long = [firstMember.locLong doubleValue]; 
      double max_lat = [firstMember.locLat doubleValue]; 
      double min_lat = [firstMember.locLat doubleValue]; 

      //find min and max values 
      for (Member *member in members) { 
       if ([member.locLat doubleValue] > max_lat) {max_lat = [member.locLat doubleValue];} 
       if ([member.locLat doubleValue] < min_lat) {min_lat = [member.locLat doubleValue];} 
       if ([member.locLong doubleValue] > max_long) {max_long = [member.locLong doubleValue];} 
       if ([member.locLong doubleValue] < min_long) {min_long = [member.locLong doubleValue];} 
      } 

      //calculate center of map 
      double center_long = (max_long + min_long)/2; 
      double center_lat = (max_lat + min_lat)/2; 

      //calculate deltas 
      double deltaLat = abs(max_lat - min_lat); 
      double deltaLong = abs(max_long - min_long); 

      //set minimal delta 
      if (deltaLat < 5) {deltaLat = 5;} 
      if (deltaLong < 5) {deltaLong = 5;} 

      //debug 
      //NSLog(@"center long: %f, center lat: %f", center_long, center_lat); 
      //NSLog(@"max_long: %f, min_long: %f, max_lat: %f, min_lat: %f", max_long, min_long, max_lat, min_lat); 

      //create new region and set map 
      CLLocationCoordinate2D coord = {latitude: center_lat, longitude: center_long}; 
      MKCoordinateSpan span = MKCoordinateSpanMake(deltaLat, deltaLong); 
      MKCoordinateRegion region = {coord, span}; 
      [resultMapView setRegion:region]; 


     } 
     @catch (NSException * e) { 
      NSLog(@"Error calculating new map region: %@", e); 
     } 
     @finally { 
      //show member pins 
      for (id member in members) { 
       [resultMapView addAnnotation:(Member *) member]; 
      } 
     } 



    } 

} 
+5

Podría ser mejor usar fabs(), en lugar de abs(). ABS() me dio algunos problemas. –

2
//show member pins 
     for (id member in members) { 
      [resultMapView addAnnotation:(Member *) member]; 
     } 

Esto se puede sustituir por

[resultMapView addAnnotations:members]; 
0

Simplemente podría utilizar esta paz de código:

-(void)updateMemberPins 
{ 
    if([members count] == 0) 
     return; 

    double minLat = 90; 
    double minLon = 180; 
    double maxLat = -90; 
    double maxLon = -180; 

    for(Member *member in members) 
    { 
     minLat = fmin(minLat, [member.locLat doubleValue]); 
     minLon = fmin(minLon, [member.locLong doubleValue]); 
     maxLat = fmax(maxLat, [member.locLat doubleValue]); 
     maxLon = fmax(maxLon, [member.locLong doubleValue]); 
    } 

    NSLog(@"MAX LAT: %f, MIN LAT: %f, MAX LONG: %f, MIN LONG: %f,", maxLat, minLat, maxLon, minLon); 

    double midLat = (minLat + maxLat)/2; 
    double midLong = (minLon + maxLon)/2; 

    double deltaLat = abs(maxLat - minLat); 
    double deltaLong = abs(maxLon - minLon); 

    if (deltaLat < 5) {deltaLat = 5;} 
    if (deltaLong < 5) {deltaLong = 5;} 

    //... 
} 
Cuestiones relacionadas