我有这张地图https://jsfiddle.net/e80zkacn/,上面有汽车图标。在0度时,汽车的图标朝北,但在我将其旋转270度时,却指向其前进的位置。我希望汽车始终使用方位角面向正确的位置。
我正在使用的公式是atan2,如此处https://www.igismap.com/formula-to-find-bearing-or-heading-angle-between-two-points-latitude-longitude/
所述这是代码
var map, marker;
var startPos = [42.42679066670903, -83.29210638999939];
var speed = 50; // km/h
var bearing = 2.6;
var symbol = {
path: "M62.1,36.5c-0.9-1.2-3.6-1.5-3.6-1.5c0.1-3.5,0.5-6.9,0.7-8.2c1.9-7.3-1.7-11.8-1.7-11.8c-4.8-4.8-9.1-5-12.5-5 c-3.4,0-7.8,0.3-12.5,5c0,0-3.6,4.5-1.7,11.8c0.2,1.2,0.5,4.6,0.7,8.2c0,0-2.7,0.3-3.6,1.5c-0.9,1.2-0.9,1.9,0,1.9 c0.9,0,2.9-2.3,3.6-2.3V35c0,1,0.1,2,0.1,3c0,4.4,0,33.7,0,33.7s-0.3,6.1,5,7.8c1.2,0,4.6,0.4,8.4,0.5c3.8-0.1,7.3-0.5,8.4-0.5 c5.3-1.7,5-7.8,5-7.8s0-29.3,0-33.7c0-1,0-2,0.1-3v1.2c0.7,0,2.7,2.3,3.6,2.3C63,38.5,63,37.7,62.1,36.5z M34.7,66.5 c-0.3,3.3-2.3,4.1-2.3,4.1V37.4c0.8,1.2,2.3,6.8,2.3,6.8S34.9,63.2,34.7,66.5z M54.8,75.2c0,0-4.2,2.3-9.8,2.2 c-5.6,0.1-9.8-2.2-9.8-2.2v-2.8c4.9,2.2,9.8,2.2,9.8,2.2s4.9,0,9.8-2.2V75.2z M35.2,41.1l-1.7-10.2c0,0,4.5-3.2,11.5-3.2 s11.5,3.2,11.5,3.2l-1.7,10.2C51.4,39.2,38.6,39.2,35.2,41.1z M57.7,70.6c0,0-2.1-0.8-2.3-4.1c-0.3-3.3,0-22.4,0-22.4 s1.5-5.6,2.3-6.8V70.6z",
fillColor: '#FF0000',
fillOpacity: .5,
anchor: new google.maps.Point(0, 0),
strokeWeight: 1,
scale: .5,
rotation: bearing
}
var delay = 100;
// If you set the delay below 1000ms and you go to another tab,
// the setTimeout function will wait to be the active tab again
// before running the code.
// See documentation :
// https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Inactive_tabs
function animateMarker(marker, coords, km_h)
{
var target = 0;
var km_h = km_h || 50;
coords.push([startPos[0], startPos[1]]);
function goToPoint()
{
function radians_to_degrees(radians)
{
var pi = Math.PI;
return radians * (180/pi);
}
var lat = marker.position.lat();
var lng = marker.position.lng();
var step = (km_h * 1000 * delay) / 3600000; // in meters
var dest = new google.maps.LatLng(
coords[target][0], coords[target][1]);
var distance =
google.maps.geometry.spherical.computeDistanceBetween(
dest, marker.position); // in meters
var numStep = distance / step;
var i = 0;
var deltaLat = (coords[target][0] - lat) / numStep;
var deltaLng = (coords[target][1] - lng) / numStep;
function the_bearing(){
//console.log('x', lat);
//console.log('y', lng);
let bear = Math.atan2(lat, lng);
var brng = radians_to_degrees(bear);
brng = (brng + 360) % 360;
console.log('angle is ', brng);
}
the_bearing();
function moveMarker()
{
lat += deltaLat;
lng += deltaLng;
i += step;
if (i < distance)
{
marker.setPosition(new google.maps.LatLng(lat, lng));
setTimeout(moveMarker, delay);
}
else
{ marker.setPosition(dest);
target++;
if (target == coords.length){ target = 0; }
setTimeout(goToPoint, delay);
}
}
moveMarker();
}
goToPoint();
}
function initialize()
{
var myOptions = {
zoom: 16,
center: new google.maps.LatLng(42.425175091823974, -83.2943058013916),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var icon = symbol;
marker = new google.maps.Marker({
position: new google.maps.LatLng(startPos[0], startPos[1]),
map: map,
icon: icon
});
google.maps.event.addListenerOnce(map, 'idle', function()
{
animateMarker(marker, [
// The coordinates of each point you want the marker to go to.
// You don't need to specify the starting position again.
[42.42666395645802, -83.29694509506226],
[42.42300508749226, -83.29679489135742],
[42.42304468678425, -83.29434871673584],
[42.424882066428424, -83.2944130897522],
[42.42495334300206, -83.29203128814697]
], speed);
});
}
initialize();
目前,atan2的结果正在转换为度数,我对此表示怀疑。我如何才能使svg图标始终面对其前进的方向,并且有一种可靠的方法可以使svg图标始终朝着其前进的方向看?。
答案 0 :(得分:3)
geometry library for Google Maps' JavaScript API提供了一种称为google.maps.geometry.spherical.computeHeading(p1, p2)
的有用方法,可以精确计算从point1
到point2
的标题。
我可以随意修改您的代码。这是jsfiddle。
请注意正确地锚定您的图标,该锚定位于(0, 0)
处,这会使汽车驶离道路。我试图对其进行更改,以使其看起来更自然。
<!Doctype html>
<meta charset="UTF-8">
<head>
<style>
#map {
width: 600px;
height: 400px;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBx6MYRybsImp6aSn4xPphPFlGF3IaOr88&libraries=geometry"></script>
<script type="text/javascript">
var map, marker;
var startPos = [42.42679066670903, -83.29210638999939];
var speed = 270; // km/h
var bearing = 270;
var symbol = {
path: "M62.1,36.5c-0.9-1.2-3.6-1.5-3.6-1.5c0.1-3.5,0.5-6.9,0.7-8.2c1.9-7.3-1.7-11.8-1.7-11.8c-4.8-4.8-9.1-5-12.5-5 c-3.4,0-7.8,0.3-12.5,5c0,0-3.6,4.5-1.7,11.8c0.2,1.2,0.5,4.6,0.7,8.2c0,0-2.7,0.3-3.6,1.5c-0.9,1.2-0.9,1.9,0,1.9 c0.9,0,2.9-2.3,3.6-2.3V35c0,1,0.1,2,0.1,3c0,4.4,0,33.7,0,33.7s-0.3,6.1,5,7.8c1.2,0,4.6,0.4,8.4,0.5c3.8-0.1,7.3-0.5,8.4-0.5 c5.3-1.7,5-7.8,5-7.8s0-29.3,0-33.7c0-1,0-2,0.1-3v1.2c0.7,0,2.7,2.3,3.6,2.3C63,38.5,63,37.7,62.1,36.5z M34.7,66.5 c-0.3,3.3-2.3,4.1-2.3,4.1V37.4c0.8,1.2,2.3,6.8,2.3,6.8S34.9,63.2,34.7,66.5z M54.8,75.2c0,0-4.2,2.3-9.8,2.2 c-5.6,0.1-9.8-2.2-9.8-2.2v-2.8c4.9,2.2,9.8,2.2,9.8,2.2s4.9,0,9.8-2.2V75.2z M35.2,41.1l-1.7-10.2c0,0,4.5-3.2,11.5-3.2 s11.5,3.2,11.5,3.2l-1.7,10.2C51.4,39.2,38.6,39.2,35.2,41.1z M57.7,70.6c0,0-2.1-0.8-2.3-4.1c-0.3-3.3,0-22.4,0-22.4 s1.5-5.6,2.3-6.8V70.6z",
fillColor: '#FF0000',
fillOpacity: .5,
anchor: new google.maps.Point(45, 45),
strokeWeight: 1,
scale: .5,
rotation: bearing
}
var delay = 100;
// If you set the delay below 1000ms and you go to another tab,
// the setTimeout function will wait to be the active tab again
// before running the code.
// See documentation :
// https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Inactive_tabs
function animateMarker(marker, coords, km_h)
{
var target = 0;
var km_h = km_h || 50;
coords.push([startPos[0], startPos[1]]);
console.log(coords);
function goToPoint()
{
var lastPosn = marker.getPosition();
var lat = marker.position.lat();
var lng = marker.position.lng();
var step = (km_h * 1000 * delay) / 3600000; // in meters
var start = new google.maps.LatLng(startPos[0], startPos[1]);
var dest = new google.maps.LatLng(coords[target][0], coords[target][1]);
var distance = google.maps.geometry.spherical.computeDistanceBetween(dest, marker.position); // in meters
var numStep = distance / step;
var i = 0;
var deltaLat = (coords[target][0] - lat) / numStep;
var deltaLng = (coords[target][1] - lng) / numStep;
function moveMarker()
{
lat += deltaLat;
lng += deltaLng;
i += step;
if (i < distance)
{
var p = new google.maps.LatLng(lat, lng);
marker.setPosition(p);
var heading = google.maps.geometry.spherical.computeHeading(lastPosn, p);
symbol.rotation = heading;
marker.setIcon(symbol);
setTimeout(moveMarker, delay);
}
else
{
marker.setPosition(dest);
var heading = google.maps.geometry.spherical.computeHeading(lastPosn, dest);
symbol.rotation = heading;
marker.setIcon(symbol);
target++;
if (target == coords.length){ target = 0; }
setTimeout(goToPoint, delay);
}
}
moveMarker();
}
goToPoint();
}
function initialize()
{
var myOptions = {
zoom: 16,
center: new google.maps.LatLng(42.425175091823974, -83.2943058013916),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
marker = new google.maps.Marker({
position: new google.maps.LatLng(startPos[0], startPos[1]),
map: map,
icon: symbol
});
google.maps.event.addListenerOnce(map, 'idle', function()
{
animateMarker(marker, [
// The coordinates of each point you want the marker to go to.
// You don't need to specify the starting position again.
[42.42666395645802, -83.29694509506226],
[42.42300508749226, -83.29679489135742],
[42.42304468678425, -83.29434871673584],
[42.424882066428424, -83.2944130897522],
[42.42495334300206, -83.29203128814697]
], speed);
});
}
initialize();
</script>
</body>
</html>
我认为代码的某些部分可以使用API中的其他方法,例如计算deltaLat
和deltaLng
,但我不确定。
我也不确定moveMarker()
方法是否必须在两种情况下进行拆分,但是我可能是错的。