2011-02-18 2 views
11

지도가 모든 핀 주석을 동시에 표시하도록지도 영역 (중심 및 경간)을 설정하려고합니다.iPhone MKMapView :지도의 모든 핀을 표시하도록지도 영역 설정

long/lat 좌표를 NSString에서 double로 변환하는 데 문제가 있습니다. 그들과 계산해라.

- (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]; 
} 

}

로그 출력의 결과입니다 :

센터 긴 : 여기에 내가 사용하고 코드가 -1946827116, 센터는 위도 : 1075651472

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

I thin k 문제는 (잘못) NSString에서 값을 double로 변환하지만, 작동시킬 수있는 방법을 찾을 수 없습니다. 위치 문자열의 형식은 '43 .5686473 '과 같습니다.

힌트가 있습니까? Cheerz에

+0

최소 최대 lat lon의 시작 값이 잘못되었습니다. 다음을 시도하십시오 : double max_long = -360.0f; double min_long = 360.0f; double max_lat = -360.0f; double min_lat = 360.0f; – igrek

+0

및 범위 계산? 왜 그들을 추가할까요? 또한 abs는 int가 double이 아니므로 팹이되어야합니다. MKCoordinateSpan span = MKCoordinateSpanMake (fabs (max_lat - min_lat), fabs (max_long - min_long)); – igrek

+0

어쨌든 고마워, +1 내게 시간을 절약했다 – igrek

답변

5

는 대신 NSLog() 부분이 같은 %d 변경의, %f를 사용한다) NSLog (더블 값을 표시하려면

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

또한, MKMapView에서 영역을 사용하여 자신을 만드는 것보다 훨씬 간단하다. 확대/축소 비율로 설정하면 좌표가 다른지도를 동적으로 이동하는 데 필요한 작업 만 수행하면됩니다.

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

안녕 피터! 귀하의 회신에 감사드립니다. 당신은 NSLog 문과 함께 맞습니다. 그러나 이것은 내 오산을 일으키지 않는다고 추측합니다 ... ratioZoom 변종은 훌륭하지만이 비율을 알지 못합니다. 나는지도에서 볼 수있는 '가장 외진 코디안들'을 가지고있다 ... – pawi

+0

글쎄, 내가 잘못된 로그 - 문장이 준 나쁜 숫자와 혼동되었다는 것이 밝혀졌다. 그렇다면 계산 결과에서 실수를 저질렀습니다. 또한 나쁜 데이터 (0, 0 좌표)가 있습니다. – pawi

+0

'ratioZoomMax'를 더 작게 변경하여 훨씬 넓은 영역을 표시하여 서로 멀리있는 핀을 표시 할 수 있습니다. 코드를 다시 읽으면 불필요한 중심 값을 찾지 못했다는 것을 알았습니다.이미 알아 낸 것처럼 센터를 찾으려면'(lowestValue + highestValue)/2.0'을'[members count] '로 나누지 말아야합니다. – petershine

22

비슷한 무언가를 찾는 사람들을위한 최종 작업 코드 :

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

abs() 대신 fabs()를 사용하는 것이 더 나을 수도 있습니다. abs()는 나에게 몇 가지 문제점을 제시했다. –

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

이 당신은 단순히 코드의 평화를 사용할 수

[resultMapView addAnnotations:members]; 
0

로 대체 할 수있다 :

-(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;} 

    //... 
} 
관련 문제