在 UIImage 中渲染 MKPolyline
Render a MKPolyline in a UIImage
我需要在不使用 MKMapView
的情况下在 UIImage
中渲染 MKPolyline
(主要是出于性能原因,我想尽快显示路径,而地图截屏器异步提供地图,就像应用程序 Strava 所做的那样)。
我想出了这段代码:
func pathImageForSize(size: CGSize) -> UIImage {
let region = regionForPath() // MKCoordinateRegion
let coordinates = locations.map { [=10=].coordinate }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
CGContextSetStrokeColorWithColor(context, UIColor.palette_mainColor().CGColor)
CGContextSetLineWidth(context, 4.0)
CGContextBeginPath(context)
let origin = CGPoint(x: region.center.latitude - region.span.latitudeDelta / 2, y: region.center.longitude - region.span.longitudeDelta / 2)
for (index, coordinate) in coordinates.enumerate() {
let point = CGPoint(x: ((CGFloat(coordinate.latitude) - origin.x) / CGFloat(region.span.latitudeDelta)) * size.width,
y: ((CGFloat(coordinate.longitude) - origin.y) / CGFloat(region.span.longitudeDelta)) * size.height)
if index == 0 {
CGContextMoveToPoint(context, point.x, point.y)
} else {
CGContextAddLineToPoint(context, point.x, point.y)
}
}
CGContextStrokePath(context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
代码基本上重新缩放坐标并使用 CoreGraphics 绘制它们。
路径已绘制,但也旋转了 90 度,如下所示:
MapKit 渲染的多段线:
我的代码呈现的多段线:
知道我做错了什么吗?
我怀疑这是因为您将纬度用作 'x',将经度用作 'y'。纬度是垂直维度(在顶部为北的地图上),经度是水平维度。
好的,明白了,我的前提是错误的:
我正在计算的区域封装了路径的坐标,但该区域在渲染时由 mapview 进行了调整。解决方案是缩放区域以适合地图视图的框架:
let map = MKMapView(frame: CGRect(origin: CGPoint.zero, size: size))
let region = map.regionThatFits(regionForPath())
此外,正如 BrentM 所建议的那样,坐标被翻转了。结果代码是这样的:
func pathImageForSize(size: CGSize) -> UIImage {
let map = MKMapView(frame: CGRect(origin: CGPoint.zero, size: size))
let region = map.regionThatFits(regionForPath())
let coordinates = locations.map { [=11=].coordinate }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
CGContextSetLineJoin(context, .Round)
CGContextSetLineCap(context, .Round)
CGContextSetStrokeColorWithColor(context, UIColor.palette_mainColor().CGColor)
CGContextSetLineWidth(context, 4.0)
CGContextBeginPath(context)
let origin = CGPoint(x: region.center.longitude - region.span.longitudeDelta / 2, y: region.center.latitude - region.span.latitudeDelta / 2)
for (index, coordinate) in coordinates.enumerate() {
let point = CGPoint(x: ((CGFloat(coordinate.longitude) - origin.x) / CGFloat(region.span.longitudeDelta)) * size.width,
y: ((CGFloat(coordinate.latitude) - origin.y) / CGFloat(region.span.latitudeDelta)) * size.height)
if index == 0 {
CGContextMoveToPoint(context, point.x, size.height - point.y)
} else {
CGContextAddLineToPoint(context, point.x, size.height - point.y)
}
}
CGContextStrokePath(context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
我需要在不使用 MKMapView
的情况下在 UIImage
中渲染 MKPolyline
(主要是出于性能原因,我想尽快显示路径,而地图截屏器异步提供地图,就像应用程序 Strava 所做的那样)。
我想出了这段代码:
func pathImageForSize(size: CGSize) -> UIImage {
let region = regionForPath() // MKCoordinateRegion
let coordinates = locations.map { [=10=].coordinate }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
CGContextSetStrokeColorWithColor(context, UIColor.palette_mainColor().CGColor)
CGContextSetLineWidth(context, 4.0)
CGContextBeginPath(context)
let origin = CGPoint(x: region.center.latitude - region.span.latitudeDelta / 2, y: region.center.longitude - region.span.longitudeDelta / 2)
for (index, coordinate) in coordinates.enumerate() {
let point = CGPoint(x: ((CGFloat(coordinate.latitude) - origin.x) / CGFloat(region.span.latitudeDelta)) * size.width,
y: ((CGFloat(coordinate.longitude) - origin.y) / CGFloat(region.span.longitudeDelta)) * size.height)
if index == 0 {
CGContextMoveToPoint(context, point.x, point.y)
} else {
CGContextAddLineToPoint(context, point.x, point.y)
}
}
CGContextStrokePath(context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
代码基本上重新缩放坐标并使用 CoreGraphics 绘制它们。 路径已绘制,但也旋转了 90 度,如下所示:
MapKit 渲染的多段线:
我的代码呈现的多段线:
知道我做错了什么吗?
我怀疑这是因为您将纬度用作 'x',将经度用作 'y'。纬度是垂直维度(在顶部为北的地图上),经度是水平维度。
好的,明白了,我的前提是错误的: 我正在计算的区域封装了路径的坐标,但该区域在渲染时由 mapview 进行了调整。解决方案是缩放区域以适合地图视图的框架:
let map = MKMapView(frame: CGRect(origin: CGPoint.zero, size: size))
let region = map.regionThatFits(regionForPath())
此外,正如 BrentM 所建议的那样,坐标被翻转了。结果代码是这样的:
func pathImageForSize(size: CGSize) -> UIImage {
let map = MKMapView(frame: CGRect(origin: CGPoint.zero, size: size))
let region = map.regionThatFits(regionForPath())
let coordinates = locations.map { [=11=].coordinate }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
CGContextSetLineJoin(context, .Round)
CGContextSetLineCap(context, .Round)
CGContextSetStrokeColorWithColor(context, UIColor.palette_mainColor().CGColor)
CGContextSetLineWidth(context, 4.0)
CGContextBeginPath(context)
let origin = CGPoint(x: region.center.longitude - region.span.longitudeDelta / 2, y: region.center.latitude - region.span.latitudeDelta / 2)
for (index, coordinate) in coordinates.enumerate() {
let point = CGPoint(x: ((CGFloat(coordinate.longitude) - origin.x) / CGFloat(region.span.longitudeDelta)) * size.width,
y: ((CGFloat(coordinate.latitude) - origin.y) / CGFloat(region.span.latitudeDelta)) * size.height)
if index == 0 {
CGContextMoveToPoint(context, point.x, size.height - point.y)
} else {
CGContextAddLineToPoint(context, point.x, size.height - point.y)
}
}
CGContextStrokePath(context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}