如何沿路线制作自定义 Google 地图标记的动画?

发布于 2024-07-15 13:02:17 字数 129 浏览 5 评论 0原文

我使用 JavaScript 和 Google Maps API 为手持设备编写了一个小型应用程序,现在我需要使用计时器功能将我的标记图标沿着路线移动到地图上的任何位置。 我有一个男人图标,我需要在地图上自动移动它。 我怎样才能做到这一点?

I have written a small application for a handheld device using JavaScript and Google Maps API's, now II need to move my marker icon anywhere on the map along a route using a timer function. I have a man icon and I need to move it automatically on the map. How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜警司 2024-07-22 13:02:17

这里有一个非常酷的示例:

http://www.kmcgraphics.com/google/

A pretty cool example is here:

http://www.kmcgraphics.com/google/

在巴黎塔顶看东京樱花 2024-07-22 13:02:17

不幸的是,官方 GMaps 集合中没有自动标记移动功能。

然而,如果你有一个GRoute,那就意味着你有一组点。 要循环遍历路线步骤,您可以使用类似以下的内容:

for (var c = 0; c < yourroute.getNumSteps(); c++) { 
    yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
}

当然,您可能希望使用计时器异步执行此操作:

function moveToStep(yourmarker,yourroute,c) {
    if {yourroute.getNumSteps() > c) {
        yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
        window.setTimeout(function(){
            moveToStep(yourmarker,yourroute,c+1);
        },500);
    }
}

moveToStep(marker,route,0);

为了更平滑的移动,您可以从已有的点中插入点。

Unfortunately, there is no automatic-marker-movement function in the official GMaps collection.

However, if you have a GRoute, that would mean you have a set of points. To loop through the route steps, you could use something like this:

for (var c = 0; c < yourroute.getNumSteps(); c++) { 
    yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
}

Of course, you'll probably want to do this asynchronously using the timers:

function moveToStep(yourmarker,yourroute,c) {
    if {yourroute.getNumSteps() > c) {
        yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
        window.setTimeout(function(){
            moveToStep(yourmarker,yourroute,c+1);
        },500);
    }
}

moveToStep(marker,route,0);

For even smoother movement, you could interpolate the points from those you already have.

陌上芳菲 2024-07-22 13:02:17

这是我的解决方案,适用于 v3 API。 这不是以固定速度,而是基于计算的路线持续时间来对标记进行动画处理。 这里有一个速度因素,例如,您可以比实际情况快 10 倍地行驶通过该路线。

我尝试尽可能简单地做到这一点。 随意使用它。

var autoDriveSteps = new Array();
var speedFactor = 10; // 10x faster animated drive

function setAnimatedRoute(origin, destination, map) {
    // init routing services
    var directionsService = new google.maps.DirectionsService;
    var directionsRenderer = new google.maps.DirectionsRenderer({
        map: map
    });

    //calculate route
    directionsService.route({
            origin: origin,
            destination: destination,
            travelMode: google.maps.TravelMode.DRIVING
        },
        function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                // display the route
                directionsRenderer.setDirections(response);

                // calculate positions for the animation steps
                // the result is an array of LatLng, stored in autoDriveSteps
                autoDriveSteps = new Array();
                var remainingSeconds = 0;
                var leg = response.routes[0].legs[0]; // supporting single route, single legs currently
                leg.steps.forEach(function(step) {
                    var stepSeconds = step.duration.value;
                    var nextStopSeconds = speedFactor - remainingSeconds;
                    while (nextStopSeconds <= stepSeconds) {
                        var nextStopLatLng = getPointBetween(step.start_location, step.end_location, nextStopSeconds / stepSeconds);
                        autoDriveSteps.push(nextStopLatLng);
                        nextStopSeconds += speedFactor;
                    }
                    remainingSeconds = stepSeconds + speedFactor - nextStopSeconds;
                });
                if (remainingSeconds > 0) {
                    autoDriveSteps.push(leg.end_location);
                }
            } else {
                window.alert('Directions request failed due to ' + status);
            }
        });
}

// helper method to calculate a point between A and B at some ratio
function getPointBetween(a, b, ratio) {
    return new google.maps.LatLng(a.lat() + (b.lat() - a.lat()) * ratio, a.lng() + (b.lng() - a.lng()) * ratio);
}

// start the route simulation   
function startRouteAnimation(marker) {
    var autoDriveTimer = setInterval(function () {
            // stop the timer if the route is finished
            if (autoDriveSteps.length === 0) {
                clearInterval(autoDriveTimer);
            } else {
                // move marker to the next position (always the first in the array)
                marker.setPosition(autoDriveSteps[0]);
                // remove the processed position
                autoDriveSteps.shift();
            }
        },
        1000);
}

用法:

setAnimatedRoute("source address or LatLng ...", "destination address or LatLng ...", map);
// start simulation on button click...
$("#simulateRouteButton").click(function() {
    startRouteAnimation(agentMarker);
});

Here is my solution that works with the v3 API. This animates the marker not with a fixed velocity, but based on the calculated route duration. There is a speed factor, so for example you can drive through the route 10x faster than in reality.

I've tried to do it as simple as possible. Feel free to use it.

var autoDriveSteps = new Array();
var speedFactor = 10; // 10x faster animated drive

function setAnimatedRoute(origin, destination, map) {
    // init routing services
    var directionsService = new google.maps.DirectionsService;
    var directionsRenderer = new google.maps.DirectionsRenderer({
        map: map
    });

    //calculate route
    directionsService.route({
            origin: origin,
            destination: destination,
            travelMode: google.maps.TravelMode.DRIVING
        },
        function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                // display the route
                directionsRenderer.setDirections(response);

                // calculate positions for the animation steps
                // the result is an array of LatLng, stored in autoDriveSteps
                autoDriveSteps = new Array();
                var remainingSeconds = 0;
                var leg = response.routes[0].legs[0]; // supporting single route, single legs currently
                leg.steps.forEach(function(step) {
                    var stepSeconds = step.duration.value;
                    var nextStopSeconds = speedFactor - remainingSeconds;
                    while (nextStopSeconds <= stepSeconds) {
                        var nextStopLatLng = getPointBetween(step.start_location, step.end_location, nextStopSeconds / stepSeconds);
                        autoDriveSteps.push(nextStopLatLng);
                        nextStopSeconds += speedFactor;
                    }
                    remainingSeconds = stepSeconds + speedFactor - nextStopSeconds;
                });
                if (remainingSeconds > 0) {
                    autoDriveSteps.push(leg.end_location);
                }
            } else {
                window.alert('Directions request failed due to ' + status);
            }
        });
}

// helper method to calculate a point between A and B at some ratio
function getPointBetween(a, b, ratio) {
    return new google.maps.LatLng(a.lat() + (b.lat() - a.lat()) * ratio, a.lng() + (b.lng() - a.lng()) * ratio);
}

// start the route simulation   
function startRouteAnimation(marker) {
    var autoDriveTimer = setInterval(function () {
            // stop the timer if the route is finished
            if (autoDriveSteps.length === 0) {
                clearInterval(autoDriveTimer);
            } else {
                // move marker to the next position (always the first in the array)
                marker.setPosition(autoDriveSteps[0]);
                // remove the processed position
                autoDriveSteps.shift();
            }
        },
        1000);
}

Usage:

setAnimatedRoute("source address or LatLng ...", "destination address or LatLng ...", map);
// start simulation on button click...
$("#simulateRouteButton").click(function() {
    startRouteAnimation(agentMarker);
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文