如何从openlayers中连续的数组点绘制线串
How to draw linestring from consecutive points of array in openlayers
我正在尝试在 openlayers 中连续 Points
绘制 LineString
来给它一种动画的感觉,就像它从头到尾都在绘制一样。
我试图通过关注 this example 来实现它。 OL2 的所有引用都转换为 OpenLayers 5,但绘制仍然应该发生一个点,然后是整个数组的下一个点,而不是一次。
在此处查找具有当前输出的代码 - my code。
[供参考]这是我正在努力实现的Snake animation for leaflet。
你的 for 循环
for(i=0;i<path.length;) {
drawAnimatedLine(/*snip*/);
}
基本同时开始所有点的动画,无需等待。在开始下一段之前,您需要等到第一行的动画完成。你的 drawAnimation
函数有第 6 个参数 fn
来为它提供一个函数的函数指针,以便在绘图完成时调用。
这是一个快速的脏版本,我在其中重写了您的 for 循环以演示我的意思。 https://jsbin.com/lanoxojugi/edit?js,output
仅使用线串的顶点不会产生流畅的动画。您可以在 OpenLayers 示例 https://openlayers.org/en/v4.6.5/examples/feature-move-animation.html 中看到,其中标记在直线部分上移动得更快。如果您需要像 OpenLayers 2 示例中那样沿着直线平滑移动,您需要使用 .getCoordinateAt()
来计算您随时应该在直线上的位置。这是一个基于标记动画示例的演示,但也计算显示蛇示例中的线串的顶点之间的位置。您还可以绘制自己的直线并观看它们的动画效果。
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
width: 4,
color: 'red'
})
});
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var vector = new ol.layer.Vector({
source: new ol.source.Vector(),
style: style
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View()
});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
xhr.onload = function() {
// read the route coordinates
eval(xhr.responseText);
// reverse the route
var geom = new ol.geom.LineString(route.reverse());
// change Lat/Lon to Lon/Lat
geom.applyTransform(function(c){ return c.reverse(); });
geom.transform('EPSG:4326', map.getView().getProjection());
map.getView().fit(geom.getExtent(), { size: map.getSize() });
var snake = new ol.Feature();
vector.getSource().addFeature(snake);
animate_line(snake, geom, 30000);
}
xhr.send();
function animate_line(feature, linestring, duration) {
var length = linestring.getLength();
var length_shown = 0;
var coords = linestring.getCoordinates();
var coords_shown = [coords[0], coords[0]];
var geom_shown = new ol.geom.LineString(coords_shown);
feature.setGeometry(geom_shown);
var coordcount = 1;
var start = new Date().getTime();
var listenerKey = map.on('postcompose', animate);
function animate() {
var elapsed = new Date().getTime() - start;
var toAdd = length*elapsed/duration - length_shown;
var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));
// restart from last intermediate point and remove it
var newPart = new ol.geom.LineString(coords_shown.slice(-1));
coords_shown.pop();
// add vertices until required length exceeded
while (coordcount < coords.length && newPart.getLength() <= toAdd) {
newPart.appendCoordinate(coords[coordcount]);
coords_shown.push(coords[coordcount]);
coordcount++;
}
// replace overrun vertex with intermediate point
coords_shown.pop();
coordcount--;
coords_shown.push(point);
geom_shown.setCoordinates(coords_shown);
length_shown += toAdd;
if (elapsed > duration) {
ol.Observable.unByKey(listenerKey);
}
map.render();
}
}
draw = new ol.interaction.Draw({
source: vector.getSource(),
type: 'LineString'
});
draw.on('drawend',function(evt){
geom = evt.feature.getGeometry();
evt.feature.setGeometry(undefined);
animate_line(evt.feature, geom, 6000);
});
map.addInteraction(draw);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
我正在尝试在 openlayers 中连续 Points
绘制 LineString
来给它一种动画的感觉,就像它从头到尾都在绘制一样。
我试图通过关注 this example 来实现它。 OL2 的所有引用都转换为 OpenLayers 5,但绘制仍然应该发生一个点,然后是整个数组的下一个点,而不是一次。
在此处查找具有当前输出的代码 - my code。
[供参考]这是我正在努力实现的Snake animation for leaflet。
你的 for 循环
for(i=0;i<path.length;) {
drawAnimatedLine(/*snip*/);
}
基本同时开始所有点的动画,无需等待。在开始下一段之前,您需要等到第一行的动画完成。你的 drawAnimation
函数有第 6 个参数 fn
来为它提供一个函数的函数指针,以便在绘图完成时调用。
这是一个快速的脏版本,我在其中重写了您的 for 循环以演示我的意思。 https://jsbin.com/lanoxojugi/edit?js,output
仅使用线串的顶点不会产生流畅的动画。您可以在 OpenLayers 示例 https://openlayers.org/en/v4.6.5/examples/feature-move-animation.html 中看到,其中标记在直线部分上移动得更快。如果您需要像 OpenLayers 2 示例中那样沿着直线平滑移动,您需要使用 .getCoordinateAt()
来计算您随时应该在直线上的位置。这是一个基于标记动画示例的演示,但也计算显示蛇示例中的线串的顶点之间的位置。您还可以绘制自己的直线并观看它们的动画效果。
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
width: 4,
color: 'red'
})
});
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var vector = new ol.layer.Vector({
source: new ol.source.Vector(),
style: style
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View()
});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
xhr.onload = function() {
// read the route coordinates
eval(xhr.responseText);
// reverse the route
var geom = new ol.geom.LineString(route.reverse());
// change Lat/Lon to Lon/Lat
geom.applyTransform(function(c){ return c.reverse(); });
geom.transform('EPSG:4326', map.getView().getProjection());
map.getView().fit(geom.getExtent(), { size: map.getSize() });
var snake = new ol.Feature();
vector.getSource().addFeature(snake);
animate_line(snake, geom, 30000);
}
xhr.send();
function animate_line(feature, linestring, duration) {
var length = linestring.getLength();
var length_shown = 0;
var coords = linestring.getCoordinates();
var coords_shown = [coords[0], coords[0]];
var geom_shown = new ol.geom.LineString(coords_shown);
feature.setGeometry(geom_shown);
var coordcount = 1;
var start = new Date().getTime();
var listenerKey = map.on('postcompose', animate);
function animate() {
var elapsed = new Date().getTime() - start;
var toAdd = length*elapsed/duration - length_shown;
var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));
// restart from last intermediate point and remove it
var newPart = new ol.geom.LineString(coords_shown.slice(-1));
coords_shown.pop();
// add vertices until required length exceeded
while (coordcount < coords.length && newPart.getLength() <= toAdd) {
newPart.appendCoordinate(coords[coordcount]);
coords_shown.push(coords[coordcount]);
coordcount++;
}
// replace overrun vertex with intermediate point
coords_shown.pop();
coordcount--;
coords_shown.push(point);
geom_shown.setCoordinates(coords_shown);
length_shown += toAdd;
if (elapsed > duration) {
ol.Observable.unByKey(listenerKey);
}
map.render();
}
}
draw = new ol.interaction.Draw({
source: vector.getSource(),
type: 'LineString'
});
draw.on('drawend',function(evt){
geom = evt.feature.getGeometry();
evt.feature.setGeometry(undefined);
animate_line(evt.feature, geom, 6000);
});
map.addInteraction(draw);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>