根据位置列表缩放MKMapView以最佳地适应距离缩放级别

时间:2013-02-08 11:57:53

标签: ios mkmapview

我有一个中心位置,我希望我的MKMapView可以放大,还有一个位置列表(纬度/经度)。我想根据这个位置列表设置缩放级别(距离),以便同时在MKMapView上可以看到许多这些位置,但是具有最小缩放级别(或最大距离),所以我的MKMapView不会缩小太多。

所以我说我有一个包含10个位置的列表,但其中一个位置离我的中心位置太远,如果我在MKMapView上显示一个位置它会缩小到很多,怎么做我计算MKCoordinateRegionMakeWithDistance的距离参数?

我希望我能很好地解释我的问题,我觉得我很难解释它。

谢谢你 索伦

5 个答案:

答案 0 :(得分:4)

我使用以下解决方案。

我使用Great-circle distance公式来计算我的中心点与所有找到的纬度/长点之间的距离,如果这个距离大于我的最小距离和我的最大距离并且大于我的“最后发现的距离”距离“我将此距离设置为我的缩放距离。它就像一个魅力,实际上很简单。

这是我的距离计算代码:

-(double)distanceBetweenLocations:(CLLocationCoordinate2D)c1 :(CLLocationCoordinate2D)c2 {
    int r = 6371 * 1000;//meters
    double dLat = (c2.latitude - c1.latitude) * M_PI / 180;
    double dLon = (c2.longitude - c1.longitude) * M_PI / 180;
    double lat1 = c1.latitude * M_PI / 180;
    double lat2 = c2.latitude * M_PI / 180;

    double a = sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos(lat1) * cos(lat2);
    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
    double d = r * c;

    return d;
}

这是我的代码,用计算出的距离缩放到我的中心点:

-(void)zoomToLocation {
    double MAX_DISTANCE = 10000.0;
    double MIN_DISTANCE = 600.0;

    double zoomDistance = MIN_DISTANCE;

    CLLocationCoordinate2D center;
    center.latitude = self.searchLocationLatitude;
    center.longitude = self.searchLocationLongitude;
    BOOL treaterVisible = NO;
    for (Treater *treater in treaters) {
        CLLocationCoordinate2D c2;
        c2.latitude = treater.latitude;
        c2.longitude = treater.longitude;
        double distance = [self distanceBetweenLocations:center :c2];
        if(distance > zoomDistance && distance < MAX_DISTANCE) {
            zoomDistance = distance;
            treaterVisible = YES;
        }
    }

    if(!treaterVisible) {
        zoomDistance = MAX_DISTANCE;
    }

    CLLocationCoordinate2D location;
    location.latitude = self.searchLocationLatitude;
    location.longitude = self.searchLocationLongitude;

    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location, zoomDistance, zoomDistance);
    MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:region];
    [self.mapView setRegion:adjustedRegion];
}

只要有人需要类似的东西。

最好的问候 索伦

答案 1 :(得分:0)

编辑didAddAnnotationViews方法。我希望这就是你要找的东西,

-(void) mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations)
{

        MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
        MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
        if (MKMapRectIsNull(zoomRect)) {
            zoomRect = pointRect;
        } else {
            zoomRect = MKMapRectUnion(zoomRect, pointRect);
        }
}
[mapView setVisibleMapRect:zoomRect animated:YES];
}

答案 2 :(得分:0)

DDAnnotation是显示引脚(PlaceMark)的自定义类

-(void)zoomToFitMapAnnotations:(MKMapView*)mapView
{
    if([mapView.annotations count] == 0)
        return;

    CLLocationCoordinate2D topLeftCoord;
    topLeftCoord.latitude = -90;
    topLeftCoord.longitude = 180;

    CLLocationCoordinate2D bottomRightCoord;
    bottomRightCoord.latitude = 90;
    bottomRightCoord.longitude = -180;

    for(DDAnnotation* annotation in mapView.annotations)
    {
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);

        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);

    }

    NSLog(@"A%f, B%f, C%f, D%f,", topLeftCoord.latitude, topLeftCoord.longitude, bottomRightCoord.latitude, bottomRightCoord.longitude);

    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1;

    region = [mapView regionThatFits:region];
    [mapView setRegion:region animated:YES];
}

答案 3 :(得分:0)

前几天我在书中读到了你的问题的解决方案,我认为是Preparata Shamos,计算几何。

不幸的是,解决方案是komplex:问题是:找到具有给定半径的可见点的最佳/最大子集。

如果你的点数不高,不到一万,我会按如下方式进行 0)将所有点添加到当前所选子集 1)迭代所有点insubset,计算重力点,计算所有距离到重力点,它是否适合最大缩放级别所需的距离?是的准备好了。
2)不是吗?从具有最高距离的子集中移除点,然后再次执行步骤1。 这样做直到所有点都在距当前子集中心所需的距离内。

重力点是具有平均x(或经度)和平均y(或纬度)坐标的子集中的点。

(如果你接受,请不要upvote)

答案 4 :(得分:0)

为此我们需要找到最小和最大纬度和经度,之后我们需要使这个区域具有这些纬度和经度的平均和。然后将该区域分配给mapview并使其适合该区域。就是这样。