How to do freehand drawing in Google Maps on iOS?

后端 未结 3 587
遥遥无期
遥遥无期 2020-12-18 07:59

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?<

3条回答
  •  猫巷女王i
    2020-12-18 09:02

    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, with event: UIEvent?) {
    
    
            if let touch = touches.first {
    
                self.delegate?.touchBegan(touch: touch)
                lastPoint = touch.location(in: self)
            }
        }
    
    
        override func touchesMoved(_ touches: Set, 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, 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.

提交回复
热议问题