Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

In drawing application we can identify when the user is starting to draw and moving the finger to make a line/shape. I'm trying to do the same on a map, how can I do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
854 views
Welcome To Ask or Share your Answers For Others

1 Answer

Basic steps will involve:

1)Add a overlay view whenever user starts to draw.

lazy var canvasView:CanvasView = {

    var overlayView = CanvasView(frame: self.googleMapView.frame)
    overlayView.isUserInteractionEnabled = true
    overlayView.delegate = self
    return overlayView

}()
@IBAction func drawActn(_ sender: AnyObject?) {

    self.coordinates.removeAll()
    self.view.addSubview(canvasView)
    let origImage = UIImage(named: "pen")
    let tintedImage = origImage?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
    drawBtn.setImage(tintedImage, for: .normal)
    drawBtn.tintColor = UIColor.white
    drawBtn.backgroundColor = UIColor.red

}

2)Do free hand drawing in the overlay view.

class CanvasView: UIImageView {

    weak var delegate:NotifyTouchEvents?
    var lastPoint = CGPoint.zero
    let brushWidth:CGFloat = 3.0
    let opacity :CGFloat = 1.0


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {


        if let touch = touches.first {

            self.delegate?.touchBegan(touch: touch)
            lastPoint = touch.location(in: self)
        }
    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first  {

            self.delegate?.touchMoved(touch: touch)
            let currentPoint = touch.location(in: self)
            drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)
            lastPoint = currentPoint
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first  {

            self.delegate?.touchEnded(touch: touch)

        }
    }

    func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {

        UIGraphicsBeginImageContext(self.frame.size)
        let context = UIGraphicsGetCurrentContext()
        self.image?.draw(in: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))

        context?.move(to: fromPoint)
        context?.addLine(to: toPoint)

        context?.setLineCap(.round)
        context?.setLineWidth(brushWidth)
        context?.setStrokeColor(UIColor.black.cgColor)
        context?.setBlendMode(.normal)
        context?.strokePath()

        self.image = UIGraphicsGetImageFromCurrentImageContext()
        self.alpha = opacity
        UIGraphicsEndImageContext()

    }

}

3)Get all coordinates in an array from OverlayView to Controller using delegate pattern

//MARK: GET DRAWABLE COORDINATES
extension ViewController:NotifyTouchEvents{

    func touchBegan(touch:UITouch){

        let location = touch.location(in: self.googleMapView)
        let coordinate = self.googleMapView.projection.coordinate(for: location)
        self.coordinates.append(coordinate)

    }

    func touchMoved(touch:UITouch){

        let location = touch.location(in: self.googleMapView)
        let coordinate = self.googleMapView.projection.coordinate(for: location)
        self.coordinates.append(coordinate)

    }

    func touchEnded(touch:UITouch){

        let location = touch.location(in: self.googleMapView)
        let coordinate = self.googleMapView.projection.coordinate(for: location)
        self.coordinates.append(coordinate)
        createPolygonFromTheDrawablePoints()
    }
}

4)Change that coordinates into a polygon.

   func createPolygonFromTheDrawablePoints(){

        let numberOfPoints = self.coordinates.count
        //do not draw in mapview a single point
        if numberOfPoints > 2 { addPolyGonInMapView(drawableLoc: coordinates) }//neglects a single touch
        coordinates = []
        self.canvasView.image = nil
        self.canvasView.removeFromSuperview()

        let origImage = UIImage(named: "pen")
        let tintedImage = origImage?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
        drawBtn.setImage(tintedImage, for: .normal)
        drawBtn.tintColor = UIColor.red
        drawBtn.backgroundColor = UIColor.white

    }

    func  addPolyGonInMapView( drawableLoc:[CLLocationCoordinate2D]){

        isDrawingModeEnabled = true
        let path = GMSMutablePath()
        for loc in drawableLoc{

            path.add(loc)

        }
        let newpolygon = GMSPolygon(path: path)
        newpolygon.strokeWidth = 3
        newpolygon.strokeColor = UIColor.black
        newpolygon.fillColor = UIColor.black.withAlphaComponent(0.5)
        newpolygon.map = googleMapView
        if cancelDrawingBtn.isHidden == true{ cancelDrawingBtn.isHidden = false }
        userDrawablePolygons.append(newpolygon)
        addPolygonDeleteAnnotation(endCoordinate: drawableLoc.last!,polygon: newpolygon)
    }

I have created a demo project for drawing/deleting multiple polygons on Google Map in Swift 3 here.

Remember setting API key in AppDelegate and changing bundle identifier in order to run the project.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...