美文网首页
七章-85-路径回放

七章-85-路径回放

作者: 彩云飘过 | 来源:发表于2020-03-27 17:54 被阅读0次

    本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers 5.3.x api。

    源码 见 1085.html ,对应的 官网示例 https://openlayers.org/en/latest/examples/feature-move-animation.html?q=animation

    image.png
    核心技术点:
    通过frameState.time和speed计算得到当前点位的index
    根据index渲染对应的feature
    
    
    image.png
    
    <!DOCTYPE html>
    <html>
    
    <head>
     <title>路径回放</title>
     <link rel="stylesheet" href="../include/ol.css" type="text/css" />
     <script src="../include/ol.js"></script>
    </head>
    <style></style>
    
    <body>
     <label for="speed">
       速度:&nbsp;
       <input id="speed" type="range" min="10" max="999" step="10" value="60">
     </label>
     <button id="start-animation">开始移动</button>
     <div id="map" class="map"></div>
     <div id="info">&nbsp;</div>
     <script>
       var polyline = [
         'hldhx@lnau`BCG_EaC??cFjAwDjF??uBlKMd@}@z@??aC^yk@z_@se@b[wFdE??wFfE}N',
         'fIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^',
         'aMyBiHOkFNoI`CcVvM??gG^gF_@iJwC??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_E',
         'kUFmq@hBiOqBgTwS??iYse@gYq\\cp@ce@{vA}s@csJqaE}{@iRaqE{lBeRoIwd@_T{]_',
         'Ngn@{PmhEwaA{SeF_u@kQuyAw]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@',
         'sPua@_OkXaMeT_Nwk@ob@gV}TiYs[uTwXoNmT{Uyb@wNg]{Nqa@oDgNeJu_@_G}YsFw]k',
         'DuZyDmm@i_@uyIJe~@jCg|@nGiv@zUi_BfNqaAvIow@dEed@dCcf@r@qz@Egs@{Acu@mC',
         'um@yIey@gGig@cK_m@aSku@qRil@we@{mAeTej@}Tkz@cLgr@aHko@qOmcEaJw~C{w@ka',
         'i@qBchBq@kmBS{kDnBscBnFu_Dbc@_~QHeU`IuyDrC_}@bByp@fCyoA?qMbD}{AIkeAgB',
         'k_A_A{UsDke@gFej@qH{o@qGgb@qH{`@mMgm@uQus@kL{_@yOmd@ymBgwE}x@ouBwtA__',
         'DuhEgaKuWct@gp@cnBii@mlBa_@}|Asj@qrCg^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAw',
         'Xyn@ywMyOyqD{_@cfIcDe}@y@aeBJmwA`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrX',
         'itAhT}x@bE}Z_@qW_Kwv@qKaaAiBgXvIm}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@',
         'xBycBeCauBoF}}@qJioAww@gjHaPopA_NurAyJku@uGmi@cDs[eRaiBkQstAsQkcByNma',
         'CsK_uBcJgbEw@gkB_@ypEqDoqSm@eZcDwjBoGw`BoMegBaU_`Ce_@_uBqb@ytBwkFqiT_',
         'fAqfEwe@mfCka@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o',
         '~CfIewG|YibQxBssB?es@qGciA}RorAoVajA_nAodD{[y`AgPqp@mKwr@ms@umEaW{dAm',
         'b@umAw|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`Fux@}_Dui@_eB_u@guCuyAuiHukA_',
         'lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\sgBsSglAqk@yvDcS_wAyTwpBmPc|BwZknF',
         'oFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq@m~Hym@c`EuiBudIabB{hF{pWifx@snA',
         'w`GkFyVqf@y~BkoAi}Lel@wtc@}`@oaXi_C}pZsi@eqGsSuqJ|Lqeb@e]kgPcaAu}SkDw',
         'zGhn@gjYh\\qlNZovJieBqja@ed@siO{[ol\\kCmjMe\\isHorCmec@uLebB}EqiBaCg}',
         '@m@qwHrT_vFps@kkI`uAszIrpHuzYxx@e{Crw@kpDhN{wBtQarDy@knFgP_yCu\\wyCwy',
         'A{kHo~@omEoYmoDaEcPiuAosDagD}rO{{AsyEihCayFilLaiUqm@_bAumFo}DgqA_uByi',
         '@swC~AkzDlhA}xEvcBa}Cxk@ql@`rAo|@~bBq{@``Bye@djDww@z_C_cAtn@ye@nfC_eC',
         '|gGahH~s@w}@``Fi~FpnAooC|u@wlEaEedRlYkrPvKerBfYs}Arg@m}AtrCkzElw@gjBb',
         'h@woBhR{gCwGkgCc[wtCuOapAcFoh@uBy[yBgr@c@iq@o@wvEv@sp@`FajBfCaq@fIipA',
         'dy@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@s@g{AkB{bBif@_bYmC}r@kDgm@sPq_BuJ_',
         's@{X_{AsK_d@eM{d@wVgx@oWcu@??aDmOkNia@wFoSmDyMyCkPiBePwAob@XcQ|@oNdCo',
         'SfFwXhEmOnLi\\lbAulB`X_d@|k@au@bc@oc@bqC}{BhwDgcD`l@ed@??bL{G|a@eTje@',
         'oS~]cLr~Bgh@|b@}Jv}EieAlv@sPluD{z@nzA_]`|KchCtd@sPvb@wSb{@ko@f`RooQ~e',
         '[upZbuIolI|gFafFzu@iq@nMmJ|OeJn^{Qjh@yQhc@uJ~j@iGdd@kAp~BkBxO{@|QsAfY',
         'gEtYiGd]}Jpd@wRhVoNzNeK`j@ce@vgK}cJnSoSzQkVvUm^rSgc@`Uql@xIq\\vIgg@~k',
         'Dyq[nIir@jNoq@xNwc@fYik@tk@su@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB',
         '_}D~NgY`\\um@v[gm@v{Cw`G`w@o{AdjAwzBh{C}`Gpp@ypAxn@}mAfz@{bBbNia@??jI',
         'ab@`CuOlC}YnAcV`@_^m@aeB}@yk@YuTuBg^uCkZiGk\\yGeY}Lu_@oOsZiTe[uWi[sl@',
         'mo@soAauAsrBgzBqgAglAyd@ig@asAcyAklA}qAwHkGi{@s~@goAmsAyDeEirB_{B}IsJ',
         'uEeFymAssAkdAmhAyTcVkFeEoKiH}l@kp@wg@sj@ku@ey@uh@kj@}EsFmG}Jk^_r@_f@m',
         '~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL'
       ].join('');
    
       var route = (new ol.format.Polyline({
         factor: 1e6
       }).readGeometry(polyline, {
         dataProjection: 'EPSG:4326',
         featureProjection: 'EPSG:3857'
       }));
    
       console.dir(route)
    
       //获取轨迹上的所有点坐标
       var routeCoords = route.getCoordinates();
       var routeLength = routeCoords.length;
       console.log('routeLength = '+routeLength) //routeLength = 542
    
       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,
             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) {
    
           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; //获取动画已经执行的时间
    
           var index = Math.round(speed * elapsedTime / 1000); //获取到当前应画到的点的索引,index = (当前选中速度 * 已经执行的时间 / 最大速度值)
           console.log(' 已经动画时间 = '+elapsedTime) //
           console.log(' 当前index = '+index +'  ,speed = '+speed) //
           
           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);
         }
    
         map.render();//执行此函数时,又会触发postcompose事件;触发postcompose事件后,会执行函数moveFeature
       };
    
       function startAnimation() {
         if (animating) {
           stopAnimation(false);
         } else {
           animating = true;
           now = new Date().getTime();
           speed = speedInput.value;
           startButton.textContent = '停止移动';
           geoMarker.setStyle(null);//把动画的样式先隐藏,一会为了让它有动画的效果
    
           map.getView().setCenter(center);
           map.on('postcompose', moveFeature);
           map.render();
         }
       }
    
       //若动画结束为终点,则把移动点设置到终点;否则把移动点设置到起点。
       function stopAnimation(ended) {
         animating = false;
         startButton.textContent = '开始移动';
    
    
         var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
         geoMarker.getGeometry().setCoordinates(coord);
    
         map.un('postcompose', moveFeature);
       }
    
       startButton.addEventListener('click', startAnimation, false);
    
    
     </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:七章-85-路径回放

          本文链接:https://www.haomeiwen.com/subject/gboluhtx.html