在 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
的结构,称为MKMapPoint
。 MKMapPoint
有一个 x
和 y
值,它们对应于地图上的点。想象一下,如果你布置了一张世界的平面地图,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 子视图来绘制路线
如何在自定义 UIView 下方的 MKMapview 中启用 touchEvents(滚动和平移)?