如何在Google地图中更改方向之间的平滑过渡?

时间:2015-12-18 07:48:19

标签: javascript google-maps animation google-maps-markers

我有一个简单的JS应用程序,它将地图上的标记从预定义的GPS坐标移动到给定的GPS位置。

我想问一下,如何在方向变化之间做平滑标记过渡? (动画应该给用户的印象,标记像街上行走的人一样移动,这意味着速度大约每小时4公里)

我试图找到一些有效的解决方案,但没有运气。

这是我的JS小提琴。

https://jsfiddle.net/33uofo49/



<!DOCTYPE html>
<html>
<head>
	<title>Animated route</title>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<style>
		html, body, #map {
			height: 100%;
			margin: 0px;
			padding: 0px
		}
	</style>
	<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&amp;libraries=geometry"></script>
	<script>

		var startDestination = [37.762836, -122.435011];
		var endDestination = [37.769452, -122.429186 ];
		var timeout = 1 * 1000; // seconds

		function initialize() {
			var map = new google.maps.Map(document.getElementById("map"), {
			  center: {lat: startDestination[0], lng: startDestination[1]},
			  zoom: 100,
			  mapTypeId: google.maps.MapTypeId.ROADMAP
			});
			
			getDirections(map);
		}

		function moveMarker(map, marker, latlng) {
			marker.setPosition(latlng);
			map.panTo(latlng);
		}

		function autoRefresh(map, pathCoords) {
			var i, route, marker;
			
			route = new google.maps.Polyline({
				path: [],
				geodesic : true,
				strokeColor: '#FF0000',
				strokeOpacity: .5,
				strokeWeight: 2,
				editable: false,
				map:map
			});
			
			marker=new google.maps.Marker({map:map, icon:"http://maps.google.com/mapfiles/ms/micons/blue.png"});

			for (i = 0; i < pathCoords.length; i++) {				
				setTimeout(function(coords) {
					route.getPath().push(coords);
					moveMarker(map, marker, coords);
				}, timeout * i, pathCoords[i]);
			}
		}
		
		function getDirections(map) {
			var directionsService = new google.maps.DirectionsService();
			
			var start = new google.maps.LatLng(startDestination[0], startDestination[1]);
			var end = new google.maps.LatLng(endDestination[0], endDestination[1]);

			var request = {
				origin:start,
				destination:end,
				travelMode: google.maps.TravelMode.WALKING
			};
			directionsService.route(request, function(result, status) {
				if (status == google.maps.DirectionsStatus.OK) {
					autoRefresh(map, result.routes[0].overview_path);
				}
			});
		}

		google.maps.event.addDomListener(window, 'load', initialize);
	</script>
</head>
<body>
	<div id="map"></div>
</body>
</html>
&#13;
&#13;
&#13;

非常感谢任何建议

1 个答案:

答案 0 :(得分:1)

您可以考虑以下解决方案:

  • 计算路线服务返回路径的附加坐标(请参阅下面示例中的interpolatePathBetween函数)。这里的想法是提供每个距离步骤计算的路径的坐标。为此,我们将使用google.maps.geometry.spherical namespace中的函数,特别是interpolatecomputeDistanceBetween函数。
  • 一旦生成的路线的路径包含足够的坐标,timeout的{​​{1}}就可以减少

示例

setTimeout
var startDestination = [37.762836, -122.435011];
var endDestination = [37.769452, -122.429186];

function initialize() {
    var map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: startDestination[0], lng: startDestination[1] },
        zoom: 19,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    getDirections(map);
}

function moveMarker(map, marker, latlng) {
    marker.setPosition(latlng);
    map.panTo(latlng);
}

function autoRefresh(map, pathCoords) {
    var i, route, marker;

    route = new google.maps.Polyline({
        path: [],
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: .5,
        strokeWeight: 2,
        editable: false,
        map: map
    });

    marker = new google.maps.Marker({ map: map, icon: "http://maps.google.com/mapfiles/ms/micons/blue.png" });

    
      
    interpolatePathBetween(pathCoords, 10);

    var timeout = 1 * 100; // seconds
    for (i = 0; i < pathCoords.length; i++) {
        setTimeout(function (coords) {
            route.getPath().push(coords);
            moveMarker(map, marker, coords);
        }, timeout * i, pathCoords[i]);
    }
}


function interpolatePathBetween(path,step,curIndex){
    var curIndex = curIndex || 0;
    //verify path contains at least 2 coordinates
    if(path.length == 0 || path.length == 1) { 
        return;
    }
    step = Math.max(step,10); //ensure the step at least 10 meters 

    var start = path[curIndex];
    var end = path[curIndex+1];
    var dist = google.maps.geometry.spherical.computeDistanceBetween (start, end);
   
    if(dist > step) {
        var intCoord = google.maps.geometry.spherical.interpolate(start, end, .5);
        path.splice(curIndex+1, 0, intCoord);
        interpolatePathBetween(path,step,curIndex);
    }
   
    
    if(curIndex < path.length - 2) {
       interpolatePathBetween(path,step,curIndex + 1);
    }   

}

function getDirections(map) {
    var directionsService = new google.maps.DirectionsService();

    var start = new google.maps.LatLng(startDestination[0], startDestination[1]);
    var end = new google.maps.LatLng(endDestination[0], endDestination[1]);

    var request = {
        origin: start,
        destination: end,
        travelMode: google.maps.TravelMode.WALKING
    };
    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            autoRefresh(map, result.routes[0].overview_path);
        }
    });
}

google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map {
            height: 100%;
            margin: 0px;
            padding: 0px;
}

JSFiddle