Animation 在OpenLayers 3中设置多个标记的动画
我正在使用OpenLayers创建穿越太平洋的海洋动物迁徙动画。我希望每一个“动物”都能随着时间的推移追踪一条轨迹。在赛道的顶端将有一个代表该动物的图标/标记/覆盖物。我已经将其用于一个轨迹,但尽管我能够将每个动物的轨迹作为一段一段地构建的线串来生长,但我无法为每个轨迹指定一个图标/标记/覆盖。相反,我只能在一个轨迹上设置一个图标的动画。其余的线串轨迹将继续,但在跟踪轨迹时,它们在轨迹的头部没有图标。这是我的密码。谢谢你的帮助Animation 在OpenLayers 3中设置多个标记的动画,animation,openlayers-3,Animation,Openlayers 3,我正在使用OpenLayers创建穿越太平洋的海洋动物迁徙动画。我希望每一个“动物”都能随着时间的推移追踪一条轨迹。在赛道的顶端将有一个代表该动物的图标/标记/覆盖物。我已经将其用于一个轨迹,但尽管我能够将每个动物的轨迹作为一段一段地构建的线串来生长,但我无法为每个轨迹指定一个图标/标记/覆盖。相反,我只能在一个轨迹上设置一个图标的动画。其余的线串轨迹将继续,但在跟踪轨迹时,它们在轨迹的头部没有图标。这是我的密码。谢谢你的帮助 // draw tracks function m
// draw tracks
function makeLineString(id, species, multipointCoords, tracksTime) {
// layer structure and style assignment
var trackSource = new ol.source.Vector();
var trackLayer = new ol.layer.Vector({
source: trackSource,
style: BWtrackStyle
});
map.addLayer(trackLayer);
var lineString = new ol.geom.LineString([
ol.proj.fromLonLat(multipointCoords[0][0])
]);
var trackFeature = new ol.Feature({
geometry: lineString
});
if (species === "Blue Whale") {
trackFeature.setStyle([BWtrackStyle, shadowStyle]);
};
trackSource.addFeature(trackFeature);
// icon-marker-overlay styling
var BW2205005icon = document.getElementById('BW2205005icon');
var BW2205005marker = new ol.Overlay({
positioning: 'center-center',
offset: [0, 0],
element: BW2205005icon,
stopEvent: false
});
map.addOverlay(BW2205005marker);
var BW2205012icon = document.getElementById('BW2205012icon');
var BW2205012marker = new ol.Overlay({
positioning: 'center-center',
offset: [0, 0],
element: BW2205012icon,
stopEvent: false
});
map.addOverlay(BW2205012marker);
var coordinate, i = 1,
length = multipointCoords[0].length;
var currentTime = tracksTime[0][0];
var nextTime = tracksTime[0][1];
speedOption = 100; // the highter this value, the faster the tracks, see next line
var transitionTime = (nextTime - currentTime) / speedOption;
console.log(transitionTime);
var timer;
timer = setInterval(function() {
segmentConstruction(id, multipointCoords, tracksTime);
}, transitionTime);
function segmentConstruction(id, multipointCoords, tracksTime) {
coordinate = ol.proj.fromLonLat(multipointCoords[0][i]);
lineString.appendCoordinate(coordinate);
console.log(id);
if (id === "BW2205005") {
BW2205005marker.setPosition(coordinate);
} else {
BW2205012marker.setPosition(coordinate);
};
if (i >= length - 1) {
clearInterval(timer);
} else {
i++;
clearInterval(timer);
currentTime = tracksTime[0][i];
nextTime = tracksTime[0][i + 1];
transitionTime = (nextTime - currentTime) / speedOption;
timer = setInterval(function() {
segmentConstruction(id, multipointCoords, tracksTime);
}, transitionTime);
};
};
};
我认为你的覆盖层在每一行都被重复使用。在任何情况下,使用点要素而不是覆盖可能会更简单、更高效,如下所示:
- 为点(圆、图像等)的图层添加新样式
- 添加表示每条线头部的点要素
- 必要时更新点要素的坐标
也可以通过为每个点要素指定其自己的样式,或在图层上使用样式功能,独立设置点的样式 我建议将其用于多个标记平滑移动的动画,但其他样式需要延迟:
var vehicles= [{ "curlon":77.654397, "curlat":12.959898, "prevlon":77.651951, "prevlat":12.951074 },{ "curlon":77.672936, "curlat":12.958100, "prevlon":77.649290, "prevlat":12.960024 }];
function push_data_for_multimarker(map,gps_obj)
{
destruct=false;
var getz = gps_obj;
var data_arry = [];
for (var i = 0, length = getz.length; i < length; i++)
{
gps_smooth_coordinates_generator(parseFloat(getz[i].prevlon),parseFloat(getz[i].prevlat),parseFloat(getz[i].curlon),parseFloat(getz[i].curlat));
}
}
function gps_smooth_coordinates_generator(map,sourcelon,sourcelat,destinationlon,destinationlat)
{
var vehicle_data=[];
var beginz=ol.proj.transform([sourcelon,sourcelat], 'EPSG:4326', 'EPSG:3857');
var endz=ol.proj.transform([destinationlon,destinationlat], 'EPSG:4326', 'EPSG:3857');
vehicle_data.push(beginz);
vehicle_data.push(endz);
var path= vehicle_data;
var genrated_positions = [];
for(var k = 1;k<path.length;k++)
{
var pointsNo = 1000;
var startPos = {};
startPos.lat = path[k-1][1];
startPos.lng = path[k-1][0];
var endPos = {};
endPos.lat = path[k][1];
endPos.lng = path[k][0];
var latDelta = (endPos.lat - startPos.lat) / pointsNo;
var lngDelta = (endPos.lng - startPos.lng) / pointsNo;
for (var i = 0; i < pointsNo; i++)
{
var curLat = startPos.lat + i * latDelta;
var curLng = startPos.lng + i * lngDelta;
var arr = [];
arr.push(curLng);
arr.push(curLat);
genrated_positions.push(arr);
}
}
animate_multiple_marker(genrated_positions);
}
function animate_multiple_marker(map,veh_croods)
{
var routeCoords = veh_croods;
var routeLength = routeCoords.length;
console.log("routeCoords"+routeCoords);
console.log("routeLength"+routeLength);
var geoMarker = new ol.Feature({
type: 'geoMarker',
geometry: new ol.geom.Point(routeCoords[0])
});
var off_style =new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
snapToPixel: false,
fill: new ol.style.Fill({color: 'black'}),
stroke: new ol.style.Stroke({
color: 'white', width: 2
})
})
});
var now;
var animating = false;
var speed=20;
var moveFeature = function(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
if (animating) {
var elapsedTime = frameState.time - now;
var index = Math.round(speed * elapsedTime / 1000);
if (index >= routeLength) {
console.log("index>>"+index);
stopAnimation();
animating = false;
console.log("animation ends");
}
if(animating)
{
var currentPoint = new ol.geom.Point(routeCoords[index]);
var feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature,off_style);
}
else
{}
if(destruct)
{
console.log("termination initiated");
stopAnimation();
//destruct=false;
}
else
{ }
}
else
{
console.log("Not amnimating!!");
}
// tell OL3 to continue the postcompose animation
map.render();
};
triggerz_animation();
function stopAnimation() {
animating = false;
caller=false;
//remove listener
map.un('postcompose', moveFeature);
}
function start_vehicles()
{
animating = true;
now = new Date().getTime();
map.on('postcompose', moveFeature);
map.render();
}
if(caller)
{
start_vehicles();
}
else
{
}
}
var caller=false;
var drive_vehicle;
function triggerz_animation()
{
caller=true;
}
var destruct=false;
function collapse_animation()
{
destruct=true;
}
var vehicles=[{“curlon”:77.654397,“curlat”:12.959898,“prevlon”:77.651951,“prevlat”:12.951074},{“curlon”:77.672936,“curlat”:12.958100,“prevlon”:77.649290,“prevlat”:12.960024};
多标记(地图、gps、obj)功能推送数据
{
破坏=错误;
var getz=gps_obj;
var数据_arry=[];
for(var i=0,length=getz.length;i>”+索引);
停止动画();
动画=假;
console.log(“动画结束”);
}
如果(动画)
{
var currentPoint=新的ol.geom.Point(路由词[索引]);
var特性=新的ol.特性(当前点);
vectorContext.drawFeature(特征,关闭_样式);
}
其他的
{}
如果(自毁)
{
控制台日志(“终止启动”);
停止动画();
//破坏=错误;
}
其他的
{ }
}
其他的
{
log(“非amnimating!!”;
}
//告诉OL3继续后期合成动画
map.render();
};
triggerz_动画();
函数stopAnimation(){
动画=假;
调用者=假;
//删除侦听器
map.un('postcompose',moveFeature);
}
功能启动(车辆)
{
动画=真;
现在=新日期().getTime();
地图上('postcompose',moveFeature);
map.render();
}
如果(呼叫者)
{
启动车辆();
}
其他的
{
}
}
var caller=false;
无功驱动车;
函数triggerz_animation()
{
调用者=真;
}
var destruct=false;
函数collapse_animation()
{
析构函数=真;
}
关于
让这件事有帮助吧谢谢
将数据作为json传递给函数:
为多标记器(地图、车辆)推送数据 我应该补充一点,这段代码的灵感来源于这个示例:“我认为每一行都在重复使用您的覆盖”是什么意思?谢谢。大多数示例都使用div覆盖并使用.setPosition设置动画。要使用点特征,我想可以使用.setGeometry或实验矢量context?我假设您有许多线串,但看起来只有两个覆盖,因此当您更改坐标以匹配线串末端时,它将移动现有覆盖。这可能解释了为什么您没有看到预期的行为。尽管vectorContext似乎需要一个事件来触发它。是的,要使用点功能,您需要使用setCoordinates()更新点的坐标。