计算包含所有引脚的MKMapRect

时间:2012-09-01 23:08:33

标签: iphone

我正在尝试放大地图,该地图专注于与该地图关联的所有引脚。我已将该信息保存在我的地图属性中。

我从这开始,但它还没有工作:

    double maxLatitude = 0;
    double minLatitude = 0;

    double maxLongitude = 0;
    double minLongitude = 0;

    for (MKAnnotation *address in self.map.locations) {
        // Latitude
        if ([address.latitude doubleValue] > 0) {
            maxLatitude = MAX(maxLatitude, [address.latitude doubleValue]);
        }
        else {
            minLatitude = MAX(abs(minLatitude), abs([address.latitude doubleValue]));
        }

        // Longitude
        if ([address.longitude doubleValue] > 0) {
            maxLongitude = MAX(maxLongitude, [address.longitude doubleValue]);
        }
        else {
            minLongitude = MAX(abs(minLongitude), abs([address.longitude doubleValue]));
        }
    }
    double centerLatitude = (maxLatitude - abs(minLatitude)) / 2;
    centerLatitude *= [self calculateSignWithFirstValue:maxLatitude secondValue:minLatitude];

    double centerLongitude = (maxLongitude - abs(minLongitude)) / 2;
    centerLongitude *= [self calculateSignWithFirstValue:maxLongitude secondValue:minLongitude];

//用坐标?

创建一些MKMapRect

我不认为我理解MKMapRect,因为当我尝试做这样的事情时:

    CLLocationCoordinate2D theOrigin = CLLocationCoordinate2DMake(32, -117);
    MKMapRect mapRect;
    mapRect.origin = MKMapPointForCoordinate(theOrigin);
    mapRect.size = MKMapSizeMake(10, 10);

我被放在海洋而不是圣地亚哥。不知道MKMapRect发生了什么。

4 个答案:

答案 0 :(得分:15)

/** 
 * Return a region covering all the annotations in the given array.
 * @param annotations Array of objects conforming to the <MKAnnotation> protocol.
 */
+(MKCoordinateRegion) regionForAnnotations:(NSArray*) annotations 
{
    double minLat=90.0f, maxLat=-90.0f;
    double minLon=180.0f, maxLon=-180.0f;

    for (id<MKAnnotation> mka in annotations) {
        if ( mka.coordinate.latitude  < minLat ) minLat = mka.coordinate.latitude;
        if ( mka.coordinate.latitude  > maxLat ) maxLat = mka.coordinate.latitude;
        if ( mka.coordinate.longitude < minLon ) minLon = mka.coordinate.longitude;
        if ( mka.coordinate.longitude > maxLon ) maxLon = mka.coordinate.longitude;
    }

    CLLocationCoordinate2D center = CLLocationCoordinate2DMake((minLat+maxLat)/2.0, (minLon+maxLon)/2.0);
    MKCoordinateSpan span = MKCoordinateSpanMake(maxLat-minLat, maxLon-minLon);
    MKCoordinateRegion region = MKCoordinateRegionMake (center, span);

    return region;
}

// usage
MKCoordinateRegion region = [XXXX regionForAnnotations:self.mapView.annotations];
[self.mapView setRegion:region animated:YES];

MKMapView缩放到离散间隔,这意味着如果缩放随机区域,它将选择最近的缩放间隔。这可能与瓷砖分辨率有关,但AFAIK没有记录。

答案 1 :(得分:3)

只是解释你关于在圣地亚哥创造MKMapRect并最终在海洋中的问题的第二部分......

首先,坐标32, -117仅在“圣地亚哥附近” 实际上,距离墨西哥西海岸几公里的太平洋南部几公里处。

另请注意,在MKMapRect中,origin是矩形的左上角(不是中心),因此生成的矩形不会完全包含您所在坐标周围的区域指定。

另一个真正的问题是跨度大小设置为MKMapSizeMake(10, 10) MKMapSize使用MKMapPoint单位(不包括度,米,英里,公里等) 地图点的距离(以米为单位)等于纬度。

在纬度3210地图点对应1.261110 (您可以使用{{1}使用MapKit函数MKMetersPerMapPointAtLatitude进行计算1}})。

因此,正在创建的地图矩形位于墨西哥西海岸附近,大小约为1.26 x 1.26 。因此,除了海洋之外什么也看不见(直到你缩小很多)。

虽然您可以使用上述功能将米转换为地图点并创建10.0 * MKMetersPerMapPointAtLatitude(32),但使用MKMapRect函数会更容易,该函数采用常规坐标(纬度和经度,以度为单位) ),以及所需的宽度和高度(以米为单位),以便所有计算都由地图视图处理。

答案 2 :(得分:1)

我有一种良好的感觉Jano的答案也很完美,但这里有另一种解决方案,为了多样化。这是我通常用来放大给定注释的内容:

-(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(MKPointAnnotation *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);
    }

    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)

从iOS 7开始,有一种更简单的方法:

mapView.showAnnotations(mapView.showAnnotations, animated: true)

希望这有帮助。