PolyLine上的动画标记位置

时间:2014-02-14 01:45:13

标签: google-maps google-maps-api-3 google-maps-markers google-maps-styled

我正在使用谷歌地图API V3并在PolyLine上创建了一些Icon的动画。

我的代码

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

我在折线中有6个点。一旦动画标记到达该点,我想在每个点创建一个标记。

在这种情况下,任何人都可以帮助我。

谢谢。

2 个答案:

答案 0 :(得分:2)

以下是使用google.maps.geometry.spherical namespace方法computeDistanceBetween(from:LatLng, to:LatLng, radius?:number)的可能解决方案之一。您必须包含geometry库:

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

computeDistanceBetween()用于计算点之间的距离并将其转换为整个距离的百分比:

// 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]);
}

更改了函数animateCircle(),以便在偏移量大于特定点的偏移量时创建标记:

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;
            }
        }
...

请参阅example at jsbin

注意:此示例使用几乎直线。如果您有不同的示例,那么最好计算点到点的距离并获得所有点的总和。因此,偏移计算应该略有不同:参见示例at jsbin

答案 1 :(得分:0)

我发现@AntoJurković的答案非常有用,但是他的解决方案的唯一问题是,它只能在相当笔直的直线上很好地工作(正如他本人在回答结尾所说)。 我想分享我的改进,使其适用于任何类型的线路。

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

// point distances from beginning in %
var sphericalLib = google.maps.geometry.spherical;

pointDistances = [];
var wholeDist = 0; 
// calculating the wholeDistance from point to point
for (var i = 0; i < lineCoordinates.length-1; i++) {
    wholeDist +=  sphericalLib.computeDistanceBetween(
        lineCoordinates[i+1], lineCoordinates[i]);
}

var currentDist = 0;

// <optional> to create a marker in the start point position
pointDistances[0] = 0;
// </optional>

for (var i = 0; i < lineCoordinates.length-1; i++) {
    // calculating the currentDistance from point to point
    currentDist +=  sphericalLib.computeDistanceBetween(
              lineCoordinates[i+1], lineCoordinates[i])

    // calculating the pointDistance as a percentage to compare it later with the offset
    pointDistances[i+1] = 100 * currentDist / wholeDist;
    console.log('pointDistances[' + i + ']: ' + pointDistances[i]);
}  

var myPolyline = new google.maps.Polyline({
    path: lineCoordinates,
    icons: [{
        icon: lineSymbol,
        offset: '100%'
    }],
    map: map,
    visible: true
});

var count = 0;
var offset;
var sentiel = -1;
var id;

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({
                position: myPolyline.getPath().getAt(i),
                title: myPolyline.getPath().getAt(i).toUrlValue(6),
                map: map
            });

            sentiel++;
            break;
        }
    }

    // <optional> to create a marker in the last point position
    // Note: 99.5 is the last calculated offset, when the counter is 199
    if(offset == 99.5){
        var lastLinePoint = myPolyline.getPath().length - 1;
            var marker = new google.maps.Marker({
                position: myPolyline.getPath().getAt(lastLinePoint),
                title: myPolyline.getPath().getAt(lastLinePoint).toUrlValue(6),
                map: map
            });
        // to reset the sentinel if you want to repeat the iteration at its end 
        sentiel = -1;
    }
    // </optional>

    var icons = myPolyline.get('icons');
    icons[0].offset = (count / 2) + '%';
    myPolyline.set('icons', icons);
}, 150);

编辑后的示例at jsbin