在“地图”应用程序的iPhone 3GS上,您可以点击通常显示您的位置两次的图标,蓝点从前照灯获得看起来像一个光束,基本上显示您在地图上面向的方向和相应地旋转图像。
使用MapKit MapView可以使用此选项吗?
我知道我可以使用像
这样的东西- (void)locationManager:(CLLocationManager *) manager didUpdateHeading:(CLHeading *) newHeading {
//如果准确性有效,请处理事件。
if (newHeading.headingAccuracy > 0) {
CLLocationDirection theHeading = newHeading.magneticHeading;
...
}
}
但我不知道如何在Mapkit中获得漂亮的前照灯效果,似乎没有任何文档。
有什么想法吗?
答案 0 :(得分:4)
我找到了解决方案:
我使用
的可用标题信息旋转地图[mapView setTransform:CGAffineTransformMakeRotation(heading.magneticHeading * M_PI / -180.0)];
因此,“光束”始终指向设备的顶部。我现在只在地图上显示一个ImageView并在locationManager中更改它的位置:didUpdateToLocation:fromLocation:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// scroll to new location
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
[self.mapView setRegion:region animated:YES];
// set position of "beam" to position of blue dot
self.headingAngleView.center = [self.mapView convertCoordinate:newLocation.coordinate toPointToView:self.view];
// slightly adjust position of beam
self.headingAngleView.frameTop -= self.headingAngleView.frameHeight/2 + 8;
}
其中frameTop和frameHeight是frame.origin.y和frame.size.height的快捷方式。 当点改变它的位置时,它并不理想,有时缺少一点点,但我很满意它的工作原理。
看一下我的OpenSource框架MTLocation,它完成了这一切(以及很多其他很酷的Map相关内容):
答案 1 :(得分:3)
其他答案的旋转逻辑是好的,但是依赖于位置管理器委托方法将不会产生良好的解决方案。 “光束”图像很少与蓝点在同一个地方,并且会反复弹跳。
最佳解决方案是获取蓝点视图的引用,并将“梁”图像作为子视图添加到其中。我选择了一个正方形的光束图像,光束顶部和周围的透明度。想象一下蓝点位于图像的中心。
// An MKMapViewDelegate method. Use this to get a reference to the blue dot annotation view as soon as it gets added
- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *annotationView in views) {
// Get the user location view, check for all of your custom annotation view classes here
if (![annotationView isKindOfClass:[MKPinAnnotationView class]])
{
self.userLocationAnnotationView = annotationView;
gotUsersLocationView = YES;
}
}
}
// Adds the 'viewPortView' to the annotation view. Assumes we have a reference to the annotation view. Call this before you start listening to for heading events.
- (void)addViewportToUserLocationAnnotationView {
TTDASSERT(self.userLocationAnnotationView != nil);
if (self.userLocationAnnotationView == nil) {
// No reference to the view, can't do anything
return;
}
if (self.viewPortView == nil) {
self.viewPortView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"map_viewport.png"]] autorelease];
}
[self.userLocationAnnotationView addSubview:self.viewPortView];
[self.userLocationAnnotationView sendSubviewToBack:self.viewPortView];
self.viewPortView.frame = CGRectMake((-1 * self.viewPortView.frame.size.width/2) + self.userLocationAnnotationView.frame.size.width/2,
(-1 * self.viewPortView.frame.size.height/2) + self.userLocationAnnotationView.frame.size.height/2,
self.viewPortView.frame.size.width,
self.viewPortView.frame.size.height);
}
答案 2 :(得分:3)
添加用户跟踪模式也有帮助。我知道我迟到了,但可能对像我这样的其他开发者有帮助:)。
self.mapView.userTrackingMode = RMUserTrackingModeFollowWithHeading;
答案 3 :(得分:2)
我可以想到一种方法,虽然我没有实施但可能对你有所帮助。
didUpdateHeading
中使用x和y值来计算方向的角度。请发布您对上述方法的建议/更改。
答案 4 :(得分:2)
Swift 3实施
mapView.userTrackingMode = MKUserTrackingMode.followWithHeading