我正在尝试在Google地图(v3 API)上设置跟踪车辆的路径动画。我有4条折线:一条是灰色背景线,用于指示整条路线,另外3条用于指示前一小时的跟踪数据(过去10分钟为红色,10-30分钟为橙色,30-60分钟为黄色) )。
即使我为折线正确设置了zIndex,当我创建新的动画线并破坏旧的动画线时,灰色背景线会与其他线重叠(我在动画期间不会触摸此折线)。 / p>
它还严重降低了动画的性能,如果我禁用灰线,性能就好了。
我相信正在发生的事情是Google地图使用一个画布元素来绘制与该矩形相交的所有折线,因此它必须重绘该矩形中的所有折线,而不仅仅是我动画的那些。有没有办法让Google地图将它们放在单独的图层上,以便只重绘我想要重绘的图层?
更新:我创建了一个表现相当不错的sample,但确实展示了与其他行重叠的背景线。
HTML:
<button>Animate</button> <div id="slider"/>
<div id="map" style="height: 600px; margin-top: 20px;"/>
使用Javascript:
google.maps.LatLng.prototype.destinationPoint = function(brng, dist) {
dist = dist / 6371;
brng = brng.toRad();
var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
Math.cos(lat1),
Math.cos(dist) - Math.sin(lat1) *
Math.sin(lat2));
if (isNaN(lat2) || isNaN(lon2)) return null;
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
var range_lines = {
red: null,
orange: null,
yellow: null
};
var range_colors = {
red: '#ff0000',
orange: '#FFA500',
yellow: '#FFFF00'
};
function onSlide(e, ui) {
var end_minute = ui.value;
var start_minute = Math.max(0, end_minute - 60);
var line_points = [];
var last_range = null;
var last_point = null;
for (var minute = start_minute; minute < end_minute; minute++) {
var diff = Math.abs(end_minute - minute);
var range = '';
if (diff <= 10) {
range = 'red';
} else if (diff <= 30) {
range = 'orange';
} else {
range = 'yellow';
}
if (range != last_range) {
renderLine(line_points, last_range);
line_points = [];
last_range = range;
}
if (points_by_minute.hasOwnProperty(minute)) {
for (var i = 0; i < points_by_minute[minute].length; i++) {
line_points.push(points[points_by_minute[minute][i]]);
last_point = points[points_by_minute[minute][i]];
}
}
}
marker.setPosition(last_point);
renderLine(line_points, last_range);
}
function renderLine(line_points, range) {
var line = new google.maps.Polyline({
path: line_points,
strokeColor: range_colors[range],
strokeWeight: 3,
map: map,
zIndex: getZIndex(range)
});
if (range_lines[range] != null) {
range_lines[range].setMap(null);
}
range_lines[range] = line;
}
function getZIndex(range) {
switch (range) {
case 'yellow':
return 10;
case 'orange':
return 20;
case 'red':
return 30;
}
}
var points = [];
var points_by_minute = {};
var map;
var marker;
var interval;
$(document).ready(function() {
var start_point = new google.maps.LatLng(51.3767, -0.0960);
var point = new google.maps.LatLng(51.3767, -0.0960);
var minute = 0;
var bearing = 0;
var bounds = new google.maps.LatLngBounds()
for (var i = 0; i < 5000; i++) {
if (Math.random() > 0.5) {
if (Math.random() > 0.5) {
bearing += Math.round(Math.random() * 10);
} else {
bearing -= Math.round(Math.random() * 10);
}
}
if (i != 0 && i % 12 == 0) {
minute++;
}
if (!points_by_minute.hasOwnProperty(minute)) {
points_by_minute[minute] = [];
}
points_by_minute[minute].push(points.length);
point = point.destinationPoint(bearing, 0.01);
points.push(point);
bounds.extend(point);
}
for (var i = 0; i < 5000; i++) {
if (i != 0 && i % 12 == 0) {
minute++;
}
if (!points_by_minute.hasOwnProperty(minute)) {
points_by_minute[minute] = [];
}
points_by_minute[minute].push(points.length);
var latJitter = Math.random() / 10000;
if (Math.random() > 0.5) {
latJitter = -latJitter;
}
var lngJitter = Math.random() / 10000;
if (Math.random() > 0.5) {
lngJitter = -lngJitter;
}
point = new google.maps.LatLng(
points[4999 - i].lat() + latJitter,
points[4999 - i].lng() + lngJitter
);
points.push(point);
}
map = new google.maps.Map($('#map')[0], {
center: start_point,
zoom: 8,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
map.fitBounds(bounds);
$('button').button().click(function() {
if (interval) clearInterval(interval);
var value = $('#slider').slider("option", "value");
if (value == $('#slider').slider("option", "max")) {
clearInterval(interval);
}
$('#slider').slider("option", "value", $('#slider').slider("option", "min"));
interval = setInterval(animate, 10);
});
$('#slider').slider({
min: 0,
max: minute++,
step: 1,
value: 0,
change: onSlide
});
new google.maps.Polyline({
path: points,
strokeColor: '#cccccc',
strokeWeight: 1.5,
map: map,
zIndex: 1
});
marker = new google.maps.Marker({
position: start_point,
map: map
});
});
function animate() {
var value = $('#slider').slider("option", "value");
value++;
$('#slider').slider("option", "value", value);
if (value == $('#slider').slider("option", "max")) {
clearInterval(interval);
}
}