【问题标题】:Sort a list by distance using reversed Geolocation使用反向地理定位按距离对列表进行排序
【发布时间】:2015-12-22 15:25:13
【问题描述】:

我正在使用 Xcode 7 和 iOS9。我想根据从用户当前位置到列表中所有其他位置的距离对列表进行升序排序。

我不想按坐标计算到某个位置的距离,而是按地址计算,因为距离取决于选择的方法(驾车/步行)。我要做的就是将地址保存在每个位置对象中,以便稍后计算到该对象的距离。

使用对象初始化列表时,我在每个对象的初始化程序中执行此请求:

let location = CLLocation(latitude: latitude, longitude: longitude) //changed!!!

CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in 
    //the code to obtain an address and save it in a location object is here and works
}

我现在遇到的问题是我必须发送 172 个这样的 reverseGeocodeLocation 请求,因为我的列表包含 172 个对象,我需要计算从我的用户位置到每个对象位置的距离。

如此快速地发送如此多的请求会导致此错误: 操作无法完成。 (kCLErrorDomain 错误 2。)

有没有办法解决这个问题? 如果事情不清楚,请告诉我,以便我澄清

【问题讨论】:

  • 我不认为这真的是 reverseGeocodeLocation 的预期用途,因此如果不隔开您的请求以满足 API 限制,我怀疑会有一个好的解决方案。您是否考虑过使用具有不同 API 限制或允许您一次发送多个位置的不同地理位置服务
  • 升序排序意味着您要列出附近的那些地方??
  • @anishparajuli 是的
  • 使用 google places API 或foursquare API 然后... ??
  • @anishparajuli 是的 google api 工作正常,谢谢

标签: ios swift ios9 cllocation reversegeocodelocation


【解决方案1】:

Apple 的地理编码对象不适用于批量地理编码。有关更多信息,请参阅 Xcode 中的 CLGeocoder 类参考。简短摘录:

应用程序应该意识到它们如何使用地理编码。地理编码 每个应用程序的请求都有速率限制,因此请求过多 短时间内可能会导致部分请求失败。 (超过最大速率时,地理编码器返回错误 具有值 kCLErrorNetwork 的对象到关联的完成 处理程序。)以下是使用此类的一些经验法则 有效:

为任何一项用户操作最多发送一个地理编码请求。

如果用户执行涉及地理编码相同的多个操作 位置,而是重用初始地理编码请求的结果 为每个操作启动单独的请求。

当您想自动更新用户的当前位置时 (例如当用户移动时),仅发出新的地理编码请求 当用户移动了相当长的距离并经过合理的 时间已经过去了。例如,在典型情况下,您 每分钟不应发送超过一个地理编码请求

(我添加的重点。)

总结是你不能用苹果的CLGeocoder 类做你想做的事情。

您应该只为用户操作提交一个地理编码请求,然后通常每分钟不超过一个地理编码请求。

您需要获得第三方地理编码服务的许可(并且可能需要付费)才能进行批量地理编码或反向地理编码。

【讨论】:

【解决方案2】:

在一些 cmets 的帮助下,我终于自己找到了答案。

目前,可以使用 Apple Maps API 检索的唯一距离是坐标之间的直线距离。但是,如果您想计算两个地址或坐标之间的实际距离,您可以发送一个简单的请求with the Google Maps Distance Matrix API

示例:

计算距离:51.226531,4.190688
到 51.114476,4.139618 和 51.148123,4.182590。

您可以通过这个 API 调用简单地做到这一点: https://maps.googleapis.com/maps/api/distancematrix/json?origins=51.226531,4.190688&destinations=51.114476,4.139618|51.148123,4.182590

注意我使用了 3 个参数:
json:我希望返回结果的格式
来源:坐标/地址您从哪里开始
目的地:由“|”分隔的多个坐标/地址

这是调用的结果:

{
  "destination_addresses" : [
  "Dorpstraat 70, 9140 Temse, België",
  "Eigenlostraat 38, 9100 Sint-Niklaas, België"
],
"origin_addresses" : [ "Provinciale Baan 37, 9120 Beveren, België" ],
"rows" : [
  {
     "elements" : [
        {
           "distance" : {
              "text" : "16,3 km",
              "value" : 16346
           },
           "duration" : {
              "text" : "22 min.",
              "value" : 1321
           },
           "status" : "OK"
        },
        {
           "distance" : {
              "text" : "10,5 km",
              "value" : 10521
           },
           "duration" : {
              "text" : "17 min.",
              "value" : 1003
           },
           "status" : "OK"
        }
     ]
  }
],
"status" : "OK" 
}

如果有不清楚的地方,问我!

【讨论】:

  • 无论如何,这与“172 个这样的 reverseGeocodeLocation 请求,因为我的列表包含 172 个对象”没有什么不同......只是你不会得到错误,但对于客户端你会调用很多 API?
  • 我一开始也是这么想的,但是如果你读得很好,你可以通过用“|”分隔参数中的坐标,在一次调用中检索多个距离
  • 哦,谢谢你看看...你能把链接扔掉吗?
  • @anishparajuli Google 距离矩阵 API 文档:developers.google.com/maps/documentation/distance-matrix/intro
  • 一次发送多个请求时,请记住最大 URL 长度。我怀疑一个请求可以完成 170 个位置。
猜你喜欢
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
相关资源
最近更新 更多