Ios 在Swift中在地图上显示路线
我正在苹果地图上画两点之间的路线(Swift代码)。 以下结构用于存储坐标Ios 在Swift中在地图上显示路线,ios,swift,Ios,Swift,我正在苹果地图上画两点之间的路线(Swift代码)。 以下结构用于存储坐标 struct GeoLocation { var latitude: Double var longitude: Double func distanceBetween(other: GeoLocation) -> Double { let locationA = CLLocation(latitude: self.latitude, longitude: self.lon
struct GeoLocation {
var latitude: Double
var longitude: Double
func distanceBetween(other: GeoLocation) -> Double {
let locationA = CLLocation(latitude: self.latitude, longitude: self.longitude)
let locationB = CLLocation(latitude: other.latitude, longitude: other.longitude)
return locationA.distanceFromLocation(locationB)
}
}
self.foundLocations - is an array of these structures
在自定义类中,我接收地图上点的坐标
var coordinates = self.foundLocations.map{$0.coordinate}
然后我在地图上画出路线
self.polyline = MKPolyline(coordinates: &coordinates, count: coordinates.count)
self.mapView.addOverlay(self.polyline, level: MKOverlayLevel.AboveRoads)
为了绘制路线,我从MKMapViewDelegate使用以下方法
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if let polylineOverlay = overlay as? MKPolyline {
let render = MKPolylineRenderer(polyline: polylineOverlay)
render.strokeColor = UIColor.blueColor()
return render
}
return nil
}
我得到的是两点之间的一条直线,而不是铺设在道路上的实际路线。
如何显示实际路线?您实际上必须使用CompletionHandler从Apple地图服务器获取路线 首先为源和目标创建相关的
MKMapItem
s,例如:
let geocoder = CLGeocoder()
let location = CLLocation(latitude: sourceLatitude, longitude: sourceLongitude)
geocoder.reverseGeocodeLocation(location, completionHandler: {
(placemarks:[AnyObject]?, error:NSError?) -> Void in
if placemarks?.count > 0 {
if let placemark: MKPlacemark = placemarks![0] as? MKPlacemark {
self.source = MKMapItem(placemark: placemark)
}
}
})
(对目的地重复此操作。)
然后获取MKRoute
,例如:
let request:MKDirectionsRequest = MKDirectionsRequest()
// source and destination are the relevant MKMapItems
request.setSource(source)
request.setDestination(destination)
// Specify the transportation type
request.transportType = MKDirectionsTransportType.Automobile;
// If you're open to getting more than one route,
// requestsAlternateRoutes = true; else requestsAlternateRoutes = false;
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler ({
(response: MKDirectionsResponse?, error: NSError?) in
if error == nil {
self.directionsResponse = response
// Get whichever currentRoute you'd like, ex. 0
self.route = directionsResponse.routes[currentRoute] as MKRoute
}
})
然后,在检索MKRoute
后,可以将多段线添加到地图中,如下所示:
mapView.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
Swift 3和Lyndsey Scott答案的可重复使用转换:
final class Route {
static func getRouteFor(
source: CLLocationCoordinate2D,
destination: CLLocationCoordinate2D,
completion: @escaping (
_ route: MKRoute?,
_ error: String?)->()
) {
let sourceLocation = CLLocation(
latitude: source.latitude,
longitude: source.longitude
)
let destinationLocation = CLLocation(
latitude: destination.latitude,
longitude: destination.longitude
)
let request = MKDirectionsRequest()
self.getMapItemFor(location: sourceLocation) { sourceItem, error in
if let e = error {
completion(nil, e)
}
if let s = sourceItem {
self.getMapItemFor(location: destinationLocation) { destinationItem, error in
if let e = error {
completion(nil, e)
}
if let d = destinationItem {
request.source = s
request.destination = d
request.transportType = .walking
let directions = MKDirections(request: request)
directions.calculate(completionHandler: { response, error in
if let r = response {
let route = r.routes[0]
completion(route, nil)
}
})
}
}
}
}
}
static func getMapItemFor(
location: CLLocation,
completion: @escaping (
_ placemark: MKMapItem?,
_ error: String?)->()
) {
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { placemark, error in
if let e = error {
completion(nil, e.localizedDescription)
}
if let p = placemark {
if p.count < 1 {
completion(nil, "placemark count = 0")
} else {
if let mark = p[0] as? MKPlacemark {
completion(MKMapItem(placemark: mark), nil)
}
}
}
}
}
}
最终课程路线{
静态函数getRouteFor(
资料来源:CLLocationCoordinate2D,
目的地:CLLocationCoordinate2D,
完成:@转义(
_路线:MKRoute?,
_错误:字符串?->()
) {
让sourceLocation=CLLocation(
纬度:source.latitude,
经度:source.longitude
)
让destinationLocation=CLLocation(
纬度:目的地。纬度,
经度:destination.longitude
)
let request=mkdirectionrequest()
self.getMapItemFor(位置:sourceLocation){sourceItem,中出错
如果让e=错误{
完成(无,e)
}
如果让s=sourceItem{
self.getMapItemFor(位置:destinationLocation){destinationItem,中有错误
如果让e=错误{
完成(无,e)
}
如果设d=目的地{
request.source=s
request.destination=d
request.transportType=.walking
let directions=MKDirections(请求:请求)
计算(completionHandler:{响应,错误在
如果让r=响应{
let route=r.routes[0]
完成(路线,无)
}
})
}
}
}
}
}
静态函数getMapItemFor(
地点:CLLocation,,
完成:@转义(
_placemark:MKMapItem?,
_错误:字符串?->()
) {
让geocoder=CLGeocoder()
地理编码器。反向地理位置(位置){placemark,错误在
如果让e=错误{
完成(无,例如本地化描述)
}
如果设p=placemark{
如果p.count<1{
完成(无,“placemark计数=0”)
}否则{
如果let mark=p[0]为?MKPlacemark{
完成(MKMapItem(placemark:mark),无)
}
}
}
}
}
}
用法:
Route.getRouteFor(source: CLLocationCoordinate2D, destination: CLLocationCoordinate2D) { (MKRoute?, String?) in
<#code#>
}
Route.getRouteFor(源:CLLocationCoordinate2D,目的地:CLLocationCoordinate2D){(MKRoute?,String?)在
}
您能看到这个错误吗