gpt4 book ai didi

ios - 将 MKMapView 居中在 pin 下方的 N 像素点

转载 作者:IT王子 更新时间:2023-10-29 07:43:55 27 4
gpt4 key购买 nike

想要将 MKMapView 置于给定引脚下方 N 像素 的点上(在当前 MapRect 中可能可见也可能不可见)。

我一直在尝试使用 -(CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view 来解决这个问题,但没有成功。

有人走这条路吗(没有双关语)?

enter image description here

最佳答案

最简单的技术就是将 map 向下移动,比如从 coordinate 位置向下移动 40%会是,利用 spanregionMKMapView .如果您不需要实际像素,但只需要将其向下移动以便 CLLocationCoordinate2D有问题的是靠近 map 的顶部(比如距离顶部 10%):

CLLocationCoordinate2D center = coordinate;
center.latitude -= self.mapView.region.span.latitudeDelta * 0.40;
[self.mapView setCenterCoordinate:center animated:YES];

如果您想考虑相机的旋转和俯仰,上述技术可能不够。在这种情况下,您可以:

  • 确定要将用户位置移动到的 View 中的位置;

  • 将其转换为 CLLocation ;

  • 计算当前用户位置与新的期望位置的距离;

  • 将相机沿 map 相机当前航向 180° 的方向移动该距离。

例如在 Swift 3 中,类似于:

var point = mapView.convert(mapView.centerCoordinate, toPointTo: view)
point.y -= offset
let coordinate = mapView.convert(point, toCoordinateFrom: view)
let offsetLocation = coordinate.location

let distance = mapView.centerCoordinate.location.distance(from: offsetLocation) / 1000.0

let camera = mapView.camera
let adjustedCenter = mapView.centerCoordinate.adjust(by: distance, at: camera.heading - 180.0)
camera.centerCoordinate = adjustedCenter

在哪里CLLocationCoordinate2D有以下extension :

extension CLLocationCoordinate2D {
var location: CLLocation {
return CLLocation(latitude: latitude, longitude: longitude)
}

private func radians(from degrees: CLLocationDegrees) -> Double {
return degrees * .pi / 180.0
}

private func degrees(from radians: Double) -> CLLocationDegrees {
return radians * 180.0 / .pi
}

func adjust(by distance: CLLocationDistance, at bearing: CLLocationDegrees) -> CLLocationCoordinate2D {
let distanceRadians = distance / 6_371.0 // 6,371 = Earth's radius in km
let bearingRadians = radians(from: bearing)
let fromLatRadians = radians(from: latitude)
let fromLonRadians = radians(from: longitude)

let toLatRadians = asin( sin(fromLatRadians) * cos(distanceRadians)
+ cos(fromLatRadians) * sin(distanceRadians) * cos(bearingRadians) )

var toLonRadians = fromLonRadians + atan2(sin(bearingRadians)
* sin(distanceRadians) * cos(fromLatRadians), cos(distanceRadians)
- sin(fromLatRadians) * sin(toLatRadians))

// adjust toLonRadians to be in the range -180 to +180...
toLonRadians = fmod((toLonRadians + 3.0 * .pi), (2.0 * .pi)) - .pi

let result = CLLocationCoordinate2D(latitude: degrees(from: toLatRadians), longitude: degrees(from: toLonRadians))

return result
}
}

因此,即使相机倾斜且航向不是正北,这也会将用户的位置(居中,下十字准线所在的位置)向上移动 150 像素(上十字准线所在的位置),产生如下内容:

enter image description here

显然,您应该注意退化的情况(例如,您距离南极 1 公里,并且您尝试将 map 向上移动 2 公里米;您使用的相机角度倾斜到所需的屏幕位置超出了地平线;等),但对于实际的、真实世界的场景,像上面这样的东西可能就足够了。显然,如果您不让用户改变相机的俯仰角度,答案就更简单了。


原始答案:用于移动注释 n像素

如果你有一个 CLLocationCoordinate2D ,您可以将其转换为 CGPoint , 将其移动 x 像素,然后将其转换回 CLLocationCoordinate2D :

- (void)moveCenterByOffset:(CGPoint)offset from:(CLLocationCoordinate2D)coordinate
{
CGPoint point = [self.mapView convertCoordinate:coordinate toPointToView:self.mapView];
point.x += offset.x;
point.y += offset.y;
CLLocationCoordinate2D center = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
[self.mapView setCenterCoordinate:center animated:YES];
}

你可以这样调用:

[self moveCenterByOffset:CGPointMake(0, 100) from:coordinate];

不幸的是,这只适用于 coordinate在开始之前是可见的,所以你可能必须先到原始坐标,然后再调整中心。

关于ios - 将 MKMapView 居中在 pin 下方的 N 像素点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15421106/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com