openlayers
Version:
Build tools and sources for developing OpenLayers based mapping applications
207 lines (189 loc) • 7.2 kB
JavaScript
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.Polyline');
goog.require('ol.geom.Point');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.BingMaps');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Icon');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
// This long string is placed here due to jsFiddle limitations.
// It is usually loaded with AJAX.
var polyline = [
'hldhx`BCG_EaC??cFjAwDjF??uBlKMd@}@??aC^yk[wFdE??wFfE}N',
'fIoGxB_I\\gG}\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^',
'aMyBiHOkFNoI`CcVvM??gG^gF_??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_E',
'kUFmq??iYse\\cp@{vA}s}{{lBeRoIwd{]_',
'Ngn@{PmhEwaA{SeF_u]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@',
'sPua}TiYs[uTwXoNmT{Uyb]{Nqa}YsFw]k',
'DuZyDmm~|@{Acu',
'um@{mAeTej@}Tkz~C{w',
'i{kDnBscBnFu_Dbc~QHeU`IuyDrC_}?qMbD}{AIkeAgB',
'k_A_A{UsDke{o{`{_}x',
'DuhEgaKuWct@}|Asj^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAw',
'Xyn{_}`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrX',
'itAhT}x}Z_}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@',
'xBycBeCauBoF}}[eRaiBkQstAsQkcByNma',
'CsK_uBcJgbEw`BoMegBaU_`Ce_',
'fAqfEwe}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o',
'~CfIewG|YibQxBssB?es}RorAoVajA_nAodD{[y`AgPqp{dAm',
'b|`Fux@}_Dui',
'lKszAu|OmaA{wKm}\\sgBsSglAqk|BwZknF',
'oFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq~Hym`EuiBudIabB{hF{pWifx',
'w`GkFyVqf~BkoAi}Lel@}`}pZsi|Lqeb]kgPcaAu}SkDw',
'zGhn\\qlNZovJieBqja{[ol\\kCmjMe\\isHorCmec}EqiBaCg}',
'`uAszIrpHuzYxx{Crw{wBtQarDy\\wyCwy',
'A{kHo~}rO{{AsyEihCayFilLaiUqm}DgqA_uByi',
'~AkzDlhA}xEvcBa}Cxk@`rAo|@~bBq{@``Bye',
'|gGahH~s}@``Fi~FpnAooC|u}Arg}AtrCkzElw',
'h{gCwGkgCc[wtCuOapAcFoh[yBgr@`FajBfCaq',
'dy`ExGuaBdEmbBpBssArAuqBBg}{AkB{bBif}r',
's@{X_{AsK_d{d@??aDmOkNia|',
'SfFwXhEmOnLi\\lbAulB`X_d@|k}{BhwDgcD`l@??bL{G|a@',
'oS~]cLr~Bgh@|b@}Jv}EieAlv{z]`|KchCtd{`RooQ~e',
'[upZbuIolI|gFafFzu|OeJn^{Qjh~j~BkBxO{@|QsAfY',
'gEtYiGd]}Jpd`j}cJnSoSzQkVvUm^rSgc@`Uql\\vIgg@~k',
'Dyq[nIir}uBhqEesFjoGeyHtCoD|D}Ed|',
'_}D~NgY`\\um[gm{Cw`G`w{AdjAwzBh{C}`Gpp@}mAfz@{bBbNia@??jI',
'ab@`CuOlC}YnAcV`^m}^uCkZiGk\\yGeY}Lu_[uWi[sl@',
'mo}qAwHkGi{~{B}IsJ',
'uEeFymAssAkdAmhAyTcVkFeEoKiH}l@}EsFmG}Jk^_r',
'~??a@??kF}D??OL'
].join('');
var route = /** @type {ol.geom.LineString} */ (new ol.format.Polyline({
factor: 1e6
}).readGeometry(polyline, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
}));
var routeCoords = route.getCoordinates();
var routeLength = routeCoords.length;
var routeFeature = new ol.Feature({
type: 'route',
geometry: route
});
var geoMarker = new ol.Feature({
type: 'geoMarker',
geometry: new ol.geom.Point(routeCoords[0])
});
var startMarker = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords[0])
});
var endMarker = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(routeCoords[routeLength - 1])
});
var styles = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6, color: [237, 212, 0, 0.8]
})
}),
'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'data/icon.png'
})
}),
'geoMarker': 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 animating = false;
var speed, now;
var speedInput = document.getElementById('speed');
var startButton = document.getElementById('start-animation');
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature, geoMarker, startMarker, endMarker]
}),
style: function(feature) {
// hide geoMarker if animation is active
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
}
});
var center = [-5639523.95, -3501274.52];
var map = new ol.Map({
target: document.getElementById('map'),
loadTilesWhileAnimating: true,
view: new ol.View({
center: center,
zoom: 10,
minZoom: 2,
maxZoom: 19
}),
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'AerialWithLabels',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
}),
vectorLayer
]
});
var moveFeature = function(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
if (animating) {
var elapsedTime = frameState.time - now;
// here the trick to increase speed is to jump some indexes
// on lineString coordinates
var index = Math.round(speed * elapsedTime / 1000);
if (index >= routeLength) {
stopAnimation(true);
return;
}
var currentPoint = new ol.geom.Point(routeCoords[index]);
var feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature, styles.geoMarker);
}
// tell OpenLayers to continue the postcompose animation
map.render();
};
function startAnimation() {
if (animating) {
stopAnimation(false);
} else {
animating = true;
now = new Date().getTime();
speed = speedInput.value;
startButton.textContent = 'Cancel Animation';
// hide geoMarker
geoMarker.setStyle(null);
// just in case you pan somewhere else
map.getView().setCenter(center);
map.on('postcompose', moveFeature);
map.render();
}
}
/**
* @param {boolean} ended end of animation.
*/
function stopAnimation(ended) {
animating = false;
startButton.textContent = 'Start Animation';
// if animation cancelled set the marker at the beginning
var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
/** @type {ol.geom.Point} */ (geoMarker.getGeometry())
.setCoordinates(coord);
//remove listener
map.un('postcompose', moveFeature);
}
startButton.addEventListener('click', startAnimation, false);