lat / long坐标到屏幕位置的奇怪翻译

时间:2011-10-27 11:25:06

标签: iphone mkmapview mapkit mkannotation

我的应用上有一个地图,显示两种注释:位置和位置群集。当我放大群集时,群集将展开以显示群集中包含的位置。将这些位置添加到地图时,其父簇的坐标将存储在注释对象中。我想要做的是制作动画,以便在添加这些位置时,它们从父群集的位置展开。这是我的mapView代码:didAddAnnotationViews:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    MKAnnotationView *aV;
    for (aV in views)
    {
        if (([aV.annotation isKindOfClass:[PostLocationAnnotation class]]) && (((PostLocationAnnotation *)aV.annotation).hasParent))
        {
            CLLocationCoordinate2D startCoordinate = ((PostLocationAnnotation *)aV.annotation).parentCoordinate;

            CGPoint startPoint = [ffMapView convertCoordinate:startCoordinate toPointToView:self.view];

            CGRect endFrame = aV.frame;

            aV.frame = CGRectMake(startPoint.x, startPoint.y, aV.frame.size.width, aV.frame.size.height);

            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:1.00];
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
            [aV setFrame:endFrame];
            [UIView commitAnimations];

            ((PostLocationAnnotation *)aV.annotation).hasParent = NO;
        }
    }
}

这似乎使得地图点从远离视图焦点的某个位置飞入。通过调试我发现endFrame.origin和startPoint的值之间存在巨大的差异 - 对于一个特定的aV,endFrame.origin出现为(32657,21781)(两个CGFloats)和startPoint出现为(159.756256,247.213226) )(同样,两个CGFloats)。我假设endFrame.origin是正确的值,因为这些点在我想要的地方结束,它们只是来自远处的某个地方。我在我的代码的很多其他部分使用了convertCoordinate:toPointToView:方法,没有任何问题。我还尝试将startPoint的X和Y值乘以各种值,但是对于startPoint的每个值,单个系数都不成立。知道发生了什么事吗?

1 个答案:

答案 0 :(得分:2)

注释视图的框架似乎基于当前缩放级别,然后偏离屏幕坐标。为了弥补这一点,请将startPoint偏移annotationVisibleRect.origin

此外,在调用convertCoordinate:toPointToView:时,我认为转换为地图视图的框架而不是self.view更安全,因为地图视图的大小可能与容器视图的大小不同。

尝试以下更改:

CGPoint startPoint = [ffMapView convertCoordinate:startCoordinate 
                                    toPointToView:ffMapView];
//BTW, using the passed mapView parameter instead of referencing the ivar 
//would make the above line easier to re-use.

CGRect endFrame = aV.frame;

aV.frame = CGRectMake(startPoint.x + mapView.annotationVisibleRect.origin.x,
                      startPoint.y + mapView.annotationVisibleRect.origin.y,
                      aV.frame.size.width, 
                      aV.frame.size.height);