在 UIView(不是 MKMapView)中使用 lat/long 的最佳实践

Posted

技术标签:

【中文标题】在 UIView(不是 MKMapView)中使用 lat/long 的最佳实践【英文标题】:Best practice for using lat/long within a UIView (not MKMapView) 【发布时间】:2012-12-15 11:36:51 【问题描述】:

基本上我有一个 POI 列表(名称、纬度、经度),我想在 UIView 上绘制它们,相对于我当前的纬度/经度。我正在寻找一些将这些 POI(纬度/经度)映射到 UIView 的最佳实践。

不想想使用 MKMapView(不需要显示地图数据)。

我正在阅读:

http://developer.apple.com/library/ios/#documentation/general/conceptual/Devpedia-CocoaApp/CoordinateSystem.html

但我不知道如何从 CLLocation 到 UIView 上的 (x,y)。我只想在我当前位置周围绘制那些 POI。因此,例如,如果我的屏幕代表一个 20 x 30 公里的区域,我如何将我的 POI 映射到它们对应的 (x,y) 坐标?

谢谢。

【问题讨论】:

【参考方案1】:

您所做的有点奇怪,但您可以将纬度/经度转换为类似于CGPoint 的结构,称为MKMapPointMKMapPoint 有一个 xy 值,它们对应于地图上的点。想象一下,如果你布置了一张世界的平面地图,0,0 是左上角。 MKMapPoint 是使用该坐标系的地图上的一个点。

使用函数MKMapPointForCoordinate()CLLocationCoordinate2D 转换为MKMapPoint

MKMapPoint myMapPoint = MKMapPointForCoordinate(myLocationCoordinate);

当您获得点列表时,您必须执行一些操作,例如找到最大和最小 x 和 y 值,然后使用这些值将所有点拟合到您的视图中,否则您最终会遇到负载在你的视野中的一个地方非常接近的点。

【讨论】:

但是是否这意味着我需要用户MKMap?我去玩它。我不明白什么是奇怪?,我基本上想要没有卫星图像的 MKMapView。 您可以在没有MKMapView 的情况下使用MKMapPointForCoordinate()。您仍然需要导入 MapKit 框架才能使用该功能。此外,您可以在没有卫星图像的情况下查看地图。只需将MKMapType 设置为MKMapTypeStandard【参考方案2】:

我的猜测是,对于 20KM x 30KM 的区域,您可以认为地球是平的,因此可以线性外推坐标。我相信您可以通过谷歌了解经纬度 0.00001 的距离相差多少。

因此,如果您在 X 轴上表示 20Km,并且您当前的位置是纬度 30.1234567,而 0.0000001 是 1 公里,那么您可以将您的坐标放在屏幕的中心,并将 30.1234557 作为最左边的 X 坐标和以此类推。

我不是想在这里提供答案,只是想大声思考,因为我也想做一些类似的事情,并将其作为基于 Internet 的应用程序(虽然没有显示),在给定两个坐标的情况下,我必须找到它们之间的距离。

【讨论】:

不要尝试这个。在您考虑的尺寸(20 公里)下,变换绝对不是线性的,也不是一致的。在我的日常工作中,我们发现您可以在 的距离内获得变换失真 20*30KM 只是一个例子。我想捏合并缩放到更小(或更大)的区域。【参考方案3】:

有许多(许多)不同的方法可以对行星进行建模并将 3D 坐标转换到 2D 表面上,并且各种方法引入的误差会因您所在的地球的哪个部分而异。不过,这个问题似乎涵盖了您所追求的大部分内容:

Converting Longitude & Latitude to X Y on a map with Calibration points

【讨论】:

【参考方案4】:

我认为它是最好的方式(正确适用于Mercator projection map):

extension UIView

    func addLocation(coordinate: CLLocationCoordinate2D)
    
        // max MKMapPoint values
        let maxY = Double(267995781)
        let maxX = Double(268435456)

        let mapPoint = MKMapPointForCoordinate(coordinate)

        let normalizatePointX = CGFloat(mapPoint.x / maxX)
        let normalizatePointY = CGFloat(mapPoint.y / maxY)

        let pointView = UIView(frame: CGRectMake(0, 0, 5, 5))
        pointView.center = CGPointMake(normalizatePointX * frame.width, normalizatePointY * frame.height)

        pointView.backgroundColor = UIColor.blueColor()

        addSubview(pointView)
    

我在 UIView 上添加坐标的简单项目:https://github.com/Glechik/MapCoordinateDrawer

【讨论】:

以上是关于在 UIView(不是 MKMapView)中使用 lat/long 的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIView 作为 MKMapView 子视图来绘制路线

使用 MKMapView 和可触摸的子视图创建视图

如何在自定义 UIView 下方的 MKMapview 中启用 touchEvents(滚动和平移)?

UIView 内的 MKMapView 框架没有改变

将 MKMapView 移动到相对于 superview 的特定位置

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