本文基于騰訊課堂老胡的課《跟我學(xué)Openlayers--基礎(chǔ)實例詳解》做的學(xué)習(xí)筆記战得,使用的openlayers 5.3.x api。
源碼 見 1040.html 浇冰,對應(yīng)的 官網(wǎng)示例 https://openlayers.org/en/latest/examples/flight-animation.html?q=animation
核心技術(shù)點:
map.on('postcompose', animateFlights)
frameState.time控制時間
使用第三方庫 arc.js 生成曲線
<!DOCTYPE html>
<html>
<head>
<title>航班軌跡</title>
<link rel="stylesheet" href="../include/ol.css" type="text/css" />
<script src="../include/ol.js"></script>
<!--第三方庫际乘,用來生成航班航線的弧線樣式 -->
<script src="../include/arc.js"></script>
</head>
<style></style>
<body>
<div id="map" class="map"></div>
<script>
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.Stamen({ //黑白風(fēng)格的圖層漂佩,硒鼓樣式
layer: 'toner'
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#EAE911',
width: 2
})
});
var flightsSource = new ol.source.Vector({
wrapX: false,
attributions: 'Flight data by ' +
'<a ,
loader: function () {
var url = 'https://openlayers.org/en/latest/examples/data/openflights/flights.json'; //獲取航班出發(fā)點 目的地
//var url = '../data/flights.json'; //獲取航班出發(fā)點 目的地
fetch(url).then(function (response) {
return response.json();
}).then(function (json) {
var flightsData = json.flights;
for (var i = 0; i < flightsData.length; i++) {
var flight = flightsData[i];
var from = flight[0];
var to = flight[1];
// 使用多線段擬合生成的弧線
var arcGenerator = new arc.GreatCircle(
{ x: from[1], y: from[0] },
{ x: to[1], y: to[0] });
//跨越國際日期變更線的航班投蝉,會被切割成兩半养葵;根據(jù)弧線與國際日期變更線之間的偏移量,在10度范圍內(nèi)的瘩缆,將把線分隔開
var arcLine = arcGenerator.Arc(100, { offset: 10 }); //用100個直線模擬弧線
if (arcLine.geometries.length === 1) { //把arcLine 轉(zhuǎn)為 ol中的Line
var line = new ol.geom.LineString(arcLine.geometries[0].coords);
line.transform('EPSG:4326', 'EPSG:3857');
var feature = new ol.Feature({
geometry: line,
finished: false // 標(biāo)記著飛行曲線有沒有繪制完成
});
// 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) {
if (feature.get('finished')) {
return style;
} else {
return null;
}
}
});
map.addLayer(flightsLayer);
var pointsPerMs = 0.1;
function animateFlights(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
vectorContext.setStyle(style);//設(shè)置矢量數(shù)據(jù)源的樣式
var features = flightsSource.getFeatures();
for (var i = 0; i < features.length; i++) {
var feature = features[i];
if (!feature.get('finished')) {
//沒有繪制完的話关拒,根據(jù)繪制時間,判斷該繪制哪些點了
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));
vectorContext.drawGeometry(currentLine);
}
}
map.render();
}
function addLater(feature, timeout) {
window.setTimeout(function () {
feature.set('start', new Date().getTime()); //增加start屬性庸娱,標(biāo)記起始時間
flightsSource.addFeature(feature);
}, timeout);
}
</script>
</body>
</html>