Merge pull request #4140 from tsauerwein/animation-flights
Add flight animation example
This commit is contained in:
1
examples/data/openflights/flights.json
Normal file
1
examples/data/openflights/flights.json
Normal file
File diff suppressed because one or more lines are too long
@@ -83,7 +83,7 @@ function flash(feature) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// tell OL3 to continue postcompose animation
|
// tell OL3 to continue postcompose animation
|
||||||
frameState.animate = true;
|
map.render();
|
||||||
}
|
}
|
||||||
listenerKey = map.on('postcompose', animate);
|
listenerKey = map.on('postcompose', animate);
|
||||||
}
|
}
|
||||||
|
|||||||
21
examples/flight-animation.html
Normal file
21
examples/flight-animation.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
layout: example.html
|
||||||
|
title: Flight animation example
|
||||||
|
shortdesc: Demonstrates how to animate flights with ´postcompose´.
|
||||||
|
docs: >
|
||||||
|
This example shows how to use <b>postcompose</b> and <b>vectorContext</b> to
|
||||||
|
animate flights. A great circle arc between two airports is calculated using
|
||||||
|
<a href="https://github.com/springmeyer/arc.js">arc.js</a> and then the flight
|
||||||
|
paths are animated with <b>postcompose</b>. The flight data is provided by
|
||||||
|
<a href="http://openflights.org/data.html">OpenFlights</a> (a simplified data
|
||||||
|
set from the <a href="https://www.mapbox.com/mapbox.js/example/v1.0.0/animating-flight-paths/">
|
||||||
|
Mapbox.js documentation</a> is used).
|
||||||
|
tags: "animation, vector, feature, flights, arc"
|
||||||
|
resources:
|
||||||
|
- https://api.mapbox.com/mapbox.js/plugins/arc.js/v0.1.0/arc.js
|
||||||
|
---
|
||||||
|
<div class="row">
|
||||||
|
<div class="span8">
|
||||||
|
<div id="map" class="map"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
135
examples/flight-animation.js
Normal file
135
examples/flight-animation.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// NOCOMPILE
|
||||||
|
// this example uses arc.js for which we don't have an externs file.
|
||||||
|
goog.require('ol.Attribution');
|
||||||
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.Map');
|
||||||
|
goog.require('ol.View');
|
||||||
|
goog.require('ol.control');
|
||||||
|
goog.require('ol.geom.LineString');
|
||||||
|
goog.require('ol.layer.Tile');
|
||||||
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.proj');
|
||||||
|
goog.require('ol.source.Stamen');
|
||||||
|
goog.require('ol.source.Vector');
|
||||||
|
goog.require('ol.style.Stroke');
|
||||||
|
goog.require('ol.style.Style');
|
||||||
|
|
||||||
|
var map = new ol.Map({
|
||||||
|
layers: [
|
||||||
|
new ol.layer.Tile({
|
||||||
|
source: new ol.source.Stamen({
|
||||||
|
layer: 'toner'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
controls: ol.control.defaults({
|
||||||
|
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
|
||||||
|
collapsible: false
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
renderer: 'canvas',
|
||||||
|
target: 'map',
|
||||||
|
view: new ol.View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 2
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var defaultStroke = new ol.style.Stroke({
|
||||||
|
color: '#EAE911',
|
||||||
|
width: 2
|
||||||
|
});
|
||||||
|
var defaultStyle = new ol.style.Style({
|
||||||
|
stroke: defaultStroke
|
||||||
|
});
|
||||||
|
|
||||||
|
var pointsPerMs = 0.1;
|
||||||
|
var animateFlights = function(event) {
|
||||||
|
var vectorContext = event.vectorContext;
|
||||||
|
var frameState = event.frameState;
|
||||||
|
vectorContext.setFillStrokeStyle(null, defaultStroke);
|
||||||
|
|
||||||
|
var features = flightsSource.getFeatures();
|
||||||
|
for (var i = 0; i < features.length; i++) {
|
||||||
|
var feature = features[i];
|
||||||
|
if (!feature.get('finished')) {
|
||||||
|
// only draw the lines for which the animation has not
|
||||||
|
// finished yet
|
||||||
|
var coords = feature.getGeometry().getCoordinates();
|
||||||
|
var elapsedTime = frameState.time - feature.get('start');
|
||||||
|
var elapsedPoints = elapsedTime * pointsPerMs;
|
||||||
|
|
||||||
|
if (elapsedPoints >= coords.length) {
|
||||||
|
feature.set('finished', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxIndex = Math.min(elapsedPoints, coords.length);
|
||||||
|
var currentLine = new ol.geom.LineString(coords.slice(0, maxIndex));
|
||||||
|
|
||||||
|
// directly draw the line with the vector context
|
||||||
|
vectorContext.drawLineStringGeometry(currentLine, feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tell OL3 to continue the postcompose animation
|
||||||
|
map.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
var addLater = function(feature, timeout) {
|
||||||
|
window.setTimeout(function() {
|
||||||
|
feature.set('start', new Date().getTime());
|
||||||
|
flightsSource.addFeature(feature);
|
||||||
|
}, timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
var flightsSource = new ol.source.Vector({
|
||||||
|
wrapX: false,
|
||||||
|
attributions: [new ol.Attribution({
|
||||||
|
html: 'Flight data by ' +
|
||||||
|
'<a href="http://openflights.org/data.html">OpenFlights</a>,'
|
||||||
|
})],
|
||||||
|
loader: function(extent, resolution, projection) {
|
||||||
|
var url = 'data/openflights/flights.json';
|
||||||
|
$.ajax({url: url, dataType: 'json', success: function(response) {
|
||||||
|
var flightsData = response.flights;
|
||||||
|
for (var i = 0; i < flightsData.length; i++) {
|
||||||
|
var flight = flightsData[i];
|
||||||
|
var from = flight[0];
|
||||||
|
var to = flight[1];
|
||||||
|
|
||||||
|
// create an arc circle between the two locations
|
||||||
|
var arcGenerator = new arc.GreatCircle(
|
||||||
|
{x: from[1], y: from[0]},
|
||||||
|
{x: to[1], y: to[0]});
|
||||||
|
|
||||||
|
var arcLine = arcGenerator.Arc(100, {offset: 10});
|
||||||
|
if (arcLine.geometries.length === 1) {
|
||||||
|
var line = new ol.geom.LineString(arcLine.geometries[0].coords);
|
||||||
|
line.transform(ol.proj.get('EPSG:4326'), ol.proj.get('EPSG:3857'));
|
||||||
|
|
||||||
|
var feature = new ol.Feature({
|
||||||
|
geometry: line,
|
||||||
|
finished: false
|
||||||
|
});
|
||||||
|
// add the feature with a delay so that the animation
|
||||||
|
// for all features does not start at the same time
|
||||||
|
addLater(feature, i * 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.on('postcompose', animateFlights);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var flightsLayer = new ol.layer.Vector({
|
||||||
|
source: flightsSource,
|
||||||
|
style: function(feature, resolution) {
|
||||||
|
// if the animation is still active for a feature, do not
|
||||||
|
// render the feature with the layer style
|
||||||
|
if (feature.get('finished')) {
|
||||||
|
return defaultStyle;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
map.addLayer(flightsLayer);
|
||||||
Reference in New Issue
Block a user