MKMapKit中如何精简多个坐标折线入口
How to streamline multiple coordinate poly line entries in MKMapKit
我正在尝试使用 mkmapkit 在地图上添加多条折线。这些折线表示我所在地区的步行区。问题是我的代码对于大量步行区来说太庞大了。
目前我的代码仅指示 2 条步行路线,但例如,如果我想添加 100 或 1000 条步行路线,代码将非常庞大。我确信有一种方法可以简化这段代码,这样我就可以用更少的代码添加多个步行区,但不太确定最好的方法。
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
}
}
这是它的样子:
更新:
我尝试使用循环没有奏效。我似乎有一个循环用于删除开始和结束区域的引脚,但它似乎不适用于绘制多边形线。
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
}
我对你的代码进行了如下调整:
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
调用堆积得太快,但我们的目标是解决两对坐标的问题,这似乎工作正常。)
我正在尝试使用 mkmapkit 在地图上添加多条折线。这些折线表示我所在地区的步行区。问题是我的代码对于大量步行区来说太庞大了。
目前我的代码仅指示 2 条步行路线,但例如,如果我想添加 100 或 1000 条步行路线,代码将非常庞大。我确信有一种方法可以简化这段代码,这样我就可以用更少的代码添加多个步行区,但不太确定最好的方法。
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
}
}
这是它的样子:
更新: 我尝试使用循环没有奏效。我似乎有一个循环用于删除开始和结束区域的引脚,但它似乎不适用于绘制多边形线。
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
}
我对你的代码进行了如下调整:
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
调用堆积得太快,但我们的目标是解决两对坐标的问题,这似乎工作正常。)