How to do freehand drawing in Google Maps on iOS?

后端 未结 3 555
遥遥无期
遥遥无期 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条回答
  • 2020-12-18 08:51

    Map Kit Polyline or Polygon Drawing - https://github.com/tazihosniomar/MapKitDrawing

    This link contains demo project for drawing polygons on Apple Map. But, logic remains the same for Google Map View. So, you can copy implementation logic from this and apply it on Google Map.

    I hope this will help you.

    0 讨论(0)
  • 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<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.

    0 讨论(0)
  • 2020-12-18 09:02

    To draw a line use polyline. Refer to Google Maps Shapes.

    To use polyline you need to give locatoin coordinates. To convert a point on screen to coordinate use coordinateForPoint:(CGPoint)point method of GMSProjection class.

    Polyline actually draws a line between two coordinates. Thus, with moving mapView those lines will move, too. I think this is what you want.

    0 讨论(0)
提交回复
热议问题