Search code examples
google-mapsgoogle-maps-api-3google-maps-markersgoogle-maps-styling

Animated Marker Positions on PolyLine


I am using google maps API V3 and created some Animation of a Icon over a PolyLine.

My Code

var line;

function initialize() {
    var mapOptions = {
        center: new google.maps.LatLng(2.881766, 101.626877),
        zoom: 12,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById('map-canvas'),
        mapOptions);

    var lineCoordinates = [
        new google.maps.LatLng(2.86085, 101.6437),
        new google.maps.LatLng(2.87165, 101.6362),
        new google.maps.LatLng(2.880783, 101.6273),

        new google.maps.LatLng(2.891517, 101.6201),
        new google.maps.LatLng(2.8991, 101.6162), new google.maps.LatLng(2.915067, 101.6079)
    ];
    map.setCenter(lineCoordinates[0]);

    var lineSymbol = {
        path: google.maps.SymbolPath.CIRCLE,
        scale: 6,
        strokeColor: '#393'
    };

    line = new google.maps.Polyline({
        path: lineCoordinates,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
        icons: [{
            icon: lineSymbol,
            offset: '100%'
        }],

        map: map
    });

    for (var i = 0; i < line.getPath().getLength(); i++) {
        var marker = new google.maps.Marker({
            icon: {
                url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
                size: new google.maps.Size(7, 7),
                anchor: new google.maps.Point(4, 4)
            },
            position: line.getPath().getAt(i),
            title: line.getPath().getAt(i).toUrlValue(6),
            map: map
        });
    }

    animateCircle();
}


var id;

function animateCircle() {
    var count = 0;
    id = window.setInterval(function () {
        count = (count + 1) % 200;
        var icons = line.get('icons');
        icons[0].offset = (count / 2) + '%';
        line.set('icons', icons);
        if (line.get('icons')[0].offset == "99.5%") {
            icons[0].offset = '100%';
            line.set('icons', icons);
            window.clearInterval(id);
        }

    }, 20);
}

google.maps.event.addDomListener(window, 'load', initialize);

Fiddle Link here

There I have 6 points in the polyline. I want to create a Marker at each Point once the Animated Marker reaches the point.

Can anyone help me out in this context.

Thank you.


Solution

  • Here is one of possible solution using google.maps.geometry.spherical namespace method computeDistanceBetween(from:LatLng, to:LatLng, radius?:number). You have to include geometry library:

    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=geometry"></script>
    

    computeDistanceBetween() is used to calculate distance between points and convert them to percentages of whole distance:

    // point distances from beginning in %
    var sphericalLib = google.maps.geometry.spherical;
    
    pointDistances = [];
    var pointZero = lineCoordinates[0];
    var wholeDist = sphericalLib.computeDistanceBetween(
                        pointZero,
                        lineCoordinates[lineCoordinates.length - 1]);
    
    for (var i = 0; i < lineCoordinates.length; i++) {
        pointDistances[i] = 100 * sphericalLib.computeDistanceBetween(
                                        lineCoordinates[i], pointZero) / wholeDist;
        console.log('pointDistances[' + i + ']: ' + pointDistances[i]);
    }
    

    Function animateCircle() is changed so that marker is created when offset is greater then offset of specific point:

    var id;
    function animateCircle() {
        var count = 0;
        var offset;
        var sentiel = -1;
    
        id = window.setInterval(function () {
            count = (count + 1) % 200;
            offset = count /2;
    
            for (var i = pointDistances.length - 1; i > sentiel; i--) {
                if (offset > pointDistances[i]) {
                    console.log('create marker');
                    var marker = new google.maps.Marker({
                        icon: {
                            url:"https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
                            size: new google.maps.Size(7,7),
                            anchor: new google.maps.Point(4,4)
                        },
                        position: line.getPath().getAt(i),
                        title: line.getPath().getAt(i).toUrlValue(6),
                        map: map
                    });
    
                    sentiel++;
                    break;
                }
            }
    ...
    

    See example at jsbin.

    Note: this example uses almost straight line. If you have different example then it would be better to calculate distance from point to point and get the sum of all of them. So, offset calculation should be little different: see example at jsbin.