2016-11-29 2 views
5

, если у меня есть путь к полилинии сохраняется как string,Могу ли я нарисовать миниатюру для полилинии?

С Google Maps SDK: path.encodedPath()

Или у меня есть ряд latlng сек точек,

Могу ли я нарисовать эскиз для этого дорожка ?

Я не хочу нарисовать его на mapView, интересно, могу ли я нарисовать его в любом другом виде, например, imageView или что-нибудь подобное.

+0

'UIBezierPath'? –

+0

Нет, я не имею в виду, что «полилиния», которая рисует на «карте», мне нужна ее как «image» @ 季 亨达 – wajeeh

+0

. Еще одна возможность - использовать «point (для координат: CLLocationCoordinate2D) -> CGPoint' для свойства 'projection' вашего mapView для преобразования' CLLocationCoordinate2D' в координаты просмотра ('CGPoint's).После этого вы могли бы нарисовать эти точки на 'UIBezierPath' и взять screenShot из этого' UIView'. Надеюсь, что существует лучший подход, не зависящий от SDK Google Maps и отсутствие экземпляра GMSMapView. –

ответ

3

Я создал быстрый 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

enter image description here

+0

На самом деле ваш ответ помогает мне рисовать дорожку на слое. Но, как вы знаете, расстояния в системе «latlng» очень близки друг к другу, как '0,001', поэтому график выглядит как одна точка. Я много раз пытался масштабировать фотографию до размера «200x200», но у меня не было успеха, как сделать границы для новой фигуры и заполнить все пространство? – wajeeh

+0

@wajeeh Я обновил код, где вы можете увидеть, как вы можете масштабировать путь. –

+0

Спасибо, я проверю его – wajeeh

2

Если у вас есть ряд лат тоскует, вы можете узнать максимальное и минимальное Lat долго, говорят, что они: maxLat, maxLong, minLat, minLong. Пожалуйста, не считайте, что оба максимальных значения не должны принадлежать одной и той же координате. То же самое для обоих минимальных значений.

Вы можете использовать это, чтобы получить прямоугольник:

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

Теперь, все остальные LAT тоскует являются точками этого прямоугольника. Вы можете получить каждый coordinate «S соответствующие значения CGPoint по

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

Используя этот прямоугольник и ряд CGPoints вы создали, вы можете нарисовать путь (начав с первой точкой и добавить все последующие пункты к нему) на представление (например, изображение, которое вы упомянули в своем ответе) или создать графический контекст, чтобы создать миниатюру вашего пути и сохранить ее как изображение.

Обратитесь к drawing and printing guide, если вы не знакомы с чертежом в CGContexts.

Однако, если вы хотите разместить этот эквивалент эскиза пути на изображении, реальная проблема заключается в том, как вы знаете позицию. Простым трюком было бы получить эквивалентные по карте минимальные координаты изображения, на которых вы хотите наложить миниатюру пути, и использовать эти минимальные значения для создания пути и контекста. Затем вы можете центрировать миниатюру на изображении.

Ваш проект звучит интересно. Наслаждайтесь и удачи.

+0

Спасибо за ваш ответ, но на самом деле это какой-то общий, спасибо. – wajeeh

+0

Я не понимал, что «это нечто общее». На какую часть моего ответа вы хотите получить более подробную информацию? – lukya

+0

Извините, из-за моего плохого английского, может быть, я не прояснил свою мысль, но @Nikolay ответьте более подробно. благодаря – wajeeh

Смежные вопросы