【问题标题】:What's the best way to zoom out and fit all annotations in MapKit在 MapKit 中缩小和适合所有注释的最佳方法是什么
【发布时间】:2010-11-12 22:01:19
【问题描述】:

我正在做的事情的快速背景。 UIMapView 加载并显示一个注释(从不超过一个)。在菜单栏上,有一个 Locate Me 按钮,点击后会找到 userLocation 并显示为第二个注释。然后我让 MapView 缩小以适应范围内的这两个注释,但我找不到合适的方法。根据第一个注释相对于用户位置的放置位置,有时它不会足够缩小。

例如,如果注释是用户的西北,它会很好地缩小。但是,如果注释是用户的东南方,它只会缩小到足以使它们被截断,您必须手动缩小一点。这是我正在使用的代码,是我在 SO 上找到的其他代码的变体。

        CLLocation *whereIAm = mapView.userLocation.location;

        float lat = whereIAm.coordinate.latitude;
        float lon = whereIAm.coordinate.longitude;


        CLLocationCoordinate2D southWest = {[currentLatitude floatValue], [currentLongitude floatValue]};
        CLLocationCoordinate2D northEast = southWest;

        southWest.latitude = MIN(southWest.latitude, lat);
        southWest.longitude = MIN(southWest.longitude, lon);

        northEast.latitude = MAX(northEast.latitude, lat);
        northEast.longitude = MAX(northEast.longitude, lon);

        CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
        CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];

        CLLocationDistance meters = [locSouthWest distanceFromLocation:locNorthEast];

        MKCoordinateRegion region;
        region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0;
        region.center.longitude = (southWest.longitude + northEast.longitude) / 2.0;
        region.span.latitudeDelta = meters / 111319.5
        region.span.longitudeDelta = 7.0;

        MKCoordinateRegion savedRegion = [mapView regionThatFits:region];
        [mapView setRegion:savedRegion animated:YES];

        [locSouthWest release];
        [locNorthEast release];

是否有更好的方法内置到 MapKit 中来缩小以便两个注释都有,比如说在外框它们之间有半英寸?我真的不在乎用户是否必须在之后放大,我只是希望它能够正确缩小。

【问题讨论】:

    标签: ios objective-c iphone cocoa-touch mapkit


    【解决方案1】:
    -(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(MapAnnotation* 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; // Add a little extra space on the sides
        region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
    
        region = [mapView regionThatFits:region];
        [mapView setRegion:region animated:YES];
    }
    

    取自:http://codisllc.com/blog/zoom-mkmapview-to-fit-annotations/

    (一直使用它。)

    【讨论】:

    • 嗯,我确实曾经尝试过这个,但它也没有按预期工作。我有同样的结果。不过,我要快速拍摄一下,然后再看一遍。我会回来报告的。
    • “如预期”是什么意思?你有什么问题?
    • 刚刚实现了它,它比我拥有的更好,所以我会坚持下去。现在唯一被切断的是标注,我可以通过使其在动画后重新弹出来解决。感谢您的帮助。
    • 如果用 cmets "add a little extra space..." 将行调整为 1.2、1.3 等,您可能会获得所需的填充。
    • 有没有人遇到缩放级别的问题,在IOS6中使用这个代码
    【解决方案2】:

    在 iOS7 中有一种方法可以做到这一点。只需致电:

    [yourMapView showAnnotations:yourAnnotationsArray animated:YES];
    

    【讨论】:

    • 这太棒了。谢谢你展示它。不像自制功能那么灵活,但它确实有效。如果您可以添加昆虫以在注释周围留出更多空间,那就太酷了。
    • 哦,我的……这太完美了……我已经为此使用了大约 30 行代码,而且我一直在窃听 - 这非常有效!
    【解决方案3】:

    那些做monotouch c#编码的人

    BasicMapAnnotation 是继承自 MKAnnotation 的类

    private void GetRegion(MKMapView mapView)
    {
        var userWasVisible = mapView.ShowsUserLocation;
        mapView.ShowsUserLocation = false; // ignoring the blue blip
        // start with the widest possible viewport
        var tl = new CLLocationCoordinate2D(-90, 180); // top left
        var br = new CLLocationCoordinate2D(90, -180); // bottom right
        foreach (var an in mapView.Annotations)
        {
            // narrow the viewport bit-by-bit
            CLLocationCoordinate2D coordinate = ((BasicMapAnnotation) an).Coordinate;
            tl.Longitude = Math.Min(tl.Longitude, coordinate.Longitude);
            tl.Latitude = Math.Max(tl.Latitude, coordinate.Latitude);
            br.Longitude = Math.Max(br.Longitude, coordinate.Longitude);
            br.Latitude = Math.Min(br.Latitude, coordinate.Latitude);
        }
        var center = new CLLocationCoordinate2D
        {
            // divide the range by two to get the center
            Latitude = tl.Latitude - (tl.Latitude - br.Latitude)*0.5,Longitude = tl.Longitude + (br.Longitude - tl.Longitude)*0.5
    
        };
        var span = new MKCoordinateSpan
        {
            // calculate the span, with 20% margin so pins aren’t on the edge
            LatitudeDelta = Math.Abs(tl.Latitude - br.Latitude)*1.2,LongitudeDelta = Math.Abs(br.Longitude - tl.Longitude)*1.2
    
        };
        var region = new MKCoordinateRegion {Center = center, Span = span};
        region = mapView.RegionThatFits(region); // adjusts zoom level too
                    mapView.SetRegion(region, true); // animated transition
                    mapView.ShowsUserLocation =
    
        userWasVisible;
    
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用此代码显示所有注释

      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);
          zoomRect = MKMapRectUnion(zoomRect, pointRect);
      }
      [mapView setVisibleMapRect:zoomRect animated:YES];
      

      如果您想包含用户位置,只需将下面的两行替换为上述代码的第一行

      MKMapPoint annotationPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate);
      MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
      

      【讨论】:

      • 另外:double dx = zoomRect.size.width * CGRectGetWidth(self.map.bounds)/CGRectGetWidth(self.view.bounds); double dy = zoomRect.size.height * CGRectGetHeight(self.map.bounds)/CGRectGetHeight(self.view.bounds); zoomRect = MKMapRectInset(zoomRect,-dx/2,-dy/2); [self.map setVisibleMapRect:zoomRect 动画:YES];
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多