2016-11-29 13 views
5

nếu tôi có một con đường cho một polyline lưu lại dưới dạng string,Tôi có thể vẽ hình thu nhỏ cho một polyline không?

Từ bản đồ google sdk: path.encodedPath()

Hoặc tôi có một loạt các latlng s điểm,

Tôi có thể vẽ một hình thu nhỏ cho rằng con đường ?

Tôi không muốn vẽ nó trên mapView, tôi tự hỏi nếu tôi có thể vẽ nó trong bất kỳ chế độ xem nào khác như imageView hoặc bất kỳ điều gì tương tự.

+0

'UIBezierPath'? –

+0

Không, tôi không có nghĩa là, 'polyline' đang vẽ trên' bản đồ', tôi cần nó là 'hình ảnh' @ 季 亨达 – wajeeh

+0

Một khả năng khác là sử dụng' điểm (cho tọa độ: CLLocationCoordinate2D) -> Chức năng CGPoint' trên thuộc tính 'chiếu' của bạn mapView để chuyển đổi' CLLocationCoordinate2D' thành các tọa độ xem ('CGPoint' s).Sau đó bạn có thể vẽ các điểm này vào một 'UIBezierPath' và lấy một screenShot từ' UIView'. Hy vọng có cách tiếp cận tốt hơn không phụ thuộc vào SDK Google Maps và không cần một phiên bản GMSMapView. –

Trả lời

3

Tôi tạo ra nhanh chóng 3 mã mà bạn chỉ có thể sao chép và dán vào sân chơi và xem kết quả ngay lập tức

mã là ở đây:

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 

// Ngoài ra tôi có đề cập đến rằng giải pháp CAShapeLayer mất ít bộ nhớ, điều quan trọng đối với các hình ảnh thực sự lớn // nhưng UIImage dễ sử dụng hơn

hình nâu là lớp với đường theo tỷ lệ 0,5, là màu đỏ là IMAGExem

enter image description here

+0

Thực ra câu trả lời của bạn giúp tôi vẽ đường dẫn trên lớp, Nhưng như bạn đã biết khoảng cách trong hệ thống 'latlng' rất gần giống' 0,001' giữa nhau, Vì vậy, đồ thị trông giống như một dấu chấm. Tôi đã thử nhiều lần để chia tỷ lệ hình ảnh thành kích thước '200x200' nhưng tôi đã không thành công, cách tạo giới hạn cho hình dạng mới và lấp đầy toàn bộ không gian bằng nó? – wajeeh

+0

@wajeeh Tôi đã cập nhật mã nơi bạn có thể xem cách bạn có thể mở rộng đường dẫn. –

+0

Cảm ơn bạn, tôi sẽ kiểm tra nó – wajeeh

2

Nếu bạn có một loạt các chờ đợi lat, bạn có thể biết được tối đa và tối thiểu lat dài, nói rằng họ là: maxLat, maxLong, minLat, minLong. Vui lòng không phải rằng cả hai giá trị tối đa đều không thuộc cùng một tọa độ. Tương tự cho cả hai giá trị min.

Bạn có thể sử dụng điều này để có được một rect:

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

Bây giờ, tất cả chờ đợi lat khác là những điểm trong hình chữ nhật này. Bạn có thể nhận được tất cả coordinate 's tương ứng với giá trị CGPoint bởi

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

Sử dụng rect này và hàng loạt các CGPoints bạn đã tạo, bạn có thể vẽ một đường dẫn (bằng cách bắt đầu với điểm đầu tiên và thêm tất cả các điểm tiếp theo với nó) trên một chế độ xem (giống như chế độ xem hình ảnh bạn đề cập trong câu trả lời) hoặc tạo ngữ cảnh đồ họa chỉ để tạo hình thu nhỏ của đường dẫn và lưu nó dưới dạng hình ảnh.

Tham khảo drawing and printing guide nếu bạn không quen với việc vẽ trong CGContexts.

Tuy nhiên, nếu bạn muốn đặt hình thu nhỏ này tương đương với đường dẫn trên hình ảnh thì thử thách thực sự là, bạn sẽ biết vị trí như thế nào. Một mẹo đơn giản là lấy tọa độ tối đa tương đương với bản đồ của hình ảnh mà bạn muốn đặt chồng lên hình thu nhỏ của đường dẫn và sử dụng các giá trị tối thiểu tối thiểu này để tạo đường dẫn và ngữ cảnh. Sau đó, bạn có thể căn giữa hình thu nhỏ trên hình ảnh.

Dự án của bạn nghe có vẻ thú vị. Hãy tận hưởng và chúc may mắn.

+0

Cảm ơn bạn đã trả lời của bạn, Nhưng thực sự nó là một số loại chung, Cảm ơn. – wajeeh

+0

tôi không hiểu "đó là một loại chung chung". Bạn muốn biết thêm chi tiết về câu trả lời nào? – lukya

+0

Xin lỗi, vì tiếng anh xấu của tôi có lẽ tôi không rõ suy nghĩ của mình, Nhưng @Nikolay trả lời chi tiết hơn. Cảm ơn – wajeeh

Các vấn đề liên quan