欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

openlayers之轨迹回放

程序员文章站 2022-07-05 12:55:16
...

效果图

openlayers之轨迹回放

老规矩,直接上代码,已经把该备注的都备注好了(可直接复制查看)

	<div id="map"></div>
	<label for="speed">
	    speed:&nbsp;
	    <input id="speed" type="range" min="10" max="999" step="10" value="60">
	</label>
	<button id="start-animation">Start Animation</button>
<script>
	var center =  [-5639523.95, -3501274.52];

    var map = new ol.Map({
    target: document.getElementById('map'),
    view: new ol.View({
        center: center,
        zoom: 10 ,
        minZoom: 2,
        maxZoom: 18,
    }),
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM(),    //底图
        }) ],
    });
    //polyline 从官网拿到的json数据,最后转为[[],[],[]...]
    var polyline = '[email protected]`[email protected]}@[email protected]??aC^[email protected][email protected]@b[wFdE??wFfE}NfIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^aMyBiHOkFNoI`CcVvM??gG^[email protected]??eCcA]OoL}[email protected][email protected]\\[email protected]@{vA}[email protected]}{@iRaqE{[email protected]_T{][email protected]{PmhEwaA{[email protected]]wQeEgtAsZ}LiCarAkVwI}D??_}[email protected]@[email protected]@gV}TiYs[uTwXoNmT{[email protected]]{[email protected][email protected]_G}YsFw][email protected][email protected][email protected]|@[email protected][email protected]@[email protected]@[email protected]@{[email protected]@[email protected]@[email protected]@[email protected]@{[email protected]}[email protected]@[email protected]~C{[email protected]@[email protected]{[email protected]_~QHeU`IuyDrC_}@[email protected]?qMbD}{AIkeAgBk_A_A{[email protected]@qH{[email protected]@qH{`@[email protected]@kL{[email protected]@ymBgwE}[email protected][email protected]@[email protected][email protected]}|[email protected]^eaC}L{dAaJ_aAiOyjByH{nAuYu`[email protected]{[email protected]}@[email protected]`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrXitAhT}[email protected]}[email protected][email protected]}A~JovAxCqW~WanB`XewBbK{_A`K}[email protected]}}@[email protected][email protected]@cDs[[email protected][email protected]@eZcDwjBoGw`BoMegBaU_`[email protected][email protected][email protected]@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o~CfIewG|[email protected]}RorAoVajA_nAodD{[y`[email protected]@[email protected]{[email protected]|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`[email protected]}[email protected][email protected]_lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\[email protected]_wAyTwpBmPc|BwZknFoFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}[email protected][email protected]`EuiBudIabB{hF{[email protected]`[email protected]~BkoAi}[email protected]@}`@oaXi_C}[email protected]|[email protected]]kgPcaAu}[email protected]\\[email protected]@siO{[ol\\kCmjMe\\[email protected]}EqiBaCg}@[email protected][email protected]`[email protected]{[email protected]{[email protected]_yCu\\wyCwyA{[email protected]}rO{{[email protected]_bAumFo}[email protected]~AkzDlhA}xEvcBa}[email protected]@`rAo|@~bBq{@``[email protected]@[email protected]@nfC_eC|[email protected]}@``Fi~FpnAooC|[email protected]}[email protected]}[email protected]@woBhR{gCwGkgCc[[email protected][[email protected]@[email protected]@[email protected]@`[email protected]@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@[email protected]{AkB{[email protected]_bYmC}[email protected]@[email protected]{X_{[email protected]{[email protected]@[email protected][email protected]@XcQ|@oNdCoSfFwXhEmOnLi\\lbAulB`[email protected]|[email protected]@[email protected]@bqC}{BhwDgcD`[email protected]@??bL{G|[email protected]@oS~][email protected]|[email protected]}Jv}[email protected]{[email protected]_]`|[email protected]@wSb{@[email protected]`RooQ~e[upZbuIolI|[email protected]@nMmJ|OeJn^{[email protected]@[email protected]@kAp~BkBxO{@|QsAfYgEtYiGd]}[email protected]`[email protected]@vgK}cJnSoSzQkVvUm^[email protected]`[email protected]\\[email protected]~kDyq[[email protected]@[email protected]@[email protected]@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB_}D~NgY`\\[email protected][[email protected]{Cw`G`[email protected]{AdjAwzBh{C}`[email protected]@}[email protected]{[email protected][email protected]`CuOlC}YnAcV`@_^[email protected]}@[email protected]^uCkZiGk\\yGeY}[email protected][uWi[[email protected]@[email protected]@asAcyAklA}qAwHkGi{@[email protected]_{B}IsJuEeFymAssAkdAmhAyTcVkFeEoKiH}[email protected]@[email protected]@[email protected]@[email protected]@}EsFmG}Jk^[email protected][email protected][email protected]@[email protected]@[email protected]@??kF}D??OL'
    var route = new ol.format.Polyline({
        factor: 1e6,
    }).readGeometry(polyline, {
        dataProjection: 'EPSG:4326',
        featureProjection: 'EPSG:3857',
    });
    var routeLength = route.A.length;
    var routeCoords = []
    var routeCoordsX = []
    var routeCoordsY = []
    for(var i=0;i<route.A.length;i++) {
        if(i%2 ==0){
            routeCoordsX.push(route.A[i])
        }else{
            routeCoordsY.push(route.A[i])
        }
    }
    // 将[1,2,3,4,5,6...]转为[[1,2],[3,4],[5,6]...]
    for(var i=0;i<routeCoordsX.length;i++) {
        routeCoords.push([routeCoordsX[i],routeCoordsY[i]])
    }
    // 矢量元素要呈现的几何图形的特征属性LineString代表线段
    var routes = new ol.geom.LineString(routeCoords);
    var routeLength = routeCoords.length;
    // var routeCoords =[
    //     [120.97202539443971,29.149083495140076],
    //     [121.27202539443971,29.149083495140076],
    //     [121.99202539443971,29.149083495140076],
    //     [122.27202539443971,29.149083495140076],
    //     [123.27202539443971,29.149083495140076],
    //     [123.97202539443971,29.149083495140076],
    //     [125.0260719060898,30.149083495140076],
    //     [129.0260719060898,29.115327894687653]
    // ]
    // var route = new ol.geom.LineString(routeCoords);
    // 定义矢量元素
    var routeFeature = new ol.Feature({
        type: 'route',
        geometry: routes,
    });
    var geoMarker = new ol.Feature({
        type: 'geoMarker',
        geometry: new ol.geom.Point(routeCoords[0]),
    });
    var startMarker = new ol.Feature({
        type: 'iconStart',
        geometry: new ol.geom.Point(routeCoords[0]),
    });
    var endMarker = new ol.Feature({
        type: 'iconEnd',
        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],
            }),
        }),
        'iconStart': new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 0.5],
                src: './startSend.png',
            }),
        }),
        'iconEnd': new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 0.5],
                src: './endAll.png',
            }),
        }),
        'geoMarker': new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 0.5],     //图标中心
                src: './plane.png',
                scale: 0.6,
                rotation:-Math.atan2(routeCoords[0][1]-routeCoords[1][1], routeCoords[0][0]-routeCoords[1][0]),
                rotateWithView:true
            }),
        }),
    };
    // 是否处于动画状态
    var animating = false;
    // 定义的是图层类型Vector代表矢量图层源
    var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [routeFeature, geoMarker, startMarker, endMarker],
        }),
        style: function (feature) {
            console.log(feature.get('type'))
            if (animating && feature.get('type') === 'geoMarker') {
                return null;
            }
            return styles[feature.get('type')];
        },
    });

    map.addLayer(vectorLayer);

    var speed, startTime;
    var speedInput = document.getElementById('speed');
    var startButton = document.getElementById('start-animation');
    // 动画方法
    function moveFeature(event) {
        // console.log(event)
        var vectorContext = event.vectorContext
        // var vectorContext = getVectorContext(event);
        var frameState = event.frameState;
        var carStyle,rotation;
        // 开始动画
        if (animating) {
            var elapsedTime = frameState.time - startTime;
            var index = Math.round(speed * elapsedTime/1000);   //已经走了多少个点
            // 点走完停止动画
            if (index >= routeCoords.length) {
                stopAnimation(true);
                return;
            }
            if(routeCoords[index] && routeCoords[index+1]){
                // console.log(route.A[index],route.A[index+1])
                x=routeCoords[index][0]-routeCoords[index+1][0];
                y=routeCoords[index][1]-routeCoords[index+1][1];
                // 返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的弧度值
                rotation = Math.atan2(y,x);
                console.log(rotation)
                // 设置动画时的图标
                carStyle= new ol.style.Style({
                    image: new ol.style.Icon({
                        src: './plane.png',
                        rotateWithView: false,
                        rotation: (-rotation+(Math.atan2(routeCoords[0][1]-routeCoords[1][1], routeCoords[0][0]-routeCoords[1][0])/2)),
                        scale:0.6,
                        anchor: [0.5, 0.5],     //图标中心
                    })
                });
                // 矢量元素要呈现的几何图形的特征属性Point代表点
                var currentPoint = new ol.geom.Point(routeCoords[index]);
                // 添加矢量元素
                var feature = new ol.Feature(currentPoint);
                // 将特征渲染到画布中(功能,样式)
                vectorContext.drawFeature(feature, carStyle);
            }
            
        }
        map.render();
    }
    function startAnimation() {
        // console.log(animating)
        if (animating) {
            stopAnimation(false);
        } else {
            animating = true;
            startTime = new Date().getTime();
            speed = speedInput.value;
            startButton.textContent = 'Cancel Animation';
            // 隐藏geoMarker
            geoMarker.changed();
            // just in case you pan somewhere else
            map.getView().setCenter(center);
            // 添加事件,地图渲染时触发
            map.on('postcompose', moveFeature);
            map.render();
        }
    }
    function stopAnimation(ended) {
        animating = false;
        startButton.textContent = 'Start Animation';
        // if animation cancelled set the marker at the beginning
        var coord = route.getCoordinateAt(ended ? 1 : 0);
        geoMarker.getGeometry().setCoordinates(coord);
        // remove listener
        map.un('postcompose', moveFeature);
    }
    startButton.addEventListener('click', startAnimation, false);
</script>
相关标签: openlayers gis