繁体   English   中英

我可以为折线绘制缩略图吗?

[英]Can I draw a thumbnail for a polyline?

如果我有一条折线的路径另存为string

从谷歌地图SDK: path.encodedPath()

或者我有一系列的latlng s指向,

我可以为该路径绘制缩略图吗?

我不想在mapView上绘制它,我想知道是否可以在任何其他视图(例如imageView或类似的东西)中绘制它。

我创建了swift 3代码,您可以将其复制并粘贴到操场上并立即查看结果

代码在这里:

import UIKit
import PlaygroundSupport

var str = "Hello, playground"

//All you need is to create a path with that points and create image or layer with that path

//To perpare for this let make some extensions with helper code
//Extension for UIBeziePath to easily create it from points
extension UIBezierPath
{
    convenience init(points:[CGPoint])
    {

        self.init()

        //connect every points by line.
        //the first point is start point
        for (index,aPoint) in points.enumerated()
        {
            if index == 0 {
                self.move(to: aPoint)
            }
            else {
                self.addLine(to: aPoint)
            }
        }
    }
}

//to create image from path you can use this class function
extension UIImage
{
    class func imageFrom(path:UIBezierPath,lineColor:UIColor,fillColor:UIColor)->UIImage
    {
        //create context to draw in use path bounds as context size. assume that path is inzide of rect with start corener at 0,0 coordinate
        UIGraphicsBeginImageContextWithOptions(path.bounds.size, false, 0)

        print("path bounds \(path.bounds) lineWidth:\(path.lineWidth)")

        let context = UIGraphicsGetCurrentContext()

        //set fill color
        context?.setFillColor(fillColor.cgColor)
        //set line coolor
        context?.setStrokeColor(lineColor.cgColor)
        context?.setLineWidth(path.lineWidth)

        //draw a path
        context?.addPath(path.cgPath)
        context?.drawPath(using: .fillStroke)
        //get image from context
        let image = UIGraphicsGetImageFromCurrentImageContext()!

        //finish context
        UIGraphicsEndImageContext()

        return image
    }
}


//2. To create layer use this extension

extension CAShapeLayer
{
    convenience init(path:UIBezierPath, lineColor:UIColor, fillColor:UIColor)
    {
        self.init()
        self.path = path.cgPath
        self.strokeColor = lineColor.cgColor
        self.fillColor = fillColor.cgColor
        self.lineWidth = path.lineWidth

        self.opacity = 1
        self.frame = path.bounds
    }
}

//how to use:

//1. assume you recieved points
let points:[CGPoint] = [CGPoint(x: 0, y: 0),CGPoint(x: 150, y: 50),CGPoint(x: 75, y:140),CGPoint(x: 0, y: 80)]

//2. create path
let path = UIBezierPath(points: points)

//3. you can specify path line width
path.lineWidth = 2

//4. as a joinstyle too
path.lineJoinStyle = .round


//5. a)now you can create image from path with helper function
let image = UIImage.imageFrom(path: path, lineColor: UIColor.purple, fillColor: UIColor.red)
print(image)

//and set it to imageView
let imageView = UIImageView(image: image)
imageView.frame.origin = CGPoint(x: 200, y: 200)
imageView.backgroundColor = UIColor.green

//5. Maybe you will need to specify content mode for imageView
imageView.contentMode = .scaleAspectFit

//5 b.) Or you can create a Layer. Add add it to someone's layer layter

//if you need, you can apply transform to path - this is special way to 
//adjust scale, rotation an lots of other cool stuff on layers, paths.

//Create special struct which descripbes transformation
//Identity is a special case which does not make any transformations at all
var transform = CGAffineTransform.identity

//scale it by 0.5 for x and 0.5 for y. if you need to increse scale by
//100 times, just pass 100 for x and y arguments
transform = transform.scaledBy(x:  0.5, y: 0.5)

//no apply transform to path.
path.apply(transform)

let layer = CAShapeLayer(path: path, lineColor: UIColor.blue, fillColor: UIColor.brown)

//6. let see results

let container = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
container.backgroundColor = UIColor.white

//for imageView
container.addSubview(imageView)

//for CAShapeLayer
container.layer.addSublayer(layer)


//for playGround you can set this to see result there
//Do not forget to select from menu
//View -> Assistant Editor-> Show Assistance Editor
PlaygroundPage.current.liveView = container
PlaygroundPage.current.needsIndefiniteExecution = true

///此外,我不得不提到CAShapeLayer解决方案占用的内存更少,这对于真正的大图像而言至关重要///但是UIImage更易于使用

棕色的图形是路径缩放为0.5的图层,红色的是imageView

在此处输入图片说明

如果您有一系列maxLat, maxLong, minLat, minLong可以知道最大和maxLat, maxLong, minLat, minLong说它们是: maxLat, maxLong, minLat, minLong 请注意,两个最大值不必属于同一坐标。 两个最小值均相同。

您可以使用它来获得一个rect:

    let rect = CGRect(x: minLng , y: minLat, width: (maxLng - minLng), height: (maxLat - minLat))

现在,所有其他纬度都是该矩形中的点。 您可以通过以下方式获取每个coordinate的对应CGPoint值:

    let point = CGPoint(x: maxLng - coordinate.longitude, y: maxLat - coordinate.latitude)

使用此矩形和您创建的一系列CGPoint,可以在视图(如您在答案中提到的图像视图)上绘制路径(从第一个点开始并向其添加所有后续点)。只是创建路径的缩略图并将其另存为图像。

如果您不熟悉CGContexts中的绘图,请参考绘图和打印指南

但是,如果您打算将此等效路径的缩略图放在图像上,那么真正的挑战是,您将如何知道位置。 一个简单的技巧就是获取图像的等效于地图的最小最大坐标,您要在该坐标上叠加路径缩略图并使用这些最小最大值来创建路径和上下文。 然后,您可以将缩略图居中放置在图像上。

您的项目听起来很有趣。 享受,祝你好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM