openlayers轨迹匀速播放

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="lib/OpenLayers/ol.css" type="text/css">

    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="lib/OpenLayers/ol.js"></script>
    <script src="olStyle/Light.js"></script>
    <title>Document</title>
    <style>
        html,
        body {
             100%;
            height: 100%;
            margin: 0;
        }

        .map {
             100%;
            height: 100%;
            background: #f6f6f4;
        }

        input[type=range] {
            -webkit-appearance: none;
             300px;
            border-radius: 10px;
            /*这个属性设置使填充进度条时的图形为圆角*/
        }

        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
        }

        input[type=range]::-webkit-slider-runnable-track {
            height: 15px;
            border-radius: 10px;
            /*将轨道设为圆角的*/
            box-shadow: 0 1px 1px #65bdd3, inset 0 .125em .125em #127f9b;
            /*轨道内置阴影效果*/
        }

        input[type=range]:focus {
            outline: none;
        }

        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            height: 25px;
             25px;
            margin-top: -5px;
            /*使滑块超出轨道部分的偏移量相等*/
            background: #08c1e6;
            border-radius: 50%;
            /*外观设置为圆形*/
            border: solid 0.125em rgba(49, 155, 187, 0.5);
            /*设置边框*/
            box-shadow: 0 .125em .125em #08c1e6;
            /*添加底部阴影*/
        }
    </style>
</head>

<body>
    <input type="button" id="tempstop" value="暂停" />
    <input type="button" id="start" value="开始" />
    <input type="button" id="stop" value="停止" />
    <input type="button" id="next" value="前进" />
    <input type="button" id="prev" value="后退" />
    <input type="range" id="sudu" value="800" max="2000" min="100" step="100" />
    <div id="map" class="map" data-id="11"></div>
</body>

</html>
<script type="text/javascript">
    var points = [
        [120.27194738388057, 36.3357839481728]
        , [120.27194738388057, 36.33528166973691]
        , [120.27194738388057, 36.33528266973691]
        , [120.2717328071594, 36.33459124591144]
        , [120.27145385742186, 36.333882530121315]
        , [120.270938873291, 36.33315652189482]
        , [120.27091741561887, 36.332741657013344]
        , [120.2705955505371, 36.33213664176766]
        , [120.27070283889768, 36.33139333089085]
        , [120.27057409286496, 36.33087473770719]
        , [120.27108907699584, 36.33006226811251]
        , [120.27177572250363, 36.32987211443067]
        , [120.27271986007688, 36.329664673521194]
        , [120.27357816696164, 36.32918064258463]
        , [120.27342796325681, 36.32826443293632]
        , [120.27364253997803, 36.32753837235599]
        , [120.27447938919066, 36.327088902892015]
        , [120.2756381034851, 36.326795017609925]
        , [120.27731180191037, 36.32632825635429]
        , [120.27881383895873, 36.32601708063062]
        , [120.28033733367917, 36.32572319130615]
        , [120.28138875961302, 36.32570590366433]
        , [120.2832770347595, 36.32555031471519]
        , [120.28469324111937, 36.32555031471519]
        , [120.28591632843013, 36.32548116397142]
        , [120.2876543998718, 36.325412013166286]
        , [120.2888774871826, 36.325412013166286]
        , [120.29087305068967, 36.3253774377407]
        , [120.29175281524657, 36.32485880451607]
        , [120.29284715652466, 36.3245649108233]
    ]

    var newPoints = []

    function DealPoints() {
        $.each(points, function (i, item) {
            var currLng = parseFloat(item[0]);
            var currLat = parseFloat(item[1]);

            newPoints.push(ol.proj.fromLonLat([currLng, currLat]));

            if ((i + 1) == points.length) {
                return false;
            }

            var nextLng = parseFloat(points[i + 1][0]);
            var nextLat = parseFloat(points[i + 1][1]);

            var diffLng = nextLng - currLng;
            var diffLat = nextLat - currLat;

            var currParamsLng = 0
            var currParamsLat = 0
            //控制速度  标准 0.0001
            var base = 0.000005;

            currParamsLng = Math.sqrt(base * base / (1 + (diffLat / diffLng) * (diffLat / diffLng)));
            currParamsLat = (diffLat / diffLng) * currParamsLng

            currParamsLng = Math.abs(currParamsLng);
            currParamsLat = Math.abs(currParamsLat);

            if (diffLng == 0) {
                currParamsLng = 0;
                currParamsLat = base;
            }

            if (diffLat == 0) {
                currParamsLng = base;
                currParamsLat = 0;
            }

            //当经度差维度差都等于0 :则视为同一个点 不处理
            if (diffLng == 0 && diffLat == 0) {

            }
            //当精度等于0维度不等于0:判断
            else if (diffLng == 0) {
                if (diffLat < 0) {
                    currLat = currLat - currParamsLat;
                    while (currLat > nextLat) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLat = currLat - currParamsLat;
                    }
                }
                else {
                    currLat = currLat + currParamsLat;
                    while (currLat < nextLat) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLat = currLat + currParamsLat;
                    }
                }
            }
            else if (diffLat == 0) {
                if (diffLng < 0) {
                    currLng = currLng - currParamsLng;
                    while (currLng > nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng - currParamsLng;
                    }
                }
                else {
                    currLng = currLng + currParamsLng;
                    while (currLng < nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng + currParamsLng;
                    }
                }
            }
            else {
                if (diffLng > 0 && diffLat > 0) {
                    currLng = currLng + currParamsLng;
                    currLat = currLat + currParamsLat;
                    while (currLng < nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng + currParamsLng;
                        currLat = currLat + currParamsLat;
                    }
                }
                else if (diffLng > 0 && diffLat < 0) {
                    currLng = currLng + currParamsLng;
                    currLat = currLat - currParamsLat;
                    while (currLng < nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng + currParamsLng;
                        currLat = currLat - currParamsLat;
                    }
                }
                else if (diffLng < 0 && diffLat < 0) {
                    currLng = currLng - currParamsLng;
                    currLat = currLat - currParamsLat;
                    while (currLng > nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng - currParamsLng;
                        currLat = currLat - currParamsLat;
                    }
                }
                else if (diffLng < 0 && diffLat > 0) {
                    currLng = currLng - currParamsLng;
                    currLat = currLat + currParamsLat;
                    while (currLng > nextLng) {

                        newPoints.push(ol.proj.fromLonLat([currLng, currLat]));
                        currLng = currLng - currParamsLng;
                        currLat = currLat + currParamsLat;
                    }
                }
            }
        })
    }

    DealPoints();

    var map;

    //轨迹
    var layer = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rgba(255, 0, 0, 0.5)'
            }),
            stroke: new ol.style.Stroke({
                color: 'red',
                 2
            })
        })
    });

    //动画
    var speed;
    //点标记
    var geoMarker
    var endMarker

    //样式
    var style = new ol.style.Style({
        image: new ol.style.Circle({
            radius: 5,
            snapToPixel: false,
            fill: new ol.style.Fill({ color: 'rgba(30,144,255,1)' }),
            stroke: new ol.style.Stroke({
                color: 'rgb(30,144,255)',  2
            })
        })
    });


    var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector()
    });

    //地图初始化
    function InitMap() {
        map = new ol.Map({
            layers: [new ol.layer.Vector({
                source: new ol.source.Vector()
                }),
                style: function (feature, resolution) {
                    switch (feature.get('layer')) {
                        case 'poi':
                            poiStyle.getText().setText(feature.get('name'));
                            return poiStyle;
                        case 'boundary': return boundaryStyle;
                        case 'lawn': return lawnStyle;
                        case 'road':
                            roadStyle.getText().setText(feature.get('name'));
                            return (resolution < 2) ? roadStyle : null;
                        case 'building':
                            return buildingStyle(feature, resolution);
                        case 'other':
                            otherStyle.getText().setText(feature.get('name'));
                            return otherStyle;
                        default: return null;
                    }
                }
            }), layer, vectorLayer],
            target: 'map',
            view: new ol.View({
                center: ol.proj.fromLonLat([120.277, 36.330]),
                minZoom: 1,
                zoom: 16
            })
        });
    }

    /*显示并编辑区域**********************************************************************************/
    function AddPolygon() {
        layer.getSource().clear();

        //var line = new ol.geom.LineString(points);
        var line = new ol.geom.LineString(newPoints);

        var feature = new ol.Feature({
            geometry: line
        });

        layer.getSource().addFeature(feature);

        SetMoveMark();
    }

    function SetMoveMark() {
        geoMarker = new ol.Feature({
            geometry: new ol.geom.Point(newPoints[0])
        });
        geoMarker.setStyle(style)

        endMarker = new ol.Feature({
            geometry: new ol.geom.Point(newPoints[newPoints.length - 1])
        });
        endMarker.setStyle(style);

        vectorLayer.getSource().addFeatures([geoMarker, endMarker]);
    }

    InitMap();

    AddPolygon();

    //动画
    var index = 0;
    var date;
    var tempDate;
    var center = ol.proj.fromLonLat([120.277, 36.330]);
    var calcIndex = 0;

    var moveFeature = function (event) {
        var vectorContext = event.vectorContext;

        var frameState = event.frameState;
        var elapsedTime = frameState.time - date;

        if (ispuse == 0) {
            index = Math.round(speed * elapsedTime / 1000) + calcIndex;
            console.log(calcIndex)
        }

        if (index >= newPoints.length) {
            stopAnimation();
            clearInterval(inter);
            return;
        }

        var currentPoint = new ol.geom.Point(newPoints[index]);
        var feature = new ol.Feature(currentPoint);
        vectorContext.drawFeature(feature, style);

        if (ispuse == 0) {
            map.render();
        }
    };



    function startAnimation() {
        //now = new Date().getTime();
        //speed = 20000 / $("#sudu").val();
        speed = $("#sudu").val();

        geoMarker.setStyle(style);
        map.on('postcompose', moveFeature);
        map.render();
    }


    /**
     * @param {boolean} ended end of animation.
     */
    function stopAnimation() {
        index = 0;
        date = 0;
        tempDate = 0;
        (geoMarker.getGeometry()).setCoordinates(newPoints[0]);
        map.un('postcompose', moveFeature);
    }

    var inter;
    var ispuse = 0;

    $("#tempstop").click(function () {
        //stopAnimation();
        map.render();
        clearInterval(inter);
        tempDate = (new Date()).getTime();
        ispuse = 1;
    })


    $("#start").click(function () {
        if (date == undefined || date == 0) {
            date = (new Date()).getTime();
            calcIndex = 0;
        }

        if (tempDate != undefined && tempDate != 0) {
            date = date + ((new Date()).getTime() - tempDate);
        }

        ispuse = 0;
        startAnimation();
        startMove();
    })

    function startMove() {
        inter = setInterval(function () {
            map.render();
        }, speed);
    }

    $("#stop").click(function () {
        stopAnimation();
        clearInterval(inter);
        calcIndex = 0;
    })

    $("#next").click(function () {
        var tempIndex = index;

        var ispoint = true;
        while (ispoint) {
            var p = newPoints[tempIndex];

            for (i = 0; i < points.length; i++) {
                var p1 = ol.proj.fromLonLat(points[i]);

                if (p[0] == p1[0] && p[1] == p1[1]) {
                    ispoint = false;
                    break;
                }
            }

            tempIndex = tempIndex + 1;

            if (tempIndex >= newPoints.length) {
                ispoint = false;
            }
        }

        calcIndex = tempIndex - index + calcIndex;
        index = tempIndex;
        map.render();
    })

    $("#prev").click(function () {
        var tempIndex = index;

        var ispoint = true;
        while (ispoint) {
            var p = newPoints[tempIndex];

            for (i = 0; i < points.length; i++) {
                var p1 = ol.proj.fromLonLat(points[i]);

                if (p[0] == p1[0] && p[1] == p1[1]) {
                    ispoint = false;
                    break;
                }
            }

            tempIndex = tempIndex - 1;

            if (tempIndex == 0) {
                ispoint = false;
            }
        }

        calcIndex = tempIndex - index + calcIndex;
        index = tempIndex;
        map.render();
    })

</script>

  

原文地址:https://www.cnblogs.com/zhoushangwu/p/9476007.html