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);