如何精简MKMapKit中的多个坐标折线条目 [英] How to streamline multiple coordinate poly line entries in MKMapKit

查看:97
本文介绍了如何精简MKMapKit中的多个坐标折线条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用mkmapkit将多条折线添加到地图上.这些折线表示我所在区域的步行区域.问题是我的代码对于大量的步行区域而言过于庞大.

I am trying to add multiple poly lines onto a map using mkmapkit. These poly lines indicate walking zones in my area. The problem is that my code is too bulky for a large amount of walking zones.

目前,我的代码仅指示2条步行路线,但是例如,如果我想添加100或1000条步行路线,则该代码将非常庞大.我敢肯定,有一种方法可以简化此代码,以便可以用更少的代码添加多个步行区域,但并不确定最好的解决方法.

At the moment my code only indicates 2 walking routes but for instance if I want to add 100 or 1000 walking routes the code would be massive. I'm sure there is a way I could stream line this code so I could add in multiple walking zones with a lot less code but in not too sure the best way to go about it.

import UIKit
import MapKit

class customPin: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?

init(pinTitle:String, pinSubTitle:String, location:CLLocationCoordinate2D) {
    self.title = pinTitle
    self.subtitle = pinSubTitle
    self.coordinate = location
}
}

class ViewController: UIViewController, MKMapViewDelegate {

@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //co-ordinates
    let zone1S = CLLocationCoordinate2D(latitude: 52.100525, longitude: -9.623071)
    let zone1E = CLLocationCoordinate2D(latitude: 52.07241, longitude: -9.575299)

    let zone2S = CLLocationCoordinate2D(latitude: 52.054161, longitude: -9.385031)
    let zone2E = CLLocationCoordinate2D(latitude: 52.081185, longitude: -9.247033)


    //pins
    let zone1PinS = customPin(pinTitle: "Zone 1 Start", pinSubTitle: "", location: zone1S)
    let zone1PinE = customPin(pinTitle: "Zone 1 End", pinSubTitle: "", location: zone1E)
    self.mapView.addAnnotation(zone1PinS)
    self.mapView.addAnnotation(zone1PinE)

    let zone2PinS = customPin(pinTitle: "Zone 2 Start", pinSubTitle: "", location: zone2S)
    let zone2PinE = customPin(pinTitle: "Zone 2 End", pinSubTitle: "", location: zone2E)
    self.mapView.addAnnotation(zone2PinS)
    self.mapView.addAnnotation(zone2PinE)


    let zone1PlacemarkS = MKPlacemark(coordinate: zone1S)
    let zone1PlacemarkE = MKPlacemark(coordinate: zone1E)

    let zone2PlacemarkS = MKPlacemark(coordinate: zone2S)
    let zone2PlacemarkE = MKPlacemark(coordinate: zone2E)


    //add polyline to map
    let directionRequestZone1 = MKDirections.Request()
    directionRequestZone1.source = MKMapItem(placemark: zone1PlacemarkS)
    directionRequestZone1.destination = MKMapItem(placemark: zone1PlacemarkE)

    let directionRequestZone2 = MKDirections.Request()
    directionRequestZone2.source = MKMapItem(placemark: zone2PlacemarkS)
    directionRequestZone2.destination = MKMapItem(placemark: zone2PlacemarkE)


    //type of commute
    directionRequestZone1.transportType = .automobile
     directionRequestZone2.transportType = .automobile


    let directions1 = MKDirections(request: directionRequestZone1)
    directions1.calculate { (response, error) in
        guard let directionResonse = response else {
            if let error = error {
                print("we have error getting directions==\(error.localizedDescription)")
            }
            return
        }

        let route = directionResonse.routes[0]
        self.mapView.addOverlay(route.polyline, level: .aboveRoads)


        let rect = route.polyline.boundingMapRect
        //zooming in on location
       // self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
    }


    let directions2 = MKDirections(request: directionRequestZone2)
    directions2.calculate { (response, error) in
        guard let directionResonse = response else {
            if let error = error {
                print("we have error getting directions==\(error.localizedDescription)")
            }
            return
        }

        let route2 = directionResonse.routes[0]
        self.mapView.addOverlay(route2.polyline, level: .aboveRoads)


        let rect = route2.polyline.boundingMapRect
        //zooming in on location
       // self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
    }


    //set delegate for mapview
    self.mapView.delegate = self
}


func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let renderer = MKPolylineRenderer(overlay: overlay)
    renderer.strokeColor = UIColor.red
    renderer.lineWidth = 5.0
    return renderer
}
}

这是它的外观:

更新: 我使用循环的尝试无效.我似乎有一个循环可用于放置起点和终点区域的销钉,但似乎对绘制折线不起作用.

UPDATE: My attempt to use loops hasn't worked. I seem to have a loop working for dropping the start and end zone pins however it doesn't seem to work for drawing the poly lines.

        struct Location {
        let title: String
        let latitude: Double
        let longitude: Double
    }

    let locationsStart = [
        Location(title: "Start",    latitude: 52.100525, longitude: -9.623071)
    ]

    let locationsEnd = [
        Location(title: "End",    latitude: 52.07241, longitude: -9.575299)
    ]

    for location in locationsStart {
        let annotation = MKPointAnnotation()
        annotation.title = location.title
        annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
        mapView.addAnnotation(annotation)

        let directionRequestZone1 = MKDirections.Request()
        let zonePlacemarkS = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
        let directionRequest = MKDirections.Request()
        directionRequest.source = MKMapItem(placemark: zonePlacemarkS)
        directionRequestZone1.transportType = .automobile
    }

    for location in locationsEnd {
        let annotation = MKPointAnnotation()
        annotation.title = location.title
        annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
        mapView.addAnnotation(annotation)

        let directionRequestZone1 = MKDirections.Request()
        let zonePlacemarkE = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
        let directionRequest = MKDirections.Request()
        directionRequest.destination = MKMapItem(placemark: zonePlacemarkE)
        directionRequestZone1.transportType = .automobile

        let directions1 = MKDirections(request: directionRequestZone1)
        directions1.calculate { (response, error) in
            guard let directionResonse = response else {
                if let error = error {
                    print("we have error getting directions==\(error.localizedDescription)")
                }
                return
            }

            let route = directionResonse.routes[0]
            self.mapView.addOverlay(route.polyline, level: .aboveRoads)


            let rect = route.polyline.boundingMapRect
        }
    }
           //set delegate for mapview
           self.mapView.delegate = self
}


func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let renderer = MKPolylineRenderer(overlay: overlay)
    renderer.strokeColor = UIColor.red
    renderer.lineWidth = 5.0
    return renderer
}

推荐答案

我对您的代码进行了如下修改:

I adapted your code as follows:

let zone1S = CLLocationCoordinate2D(latitude: 52.100525, longitude: -9.623071)
let zone1E = CLLocationCoordinate2D(latitude: 52.07241, longitude: -9.575299)
let zone2S = CLLocationCoordinate2D(latitude: 52.054161, longitude: -9.385031)
let zone2E = CLLocationCoordinate2D(latitude: 52.081185, longitude: -9.247033)

let zones = [(start:zone1S, end:zone1E), (start:zone2S, end:zone2E)]
for (i, zone) in zones.enumerated() {
    let pinS = customPin(pinTitle: "Zone \(i+1) Start", pinSubTitle: "", location: zone.start)
    let pinE = customPin(pinTitle: "Zone \(i+1) End", pinSubTitle: "", location: zone.end)
    self.mapView.addAnnotation(pinS)
    self.mapView.addAnnotation(pinE)
    let placeS = MKPlacemark(coordinate: zone.start)
    let placeE = MKPlacemark(coordinate: zone.end)
    let req = MKDirections.Request()
    req.source = MKMapItem(placemark: placeS)
    req.destination = MKMapItem(placemark: placeE)
    req.transportType = .automobile
    let dir = MKDirections(request: req)
    dir.calculate { (response, error) in
        guard let directionResponse = response else {
            if let error = error {
                print("we have error getting directions==\(error.localizedDescription)")
            }
            return
        }
        DispatchQueue.main.async {
            let route = directionResponse.routes[0]
            self.mapView.addOverlay(route.polyline, level: .aboveRoads)
        }
    }
}

很显然,这可以简单地扩展到任意数量的区域. (也许我们应该使用DispatchGroup之类的东西来防止网络calculate调用堆积得太快,但目标是要解决两对坐标,这似乎很好.)

Clearly this can be trivially extended to any number of zones. (It may be that we should be using something like a DispatchGroup to prevent the networking calculate calls from piling up too quickly, but the goal was to solve it for two pairs of coordinates and this seems to work fine.)

这篇关于如何精简MKMapKit中的多个坐标折线条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆