如何在 swift 3 中将 MKPolylines 添加到 MKSnapShotter?
Posted
技术标签:
【中文标题】如何在 swift 3 中将 MKPolylines 添加到 MKSnapShotter?【英文标题】:How do you add MKPolylines to MKSnapShotter in swift 3? 【发布时间】:2016-07-18 22:18:57 【问题描述】:有没有办法截取 mapView 并包含折线?我相信我需要在 MKSnapShotter 返回的图像上绘制 CGPoint,但我不确定如何这样做。
当前代码
func takeSnapshot(mapView: MKMapView, withCallback: (UIImage?, NSError?) -> ())
let options = MKMapSnapshotOptions()
options.region = mapView.region
options.size = mapView.frame.size
options.scale = UIScreen.main().scale
let snapshotter = MKMapSnapshotter(options: options)
snapshotter.start() snapshot, error in
guard snapshot != nil else
withCallback(nil, error)
return
if let image = snapshot?.image
withCallback(image, nil)
for coordinate in self.area
image.draw(at:snapshot!.point(for: coordinate))
【问题讨论】:
在Putting Map Kit in Perspective 视频中,Apple 演示了如果您想在快照中包含注释,您必须自己手动绘制它们。 (令人困惑,是的,但事实就是如此。)我认为MKPolyline
之类的叠加层也是如此。
谢谢,我去看看。
好的,视频内容丰富,但并没有真正的帮助。
我原以为演示,在快照中手动渲染注释图钉,会给你足够的线索如何用覆盖做等效的......
【参考方案1】:
我今天也遇到了同样的问题。经过几个小时的研究,这是我的解决方法。
以下代码在 Swift 3 中。
1。初始化你的折线坐标数组
// initial this array with your polyline coordinates
var yourCoordinates = [CLLocationCoordinate2D]()
yourCoorinates.append( coordinate 1 )
yourCoorinates.append( coordinate 2 )
...
// you can use any data structure you like
2。照常拍摄快照,但根据您的坐标设置区域:
func takeSnapShot()
let mapSnapshotOptions = MKMapSnapshotOptions()
// Set the region of the map that is rendered. (by polyline)
let polyLine = MKPolyline(coordinates: &yourCoordinates, count: yourCoordinates.count)
let region = MKCoordinateRegionForMapRect(polyLine.boundingMapRect)
mapSnapshotOptions.region = region
// Set the scale of the image. We'll just use the scale of the current device, which is 2x scale on Retina screens.
mapSnapshotOptions.scale = UIScreen.main.scale
// Set the size of the image output.
mapSnapshotOptions.size = CGSize(width: IMAGE_VIEW_WIDTH, height: IMAGE_VIEW_HEIGHT)
// Show buildings and Points of Interest on the snapshot
mapSnapshotOptions.showsBuildings = true
mapSnapshotOptions.showsPointsOfInterest = true
let snapShotter = MKMapSnapshotter(options: mapSnapshotOptions)
snapShotter.start() snapshot, error in
guard let snapshot = snapshot else
return
// Don't just pass snapshot.image, pass snapshot itself!
self.imageView.image = self.drawLineOnImage(snapshot: snapshot)
3。使用 snapshot.point() 在 Snapshot Image 上绘制折线
func drawLineOnImage(snapshot: MKMapSnapshot) -> UIImage
let image = snapshot.image
// for Retina screen
UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, true, 0)
// draw original image into the context
image.draw(at: CGPoint.zero)
// get the context for CoreGraphics
let context = UIGraphicsGetCurrentContext()
// set stroking width and color of the context
context!.setLineWidth(2.0)
context!.setStrokeColor(UIColor.orange.cgColor)
// Here is the trick :
// We use addLine() and move() to draw the line, this should be easy to understand.
// The diificult part is that they both take CGPoint as parameters, and it would be way too complex for us to calculate by ourselves
// Thus we use snapshot.point() to save the pain.
context!.move(to: snapshot.point(for: yourCoordinates[0]))
for i in 0...yourCoordinates.count-1
context!.addLine(to: snapshot.point(for: yourCoordinates[i]))
context!.move(to: snapshot.point(for: yourCoordinates[i]))
// apply the stroke to the context
context!.strokePath()
// get the image from the graphics context
let resultImage = UIGraphicsGetImageFromCurrentImageContext()
// end the graphics context
UIGraphicsEndImageContext()
return resultImage!
就是这样,希望这对某人有帮助。
参考文献
How do I draw on an image in Swift?
MKTileOverlay,MKMapSnapshotter & MKDirections
Creating an MKMapSnapshotter with an MKPolylineRenderer
Render a Map as an Image using MapKit
【讨论】:
@user287589 如何计算区域跨度以在快照上插入? @AymenHARRATH 我不知道。对不起 我尝试运行这个 sn-p 代码。它在这一行中给了我以下错误: context!.setLineWidth(2.0) 错误消息说:“致命错误:在展开可选值时意外发现 nil”【参考方案2】:有什么问题:
snapshotter.start( completionHandler: snapshot, error in
guard snapshot != nil else
withCallback(nil, error)
return
if let image = snapshot?.image
withCallback(image, nil)
for coordinate in self.area
image.draw(at:snapshot!.point(for: coordinate))
)
【讨论】:
我最终只是将坐标存储在一个数组中,然后将它们显示在我在另一个视图中创建的地图上。【参考方案3】:如果您只想要用户在 MKMapView 中看到的图像的副本,请记住它是 UIView 子类,因此您可以这样做...
public extension UIView
public var snapshot: UIImage?
get
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
// ...
if let img = self.mapView.snapshot
// Do something
【讨论】:
以上是关于如何在 swift 3 中将 MKPolylines 添加到 MKSnapShotter?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Alamofire,swift 3 中将字典作为参数发送
如何在 Swift 3 中将 NSConstraints 添加到 UITextView
如何在 swift 3 中将 MKPolylines 添加到 MKSnapShotter?