Search code examples
swift3google-maps-markersgoogle-maps-sdk-iosgoogle-polyline

How to Move marker exactly along Polyline?


Marker Movement from source to destination

Image Showing Marker Movement which is straight line with marker in one direction only. I want to move my marker along polyline with the marker direction should change along with polyline direction. How to achieve this. My current code is like this:

class MapScreenVC: BaseVC {

var path = GMSMutablePath()
var arrayCoordinates : [CLLocationCoordinate2D] = []
var destCoord = CLLocationCoordinate2D()
var marker = GMSMarker()
var mapView : GMSMapView? = nil
override func viewDidLoad() {
    super.viewDidLoad()

    let camera = GMSCameraPosition.camera(withLatitude: 53.4545, longitude: -2.1811, zoom: 14)
    mapView = GMSMapView.map(withFrame: .zero, camera: camera)
    marker = GMSMarker()
    marker.position = CLLocationCoordinate2DMake(53.4387, -2.1827)
    marker.title = "Source"
    marker.snippet = "Source"
    marker.icon = UIImage(named: "car")
    marker.map = mapView



    let DestinationMarker = GMSMarker()
    self.destCoord = CLLocationCoordinate2DMake(53.4645, -2.1873)
    DestinationMarker.position = CLLocationCoordinate2DMake(53.4643, -2.1869)
    DestinationMarker.title = "Destination"
    DestinationMarker.snippet = "Destination"
    DestinationMarker.icon = UIImage(named: "home")
    DestinationMarker.map = mapView

// PolyLine

    path.addLatitude(53.4395, longitude:-2.1834)
    path.addLatitude(53.4403, longitude:-2.1854)
    path.addLatitude(53.4414, longitude:-2.1852)
    path.addLatitude(53.4428, longitude:-2.1832)
    path.addLatitude(53.4442, longitude:-2.1818)
    path.addLatitude(53.4449, longitude:-2.1801)
    path.addLatitude(53.4478, longitude:-2.1793)
    path.addLatitude(53.4504, longitude:-2.1798)
    path.addLatitude(53.4526, longitude:-2.1806)
    path.addLatitude(53.4545, longitude:-2.1811)
    path.addLatitude(53.4564, longitude:-2.1811)
    path.addLatitude(53.4584, longitude:-2.1811)
    path.addLatitude(53.4601, longitude:-2.1811)
    path.addLatitude(53.4617, longitude:-2.1821)
    path.addLatitude(53.4630, longitude:-2.1829)
    path.addLatitude(53.4632, longitude:-2.1851)
    path.addLatitude(53.4635, longitude:-2.1869)
    path.addLatitude(53.4638, longitude:-2.1882)
    path.addLatitude(53.4645, longitude:-2.1873)


    let polyline = GMSPolyline(path: path)
    polyline.strokeColor = .blue
    polyline.strokeWidth = 6.0
    polyline.geodesic = true
    polyline.map = mapView
    updateMarker(coordinates: destCoord)
    view = mapView
}

func updateMarker(coordinates: CLLocationCoordinate2D) {
    CATransaction.begin()
    CATransaction.setAnimationDuration(10.0)
    marker.position = coordinates
    CATransaction.commit()
}

}


Solution

  • I am not familiar with a library or similar that can give you this, so I will outline a manual approach you can use to do this rather easily.

    To move the marker across the polyline you will need to calculate the steps the marker needs to take from each point in order to reach the next point.
    One option is to do the following for each individual line that defines the polyline:
    1) Define a line f(x) = ax + b for each 2 points You can read further here if you need help in calculating the slope of the line (a in the above equation)

    2) Define the step the marker takes until it reaches the end of this line. You can divide the length of the line by a constant which will give you a constant step. This isn't ideal since it will take the same number of steps to move across short and longer lines, but its a start. Also note that the distance between 2 lat/lng points is on a sphere and not as simple as in 2 dimensions. Look at https://en.wikipedia.org/wiki/Haversine_formula for more info.

    3) Put the marker on the first point (x1,y1), and move it to (x1+step, f(x1+step)).
    You need to determine whether to move left or right on the line.

    4) After each time you move the marker, check if it reached the end point of the current line, and then start over for the next line.