将MapKit用户坐标转换为屏幕坐标时出现问题

3
“好的,实际上这是一个包含三个不同问题的线程:”
“1)我正在使用:”
- (void)viewDidLoad
{
    [super viewDidLoad];
    [mapView setFrame :CGRectMake(-100,-100,520,520)];
    [mapView setAutoresizesSubviews:true];
    mapView.showsUserLocation = YES;

    locManager = [[CLLocationManager alloc] init];
    locManager.delegate = self;
    [locManager startUpdatingLocation];
    [locManager startUpdatingHeading];

    [bt_toolbar setEnabled:YES];
}


- (IBAction) CreatePicture
{
     CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(mapView.userLocation.coordinate.latitude, mapView.userLocation.coordinate.longitude);

     CGPoint annPoint = [self.mapView convertCoordinate:coord toPointToView:self.mapView];    
     mapPic = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pic.png"]];
     mapPic.frame = CGRectMake(annPoint.x, annPoint.y, 32, 32);
     [self.view addSubview:macPic];
}

使用GCRectMake在用户坐标上放置图像,但不幸的是图像没有放置在正确的位置: 并且如果我移动地图,那么图片将始终以与用户位置相同的偏移量放置。我错过什么了吗?难道它不应该直接放在用户上面吗?我猜我在第一次给mapView(我下面有一个工具栏)的偏移量(-100,-100)正是导致这种情况的原因。
我的iOS 5模拟器行为异常,在格伦代尔,凤凰城放置了我的位置 (难道不应该在库比蒂诺吗?),由于某些原因表现出向东移动;尽管我的iPhone 4一切都运行良好(除了图片的错误放置)。有什么想法吗?
我一直在考虑使用注释,但我听说它们是静态的(而我真的需要它们是动态的)。这是真的吗?
谢谢!

1
你能否包含添加mapPic到你的视图层次结构中的部分?听起来你可能正在使用mapView的坐标系,但将mapPic放置在具有不同坐标系的父视图(可能是视图控制器的视图)中。 - kalperin
嗨,谢谢回复。这是一个简单的addSubView,我刚刚添加了它。 - João Pereira
3个回答

6

添加子视图时,它的框架起点是相对于其父视图的。在这种情况下,您从地图视图中派生了一个原点,然后将图像添加到视图控制器的视图中。您需要将图像的原点转换为self.view的坐标系,如下所示:

CGPoint imageOrigin = [self.view convertPoint:annPoint fromView:self.mapView];
mapPic.frame.origin = imageOrigin;
[self.view addSubview:macPic];

NB:这是未经测试的代码,但原理是需要在地图视图的坐标空间(即从[self.mapView convertCoordinate:coord toPointToView:self.mapView]获得的内容)与self.view的坐标空间之间进行转换。这个例子有点牵强,但可以说明问题,因为更简单的方法是在第一次使用前就直接使用self.view的坐标空间:

CGPoint annPoint = [self.mapView convertCoordinate:coord toPointToView:self.view];    

它不是精确匹配(图像不会完全覆盖蓝点),但可以使用。感谢您的提示! :) - João Pereira
你的图片左上角是否与蓝点的中心对齐?尝试将图像视图居中于该点。 - kalperin
它确实(排成一行)。是否可以将图像的中心对齐而不是左上角?如果可以,怎么做? - João Pereira

2

2

MKMapView提供以下方法来在视图空间和地理坐标之间进行转换:

– convertCoordinate:toPointToView:
– convertPoint:toCoordinateFromView:
– convertRegion:toRectToView:
– convertRect:toRegionFromView:

这些适合于将触摸转换为地图坐标之类的任务。针对你所描述的任务,我认为使用地图覆盖层比尝试使用子视图在地图上绘制更加合适。覆盖层是一种注释,它允许你绘制任何内容,但是让地图负责确定何时显示覆盖层并且需要绘制覆盖层。
“3)我一直在考虑使用注释,但是我听说它们是静态的(而我确实需要动态的)。这是真的吗?”
在这里,“静态”与“动态”的意思是什么?你指想要更改覆盖层视图中的内容,还是想要更改覆盖层本身的位置?我认为您应该能够随时更新覆盖层视图。我不确定是否可以通过简单调整其boundingMapRect属性来移动覆盖层,但我预计这样会奏效。如果不行,您可以随时删除覆盖层并重新添加。
尝试创建自己的地图覆盖系统而不是使用MapKit提供的工具应该是你的最后选择。当你能够使用框架而不是反其道而行之时,生活总是更加轻松,而且你的代码在未来也不太可能出现问题。

我想改变覆盖层本身的位置;更具体地说,我想让它移动到一组坐标上(因此涉及到动态与静态的问题)。 - João Pereira
另外一个问题:地图叠加层不是有点受限,只能绘制多边形吗?我能用它来在地图上放置图片吗? - João Pereira
最后一件事:@kalperin的回答解决了主要问题,但由于我实际上问了三个问题,所以你也应该得到+50声望值。我们该如何做到这一点?我应该重复问题、发送链接,然后你回答并我给你+50吗? - João Pereira
@Hal 不是的,你可以在叠加层中绘制任何你喜欢的东西。根据 MKOverlayView 的文档:“您可以子类化 MKOverlayView 来创建基于自定义形状和内容的叠加层。” MapKit 中提供了一些子类来绘制多边形和折线,但你不仅限于这些。我注意到 MKOverlay 的 boundingMapRect 被标记为 readonly,所以我不知道地图是否会注意到更改,但你总可以将其从地图中删除、更改并再次添加。我怀疑用户永远不会注意到。 - Caleb
@Hal,感谢你考虑给我奖金的事情,但是不用担心。我鼓励你尝试使用叠加层,因为我认为这是更好的解决方案,但你应该选择一个“正确”的答案,并根据你认为最好的答案授予任何奖金。奖金只是一种额外的好处,而不是期望的东西。(而且谁知道呢?也许你会得到更好的答案。)祝你好运。 - Caleb
你确定吗?我并不在意声望,我很乐意再奖励50个...真的。感谢你的见解,我一直独自处理这个项目已经有一段时间了,对iOS编程仍然感到不舒服,开始考虑放弃了。 - João Pereira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接