作者:cc_lzx_530 | 来源:互联网 | 2023-05-29 12:11
我正在尝试构建一个API,以便了解是否CLLocation
代表土地.我需要这个离线工作,因为我希望我的大多数用户都没有连接.我使用MapBox作为tile服务器,但这仍然是一个MapKit问题,因为我没有使用MapBox SDK.
我已经尝试了几种方法来确定给定坐标是代表陆地还是海洋位置:
离线数据库的坐标大致构成了世界的海岸线.确定给定点是否在轮廓内部或外部仍然是一个问题.
png tile资源的颜色分析(必须有更好的方法!还需要大量的离线数据才能成为一种有效的方法)
另外(在上面的处理之后)是否有一种有效的方法来决定给定一个瓦片坐标(x,y,z)是否是陆地/海洋/海岸瓦片?
如果有人一直在努力解决这个问题,我会在此提出一些建议.
1> 小智..:
别担心,似乎Apple已经考虑过这个问题了!
如果你看一下CLGeocoder
类(CoreLocation),有一个reverseGeocodeLocation:completionHandler:
方法.
在完成处理程序中,您可以检索CLPlacemark
对象数组
CLPlacemark
有两个有趣的属性:
[placemark inlandWater]
对于位于内陆水域的坐标,此属性包含该水体的名称 - 湖泊,溪流,河流或其他水道的名称.
和 [placemark ocean]
坐落在海洋上的坐标,此属性包含海洋的名称.
因此,您只需对您的位置进行反向地理编码,并检查是否ocean
在结果CLPlacemark
对象上设置了属性.
2> Benjohn..:
我花了一段时间寻找一个强大的算法在球体上进行时区查找,甚至没有找到好的伪代码,更不用说c/c ++ 我完全满意.我要经历我发现的事情.我将完成可用于将这些放在一起的资源.
这很容易......在飞机上
该问题被称为"多边形点".
经常使用且简单的POP算法是"Ray Casting".2D平面上的POP依赖于无穷远处的点.在飞机上这很容易.无穷远处有无数个点.挑选任何一个!但球体上没有这样的观点.
如果在任何给定查询多边形的内部或外部都有已知点,则可以使用此方法.根据您的使用情况,这不是一个繁重的要求:您可以轻松地选择海中的任何一个点,这将在所有陆地多边形之外.
在"卷数" POP算法也失败了(据我可以看到),因为在球上,你可以接近或者在两个方向上的任何边缘.
算法
我想要一种没有辅助点而没有启发式(用于从边缘数据生成辅助点)的方法.如果我是诚实的,我想要这个,因为我确信它应该是可能的,不,因为我真的需要它.
对于您的用例,您可以使用通常的光线投射算法和已知在海洋中的单个点,因此您不需要依赖启发式算法,尽管它们可能仍然可以很好地工作.
我提出的方法是这样的......
您需要自己遍历多边形.对于每个多边形......
通过查询点和多边形的至少一条边找到一个很棒的圆(两个角之间的中点就可以了).
将大圆与多边形的边相交.
当您按顺序行走其边缘时,多边形的内部就在您的右侧(如果您愿意,则向左移动).这为每个交叉点提供了足够的信息,以了解哪一侧是内部或外部.
从最近的交叉点,您可以确定您的查询点是在内部还是外部.
实施技巧
如果您计划实现此(或任何其他POP算法),请不要尝试使用正弦或余弦.
将您的点(多边形角和查询点)表示为单位矢量.将您的大圆(多边形边和查询点所在的圆)表示为垂直于大平面所在平面的单位向量.使用点积和交叉积.不要在角度思考.在向量中思考.
它应该不会太难 - 我不需要它足以实现它.如果您喜欢自由撰稿,请与我们联系!
您可以构建解决方案的链接
c ++ boost库有一个POP实现,我也不喜欢,但这很大程度上是因为我是一个完美主义者 - 我想它几乎在所有情况下都能达到目的.
该tz_world数据库包含土地大量多边形,并有一个GeoJSON的变型的吧.您可以使用内置NSJSONSerialization
类很好地解析它.
以下是NASA针对点和球体的一些算法(虽然我不喜欢它们的POP).