1 | goog.require('ol.Feature');
|
2 | goog.require('ol.Map');
|
3 | goog.require('ol.View');
|
4 | goog.require('ol.format.Polyline');
|
5 | goog.require('ol.geom.Point');
|
6 | goog.require('ol.layer.Tile');
|
7 | goog.require('ol.layer.Vector');
|
8 | goog.require('ol.source.BingMaps');
|
9 | goog.require('ol.source.Vector');
|
10 | goog.require('ol.style.Circle');
|
11 | goog.require('ol.style.Fill');
|
12 | goog.require('ol.style.Icon');
|
13 | goog.require('ol.style.Stroke');
|
14 | goog.require('ol.style.Style');
|
15 |
|
16 |
|
17 |
|
18 | var polyline = [
|
19 | 'hldhx@lnau`BCG_EaC??cFjAwDjF??uBlKMd@}@z@??aC^yk@z_@se@b[wFdE??wFfE}N',
|
20 | 'fIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^',
|
21 | 'aMyBiHOkFNoI`CcVvM??gG^gF_@iJwC??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_E',
|
22 | 'kUFmq@hBiOqBgTwS??iYse@gYq\\cp@ce@{vA}s@csJqaE}{@iRaqE{lBeRoIwd@_T{]_',
|
23 | 'Ngn@{PmhEwaA{SeF_u@kQuyAw]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@',
|
24 | 'sPua@_OkXaMeT_Nwk@ob@gV}TiYs[uTwXoNmT{Uyb@wNg]{Nqa@oDgNeJu_@_G}YsFw]k',
|
25 | 'DuZyDmm@i_@uyIJe~@jCg|@nGiv@zUi_BfNqaAvIow@dEed@dCcf@r@qz@Egs@{Acu@mC',
|
26 | 'um@yIey@gGig@cK_m@aSku@qRil@we@{mAeTej@}Tkz@cLgr@aHko@qOmcEaJw~C{w@ka',
|
27 | 'i@qBchBq@kmBS{kDnBscBnFu_Dbc@_~QHeU`IuyDrC_}@bByp@fCyoA?qMbD}{AIkeAgB',
|
28 | 'k_A_A{UsDke@gFej@qH{o@qGgb@qH{`@mMgm@uQus@kL{_@yOmd@ymBgwE}x@ouBwtA__',
|
29 | 'DuhEgaKuWct@gp@cnBii@mlBa_@}|Asj@qrCg^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAw',
|
30 | 'Xyn@ywMyOyqD{_@cfIcDe}@y@aeBJmwA`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrX',
|
31 | 'itAhT}x@bE}Z_@qW_Kwv@qKaaAiBgXvIm}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@',
|
32 | 'xBycBeCauBoF}}@qJioAww@gjHaPopA_NurAyJku@uGmi@cDs[eRaiBkQstAsQkcByNma',
|
33 | 'CsK_uBcJgbEw@gkB_@ypEqDoqSm@eZcDwjBoGw`BoMegBaU_`Ce_@_uBqb@ytBwkFqiT_',
|
34 | 'fAqfEwe@mfCka@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o',
|
35 | '~CfIewG|YibQxBssB?es@qGciA}RorAoVajA_nAodD{[y`AgPqp@mKwr@ms@umEaW{dAm',
|
36 | 'b@umAw|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`Fux@}_Dui@_eB_u@guCuyAuiHukA_',
|
37 | 'lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\sgBsSglAqk@yvDcS_wAyTwpBmPc|BwZknF',
|
38 | 'oFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq@m~Hym@c`EuiBudIabB{hF{pWifx@snA',
|
39 | 'w`GkFyVqf@y~BkoAi}Lel@wtc@}`@oaXi_C}pZsi@eqGsSuqJ|Lqeb@e]kgPcaAu}SkDw',
|
40 | 'zGhn@gjYh\\qlNZovJieBqja@ed@siO{[ol\\kCmjMe\\isHorCmec@uLebB}EqiBaCg}',
|
41 | '@m@qwHrT_vFps@kkI`uAszIrpHuzYxx@e{Crw@kpDhN{wBtQarDy@knFgP_yCu\\wyCwy',
|
42 | 'A{kHo~@omEoYmoDaEcPiuAosDagD}rO{{AsyEihCayFilLaiUqm@_bAumFo}DgqA_uByi',
|
43 | '@swC~AkzDlhA}xEvcBa}Cxk@ql@`rAo|@~bBq{@``Bye@djDww@z_C_cAtn@ye@nfC_eC',
|
44 | '|gGahH~s@w}@``Fi~FpnAooC|u@wlEaEedRlYkrPvKerBfYs}Arg@m}AtrCkzElw@gjBb',
|
45 | 'h@woBhR{gCwGkgCc[wtCuOapAcFoh@uBy[yBgr@c@iq@o@wvEv@sp@`FajBfCaq@fIipA',
|
46 | 'dy@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@s@g{AkB{bBif@_bYmC}r@kDgm@sPq_BuJ_',
|
47 | 's@{X_{AsK_d@eM{d@wVgx@oWcu@??aDmOkNia@wFoSmDyMyCkPiBePwAob@XcQ|@oNdCo',
|
48 | 'SfFwXhEmOnLi\\lbAulB`X_d@|k@au@bc@oc@bqC}{BhwDgcD`l@ed@??bL{G|a@eTje@',
|
49 | 'oS~]cLr~Bgh@|b@}Jv}EieAlv@sPluD{z@nzA_]`|KchCtd@sPvb@wSb{@ko@f`RooQ~e',
|
50 | '[upZbuIolI|gFafFzu@iq@nMmJ|OeJn^{Qjh@yQhc@uJ~j@iGdd@kAp~BkBxO{@|QsAfY',
|
51 | 'gEtYiGd]}Jpd@wRhVoNzNeK`j@ce@vgK}cJnSoSzQkVvUm^rSgc@`Uql@xIq\\vIgg@~k',
|
52 | 'Dyq[nIir@jNoq@xNwc@fYik@tk@su@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB',
|
53 | '_}D~NgY`\\um@v[gm@v{Cw`G`w@o{AdjAwzBh{C}`Gpp@ypAxn@}mAfz@{bBbNia@??jI',
|
54 | 'ab@`CuOlC}YnAcV`@_^m@aeB}@yk@YuTuBg^uCkZiGk\\yGeY}Lu_@oOsZiTe[uWi[sl@',
|
55 | 'mo@soAauAsrBgzBqgAglAyd@ig@asAcyAklA}qAwHkGi{@s~@goAmsAyDeEirB_{B}IsJ',
|
56 | 'uEeFymAssAkdAmhAyTcVkFeEoKiH}l@kp@wg@sj@ku@ey@uh@kj@}EsFmG}Jk^_r@_f@m',
|
57 | '~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL'
|
58 | ].join('');
|
59 |
|
60 | var route = (new ol.format.Polyline({
|
61 | factor: 1e6
|
62 | }).readGeometry(polyline, {
|
63 | dataProjection: 'EPSG:4326',
|
64 | featureProjection: 'EPSG:3857'
|
65 | }));
|
66 |
|
67 | var routeCoords = route.getCoordinates();
|
68 | var routeLength = routeCoords.length;
|
69 |
|
70 | var routeFeature = new ol.Feature({
|
71 | type: 'route',
|
72 | geometry: route
|
73 | });
|
74 | var geoMarker = new ol.Feature({
|
75 | type: 'geoMarker',
|
76 | geometry: new ol.geom.Point(routeCoords[0])
|
77 | });
|
78 | var startMarker = new ol.Feature({
|
79 | type: 'icon',
|
80 | geometry: new ol.geom.Point(routeCoords[0])
|
81 | });
|
82 | var endMarker = new ol.Feature({
|
83 | type: 'icon',
|
84 | geometry: new ol.geom.Point(routeCoords[routeLength - 1])
|
85 | });
|
86 |
|
87 | var styles = {
|
88 | 'route': new ol.style.Style({
|
89 | stroke: new ol.style.Stroke({
|
90 | width: 6, color: [237, 212, 0, 0.8]
|
91 | })
|
92 | }),
|
93 | 'icon': new ol.style.Style({
|
94 | image: new ol.style.Icon({
|
95 | anchor: [0.5, 1],
|
96 | src: 'data/icon.png'
|
97 | })
|
98 | }),
|
99 | 'geoMarker': new ol.style.Style({
|
100 | image: new ol.style.Circle({
|
101 | radius: 7,
|
102 | snapToPixel: false,
|
103 | fill: new ol.style.Fill({color: 'black'}),
|
104 | stroke: new ol.style.Stroke({
|
105 | color: 'white', width: 2
|
106 | })
|
107 | })
|
108 | })
|
109 | };
|
110 |
|
111 | var animating = false;
|
112 | var speed, now;
|
113 | var speedInput = document.getElementById('speed');
|
114 | var startButton = document.getElementById('start-animation');
|
115 |
|
116 | var vectorLayer = new ol.layer.Vector({
|
117 | source: new ol.source.Vector({
|
118 | features: [routeFeature, geoMarker, startMarker, endMarker]
|
119 | }),
|
120 | style: function(feature) {
|
121 |
|
122 | if (animating && feature.get('type') === 'geoMarker') {
|
123 | return null;
|
124 | }
|
125 | return styles[feature.get('type')];
|
126 | }
|
127 | });
|
128 |
|
129 | var center = [-5639523.95, -3501274.52];
|
130 | var map = new ol.Map({
|
131 | target: document.getElementById('map'),
|
132 | loadTilesWhileAnimating: true,
|
133 | view: new ol.View({
|
134 | center: center,
|
135 | zoom: 10,
|
136 | minZoom: 2,
|
137 | maxZoom: 19
|
138 | }),
|
139 | layers: [
|
140 | new ol.layer.Tile({
|
141 | source: new ol.source.BingMaps({
|
142 | imagerySet: 'AerialWithLabels',
|
143 | key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
|
144 | })
|
145 | }),
|
146 | vectorLayer
|
147 | ]
|
148 | });
|
149 |
|
150 | var moveFeature = function(event) {
|
151 | var vectorContext = event.vectorContext;
|
152 | var frameState = event.frameState;
|
153 |
|
154 | if (animating) {
|
155 | var elapsedTime = frameState.time - now;
|
156 |
|
157 |
|
158 | var index = Math.round(speed * elapsedTime / 1000);
|
159 |
|
160 | if (index >= routeLength) {
|
161 | stopAnimation(true);
|
162 | return;
|
163 | }
|
164 |
|
165 | var currentPoint = new ol.geom.Point(routeCoords[index]);
|
166 | var feature = new ol.Feature(currentPoint);
|
167 | vectorContext.drawFeature(feature, styles.geoMarker);
|
168 | }
|
169 |
|
170 | map.render();
|
171 | };
|
172 |
|
173 | function startAnimation() {
|
174 | if (animating) {
|
175 | stopAnimation(false);
|
176 | } else {
|
177 | animating = true;
|
178 | now = new Date().getTime();
|
179 | speed = speedInput.value;
|
180 | startButton.textContent = 'Cancel Animation';
|
181 |
|
182 | geoMarker.setStyle(null);
|
183 |
|
184 | map.getView().setCenter(center);
|
185 | map.on('postcompose', moveFeature);
|
186 | map.render();
|
187 | }
|
188 | }
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 | function stopAnimation(ended) {
|
195 | animating = false;
|
196 | startButton.textContent = 'Start Animation';
|
197 |
|
198 |
|
199 | var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
|
200 | (geoMarker.getGeometry())
|
201 | .setCoordinates(coord);
|
202 |
|
203 | map.un('postcompose', moveFeature);
|
204 | }
|
205 |
|
206 | startButton.addEventListener('click', startAnimation, false);
|