运动轨迹的demo封装

基于上一篇文章使用OpenLayers3来展示一段运动轨迹的封装拓展

样式参数什么的都写的乱七八糟的,只是简单的实现一下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>openlayers绘制</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"/>
    
    <link href="https://openlayers.org/en/v4.1.0/css/ol.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" type="text/css" media="screen" />
    <script type="text/javascript" src="https://openlayers.org/en/v4.1.0/build/ol.js"></script>
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>

    <style type="text/css">
    body,html,div,ul,li,iframe,p,img{
        border:none;padding:0;margin:0;
    }
    html{
        height: 100%;
    }
    body{
        height: 100%;
        overflow: hidden;
    }
    li{list-style-type: none;}
    #map{
        width:100%;
        height:100%;
    }
    /* 隐藏缩放按钮 */
    /*#map .ol-zoom-in, #map .ol-zoom-out {
      display: none;
    }*/
    #changeBtn1{
        position: absolute;
        bottom: 20px;
        right: 180px;
        width: 150px;
        height: 30px;
        line-height: 30px;
        text-align: center;
        background-color: #ff3366;
    }
    #changeBtn2{
        position: absolute;
        bottom: 20px;
        right: 20px;
        width: 150px;
        height: 30px;
        line-height: 30px;
        text-align: center;
        background-color: white;
    }
    .right-btn{
        position: absolute;
        top: 50px;
        right: 0px; 
        width: 50px;
        height: 50px;
        line-height: 50px;
        background-color: red;
        text-align: center;
        -webkit-transition:all 500ms linear;
        transition:all 500ms linear;
        z-index: 999;
    }
    .right-btn.on{
        right: 150px;
        -webkit-transition:all 500ms linear;
        transition:all 500ms linear;
    }
    .right-view{
        position: absolute;
        top: 0px;
        right: -150px;
        width: 150px;
        height: 100%;
        line-height: 100%;
        background-color: #ccc;
        -webkit-transition:all 500ms linear;
        transition:all 500ms linear;
        z-index: 999;
    }
    .right-view.on{
        right: 0px;
        -webkit-transition:all 500ms linear;
        transition:all 500ms linear;
    }
    .time-view{
        position: absolute;
        left: 3em;
        top: 0.5em;
        width: 100px;
        line-height: 1.5em;
        text-align: center;
        background-color: white;
    }
    .player{
        position: absolute;
        left: 3em;
        top: 3em;
        width: 200px;
    }
    .player li{
        line-height: 20px;
        padding: 0px 5px;
        color: white;
        background-color: #ccc;
        overflow: hidden;
    }
    .player .player-color{
        margin-top: 3px;
        width: 14px;
        height: 14px;
        float: left;
    }
    .player .green{background-color: green}
    .player .blue{background-color: blue}
    .player .red{background-color: red}
    .player .player-info{margin-left: 5px; float: left;}
    .player .player-live{float: right;}
    .grade{position: absolute; width: 210px; left: 5%; bottom: 45px;}
    .grade li {margin-top: 5px; padding: 0 5px; width: 200px; line-height: 20px; background-color: #eee; overflow: hidden;}
    .grade .checkPoint{float: left;}
    .grade .number{float: left; margin-left: 20px;}
    .grade .distance{float: right;}
    .grade .ranking{float: left; width: 15px;}
    .grade img{float: left; margin: 0px 5px; width: 20px; height: 20px;}
    .grade .name{float: left;}
    .grade .time{float: right;}
    .newGrade {position: absolute; width: 90% !important; max-width: 400px; line-height: 20px; left: 5%; bottom: 20px; background-color: #eee; padding: 0 5px;}
    .newGrade img {float: left; margin: 0px 5px 0px 20px; width: 20px; height: 20px;}
    .newGrade .name{float: left;}
    .newGrade .time {float: right; margin-right: 30px;}
    .newGrade .slow-time{background-color: black; width: 100px; line-height: 20px; text-align: center; color: white; position: absolute; right: 0px; bottom: 25px;}
    </style>

</head>
<body>
    <div id="map" class="map"></div>
    <div id="changeBtn1" class="changeBtn2" onclick="changeMap1()">谷歌卫星图(默认)</div>
    <div id="changeBtn2" class="changeBtn2" onclick="changeMap2()">谷歌地形图</div>
    <div class="right-btn" onclick="showHideRightView()">点击</div>
    <div class="right-view">这是一个侧边栏</div>
    <div class="time-view">00:09:35</div>
    <div class="player">
        <li><div class="player-color green"></div><div class="player-info">XXXXXX 张三</div><div class="player-live">LIVE</div></li>
        <li><div class="player-color blue"></div><div class="player-info">XXXXXX 张三</div><div class="player-live">LIVE</div></li>
        <li><div class="player-color red"></div><div class="player-info">XXXXXX 张三</div><div class="player-live">LIVE</div></li>
    </div>
    <div class="grade">
        <li><div class="checkPoint">检查点</div><div class="number">49</div><div class="distance">3.7KM</div></li>
        <li><div class="ranking">1.</div><img src="" /><div class="name">张三</div><div class="time">10:45</div></li>
        <li><div class="ranking">2.</div><img src="" /><div class="name">李四</div><div class="time">10:45</div></li>
        <li><div class="ranking">3.</div><img src="" /><div class="name">王五</div><div class="time">10:45</div></li>
    </div>
    <div class="newGrade">
        <img src="" />
        <div class="name">王五</div>
        <div class="time">10:45</div>
        <div class="slow-time">-2:09</div>
    </div>
    <script type="text/javascript">

        //使用瓦片
        // 初始给的中心点坐标。
        var centerX = 10711315.612909358;
        var centerY = 1900873.5099405567;
        var extent = [centerX, centerY, centerX, centerY];

        var layer1 = new ol.layer.Tile({
                source: new ol.source.XYZ({
                    url:'http://mt2.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=G' //谷歌瓦片
                }), 
            }); // 谷歌卫星地图(混合)
        var layer2 = new ol.layer.Tile({
                source: new ol.source.XYZ({
                    url:'http://mt3.google.cn/vt/lyrs=t@131,r@216000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Gal'//谷歌地形地图  
                }), 
            }); // 谷歌地形地图
        var layerImage = new ol.layer.Image({
                source: new ol.source.ImageStatic({
                    url: 'images/mapTest.jpg',//这里添加静态图片的地址
                    // url: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1512636538327&di=1198aa77a3df42bd8046d0353502904c&imgtype=0&src=http%3A%2F%2Foss.p.t262.com%2Fcpic%2Fbc%2F2e%2Fdec7377951965a2d1dca25d006522ebc.jpg',
                    imageExtent: [centerX-500, centerY-500, centerX+500, centerY+500],// 地图坐标中的图像的范围。这是图像的[左,右,右,上]地图坐标
                }), 
            }); // 自定义的地图图片

        //实例一个map
        var map = new ol.Map({
            layers: [
                // 请注意,图层按照提供的顺序进行渲染,因此,如果要使矢量图层显示在拼贴图层的顶部,则必须放在拼贴图层之后。
                layer2,
                layer1,
                // layerImage, 
            ],
            target: 'map',
            view: new ol.View({
                center: [centerX, centerY], //3857坐标系
                zoom: 17,//当前的放大度数
                minZoom:5,//最小放大度数
                maxZoom:19,//最大放大度数
                // extent: extent, // Jon: 限制中心的程度,换句话说,中心不能超出这个范围, 前后值一样(minx=maxx, miny=maxy)的话就无法移动。
                // Jon: 设置minZoom 和 maxZoom 一样大,就无法缩放。
            }),
            logo: false, // 禁用地图标志
        });

        //实例一个数据源获取feature
        //实例化一个矢量图层Vector作为绘制层
        var source = new ol.source.Vector();

        // 需要传入的轨迹数据
        var arr = [
            [10711293.51783087, 1900921.581665377],
            [10711332.930673579, 1900920.9845010934],
            [10711337.707987847, 1900825.4382157368],
            [10711293.51783087, 1900826.0353800203],
        ];
        var arr1 = [
            [10711293.51783087, 1900721.581665377],
            [10711332.930673579, 1900720.9845010934],
            [10711337.707987847, 1900625.4382157368],
            [10711293.51783087, 1900626.0353800203],
        ];
        // 管理线的数据
        var lineDic = {};
        // 管理点的数据
        var pointDic = {};
        // 管理线的源
        var featureLineDic = {};
        // 管理点的源
        var featurePointDic = {};
        // 封装一个方法,来创建全局变量的内容
        // arr: 传入的数组数据, key: 管理所用的key
        function createNewGeom(arr, key) {
            //实例一个线(标记点), Point 点, LineString 线, Polygon 多边形
            var geomLine = new ol.geom.LineString();
            var geomPoint = new ol.geom.Point([arr[3][0], arr[3][1]]);
            //添加标记点
            for (var i = 0; i < arr.length; i++) {
                geomLine.appendCoordinate(arr[i]);
            }
            // 加入管理数组中,方便外部调用
            lineDic[key] = geomLine; 
            pointDic[key] = geomPoint;

            var LineStringFeature = new ol.Feature(geomLine); //绘制线的数据
            var pointFeature = new ol.Feature(geomPoint); //绘制点的数据
            featureLineDic[key] = LineStringFeature;
            featurePointDic[key] = pointFeature;

            //将线添加到Vector绘制层上
            source.addFeature(LineStringFeature);
            source.addFeature(pointFeature);
        }

        //将线添加到Vector绘制层上
        var vectorLayer = new ol.layer.Vector({
            source: source,
            style: new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: '#f00',
                    width: 4
                }),
                image: new ol.style.Icon({
                    src: 'images/map.png',
                    anchor: [0.5, 35], //相对位置
                    anchorYUnits: 'pixels',
                }),
            })
        });
        map.addLayer(vectorLayer); //将绘制层添加到地图容器中

        // 开启某条线的运动轨迹
        // arr: 运动的轨迹数据, key: 需要开启运行的线
        function startMove(arr, key) {
            // 点和线都要开始运动
            var geomLine = lineDic[key];
            var geomPoint = pointDic[key];
            // 频率
            var key = setInterval(function(){
                // 暂时,可删除。
                var length = arr.length-1;
                var lngX = arr[length][0];
                var lngY = arr[length][1];
                lngX = lngX - Math.random() * 30;  
                lngY = lngY + Math.random() * 30;
                var newPoint = [lngX, lngY];
                arr.shift();
                arr.push(newPoint);
                // 更新点和线的位置
                geomLine.setCoordinates(arr);
                geomPoint.setCoordinates(newPoint);
            }, 300);

            setTimeout(function(){
                clearInterval(key);
            }, 3000);
        }

        // 移除某条轨迹
        // key: 需要关闭的线
        function removeGeom(key){
            // setTimeout(function(){
                console.log("移除某一条轨迹");
                if(featureLineDic[key]){
                    var LineStringFeature = featureLineDic[key];
                    source.removeFeature(LineStringFeature);
                } 
                if(featurePointDic[key]){
                    var pointFeature = featurePointDic[key];
                    source.removeFeature(pointFeature);
                }
                delete featureLineDic[key];
                delete featurePointDic[key];
            // }, 5000);
        }

        // webSocket部分
        var websocket;
        var host = "ws://echo.websocket.org/";//声明host注意:是ws协议
        //判断当前浏览器是否支持WebSocket  
        if('WebSocket' in window){  
            websocket = new WebSocket(host); 
        }  
        else{  
            alert('当前浏览器不支持WebSocket'); 
        } 

        websocket.onopen = function (evt) { onOpen(evt) }; 
        websocket.onclose = function (evt) { onClose(evt) }; 
        websocket.onmessage = function (evt) { onMessage(evt) }; 
        websocket.onerror = function (evt) { onError(evt) }; 
        function onOpen(evt) { 
            console.log("Connected to WebSocket server."); 
        } 
        function onClose(evt) { 
            console.log("Disconnected"); 
        } 
        function onMessage(evt) { 
            console.log('Retrieved data from server: ' + evt.data); 
        } 
        function onError(evt) { 
            console.log('Error occured: ' + evt.data); 
        }

        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。  
        window.onbeforeunload = function(){  
            onClose(evt);  
        } 

        // 底层地图层的切换
        function changeMap1() {
            layer1.setVisible(true);
            layer2.setVisible(false);
        }
        function changeMap2() {
            layer1.setVisible(false);
            layer2.setVisible(true);
        }

        // 侧边栏的隐藏/显示
        function showHideRightView() {
            $(".right-btn").toggleClass('on');
            $(".right-view").toggleClass('on');
            removeGeom("one");
        }

        // 创建运动轨迹
        createNewGeom(arr, "one");
        createNewGeom(arr1, "two");
        // 开启运动轨迹
        startMove(arr, "one");
        startMove(arr1, "two");
        // 停止运动轨迹
        // removeGeom("one");


    </script>
</body>
</html>

现在需要对地图进行封装修改了一遍代码, 以下是修改的地方。

var mapDic = {};// 管理地图
var lineDic = {};// 管理线的数据
var pointDic = {};// 管理点的数据
var featureLineDic = {};// 管理线的源: Feature
var featurePointDic = {};// 管理点的源: Feature
// 创建地图控件
// 此处的id, 就是对应div的id
// obj: id, layer, centerX, centerY, zoom, layer, minZoom, maxZoom, extent
function creatMap(obj) {
    var map = new ol.Map({
        layers: [
            obj.layer,
        ],
        target: obj.id,
        view: new ol.View({
            center: [obj.centerX, obj.centerY], //3857坐标系
            zoom: obj.zoom,//当前的放大度数
            minZoom: obj.minZoom,//最小放大度数
            maxZoom: obj.maxZoom,//最大放大度数
            // extent: obj.extent, // Jon: 限制中心的程度,换句话说,中心不能超出这个范围, 前后值一样(minx=maxx, miny=maxy)的话就无法移动。
        }),
        logo: false, // 禁用地图标志
    });
    mapDic[obj.id] = map;
}

// 封装一个方法,来创建全局变量的内容
// arr: 传入的数组数据, key: 管理所用的key
function createNewGeom(arr, key, id) {
    //实例一个数据源获取feature
    //实例化一个矢量图层Vector作为绘制层
    var source = new ol.source.Vector();// 这个东西本来是在外边放的,现在放在里边,不知道会有什么需要优化的地方
    //实例一个线(标记点), Point 点, LineString 线, Polygon 多边形
    var geomLine = new ol.geom.LineString();
    var geomPoint = new ol.geom.Point([arr[3][0], arr[3][1]]);
    //添加标记点
    for (var i = 0; i < arr.length; i++) {
        geomLine.appendCoordinate(arr[i]);
    }
    // 加入管理数组中,方便外部调用
    lineDic[key] = geomLine; 
    pointDic[key] = geomPoint;

    var LineStringFeature = new ol.Feature(geomLine); //绘制线的数据
    var pointFeature = new ol.Feature(geomPoint); //绘制点的数据
    featureLineDic[key] = LineStringFeature;
    featurePointDic[key] = pointFeature;

    //将线添加到Vector绘制层上
    source.addFeature(LineStringFeature);
    source.addFeature(pointFeature);

    //将线添加到Vector绘制层上
    var vectorLayer = new ol.layer.Vector({
        source: source,
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: '#f00',
                width: 4
            }),
            image: new ol.style.Icon({
                src: 'images/map.png',
                anchor: [0.5, 35], //相对位置
                anchorYUnits: 'pixels',
            }),
        })
    });
    console.log("mapDic = ", mapDic);
    mapDic[id].addLayer(vectorLayer); //将绘制层添加到地图容器中
}

var obj = {
    id: "map", 
    layer: layer1, 
    centerX: 10711315.612909358, 
    centerY: 1900873.5099405567, 
    zoom: 17, 
    minZoom: 5, 
    maxZoom: 19, 
    extent: null,
}
// 创建地图
creatMap(obj);
// 创建运动轨迹
createNewGeom(arr, "one", "map");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269