有没有办法使用谷歌为 mkmapview 获取路线(只是路线)?
Posted
技术标签:
【中文标题】有没有办法使用谷歌为 mkmapview 获取路线(只是路线)?【英文标题】:Is there a way to get directions(just routes) using google for mkmapview? 【发布时间】:2015-09-28 16:50:21 【问题描述】:我在 ios 上使用 swift 并使用 MKMapView。 我一直在努力为用户提供从 - 到文本字段,并让用户在起点和终点之间有一种路线形式。我已经使用 Apple 的内置方向和地理编码 api 调用在 mkmapview 上工作。但是用了一段时间后发现很多国家都不支持苹果Apple - Supported Countries For Directions
那么有没有办法从谷歌地图 SDK 获取路线并将它们转换为 MKPolyline 或 MKOverlay?我没有使用谷歌地图,所以请记住这一点。我看到了这个问题iPhone: Using Google to get directions 它有一个答案,但最新的解决方案已经有 4 年历史了,而且它在 Objective-C 中。尽管我确实了解如何将 Objective-C 代码转换为 swift,但我宁愿不必经历整个项目。请记住,这是一个更大项目的一部分,所以我无法将整个项目切换到谷歌地图。
【问题讨论】:
Google 提供了获取特定位置之间路线的 API,您可以使用该 API 在 MKMapView 上绘制路径 可以用google SDK直接在MKMapView上绘制Routes吗? 在谷歌 api 响应中没有,您会找到由纬度和经度组合而成的折线对象。您必须在纬度和经度中解密它,然后您可以在任何地图上绘制路径 有现成的解决方案吗?谷歌会接受吗? 我认为 google 可以接受这个 【参考方案1】:我认为this *** answer 可以将编码的折线转换为MKPolyline。
答案是Objective-C版本,所以我尝试将其转换为Swift,示例代码:
func polyLineWithEncodedString(encodedString: String) -> MKPolyline
let bytes = (encodedString as NSString).UTF8String
let length = encodedString.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
var idx: Int = 0
var count = length / 4
var coords = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(count)
var coordIdx: Int = 0
var latitude: Double = 0
var longitude: Double = 0
while (idx < length)
var byte = 0
var res = 0
var shift = 0
do
byte = bytes[idx++] - 0x3F
res |= (byte & 0x1F) << shift
shift += 5
while (byte >= 0x20)
let deltaLat = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
latitude += Double(deltaLat)
shift = 0
res = 0
do
byte = bytes[idx++] - 0x3F
res |= (byte & 0x1F) << shift
shift += 5
while (byte >= 0x20)
let deltaLon = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
longitude += Double(deltaLon)
let finalLat: Double = latitude * 1E-5
let finalLon: Double = longitude * 1E-5
let coord = CLLocationCoordinate2DMake(finalLat, finalLon)
coords[coordIdx++] = coord
if coordIdx == count
let newCount = count + 10
let temp = coords
coords.dealloc(count)
coords = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(newCount)
for index in 0..<count
coords[index] = temp[index]
temp.destroy()
count = newCount
let polyLine = MKPolyline(coordinates: coords, count: coordIdx)
coords.destroy()
return polyLine
您可以尝试来自this GitHub link 的示例项目。
下图是使用 Google Direction API Web 服务在 MKMapView 上渲染从旧金山到圣何塞的路线。
【讨论】:
是的,我正在使用它,我可以确认它可以正常工作。 使用这个***.com/questions/28784034/… 这个算法有一些问题。对于某些路线,我在地图上得到了一些不相关的线。我为 ObjC 方法创建了一个类别并将其桥接到 swift 项目,完美运行!【参考方案2】:Swift 3 版本,略微精简,感谢ztan。
如果您想在没有 Google SDK 的情况下在 iOS 中使用 Google 地理折线。
func polyLineWithEncodedString(encodedString: String) -> [CLLocationCoordinate2D]
var myRoutePoints=[CLLocationCoordinate2D]()
let bytes = (encodedString as NSString).utf8String
var idx: Int = 0
var latitude: Double = 0
var longitude: Double = 0
while (idx < encodedString.lengthOfBytes(using: String.Encoding.utf8))
var byte = 0
var res = 0
var shift = 0
repeat
byte = bytes![idx] - 63
idx += 1
res |= (byte & 0x1F) << shift
shift += 5
while (byte >= 0x20)
let deltaLat = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
latitude += Double(deltaLat)
shift = 0
res = 0
repeat
byte = bytes![idx] - 63
idx += 1
res |= (byte & 0x1F) << shift
shift += 5
while (byte >= 0x20)
let deltaLon = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
longitude += Double(deltaLon)
myRoutePoints.append(CLLocation(latitude: Double(latitude * 1E-5), longitude: Double(longitude * 1E-5)).coordinate)
return myRoutePoints
【讨论】:
【参考方案3】:使用google api 查找起点和终点之间的路线。
必填参数:
origin : lat + long 当前位置或地点 ID .
destination : lat + long 目标位置或地点 ID .
密钥:创建新的 google api 密钥。
可选参数:
模式(默认为驾驶)驾驶为您提供更多选择,或设置 步行、骑自行车、公交。 alternatives : false 只给你一条路线,选项 true 给出起点和目的地之间的所有方向,然后你可以选择哪个 路线您希望在持续时间或腿内距离上有所帮助。然后使用 Polyline 库将点(在 overview_polyline 内)转换为 CLLocationCoordinate2D 列表 https://github.com/raphaelmor/Polyline
像这样:
func convertPointToCoordinates() -> [CLLocationCoordinate2D]?
让 polyline = Polyline(encodedPolyline: overviewPolyline.points ?? "")
返回折线.坐标
让坐标 = convertPointToCoordinates()
让 polyLine = MKPolyline(coordinates: 坐标?? [], count: (coordinates?.count ?? 0))
在地图视图上添加折线:
self.mapView.add(polyLine)
专注于折线区域:
self.mapView.setVisibleMapRect(polyLine.boundingMapRect, edgePadding: UIEdgeInsets.init(top: 60, left: 60, bottom: 60, right: 60), 动画: true)
【讨论】:
以上是关于有没有办法使用谷歌为 mkmapview 获取路线(只是路线)?的主要内容,如果未能解决你的问题,请参考以下文章
谷歌为Chromebook推出双系统启动软件:可装Windows