使用OpenLayers3来展示一段运动轨迹

网上百度到的基本都是,在已经描绘好的轨迹上进行点的运动,可以参考官方示例。而这里这个有点不一样。
需求:展示在自己的地图(图片)上,描绘最近两分钟的运动轨迹。

不懂的就百度,然后看一下官方API

如果嫌弃官方的API,就看这个吧:OpenLayers 3 Primer

以下代码中的坐标都是用的 EPSG:3857,请注意

  • 第一步:需要一个map图层
    此处有很多图层可以加载,根据各自的需要来就行。参考openlayers3加载各种底图
    我就加载一个常用的吧。代码如下:
// 页面内容
<style type="text/css">
body,html,div,ul,li,iframe,p,img{
    border:none;padding:0;margin:0;
}
#map{
    width:100%;
    height:100%;
}
</style>
<div id="map" class="map"></div>
// js内容
//实例一个map
var map = new ol.Map({
    layers: [
    // vector,
    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' //谷歌瓦片
        })
    })
    ],
    target: 'map',
    view: new ol.View({
       center: [10711315.612909358, 1900873.5099405567], //3857坐标系
       // center: ol.proj.transform([-122.619, 45.512], 'EPSG:4326', 'EPSG:3857'), //openlayers默认的坐标系是'EPSG:3857',标准经纬度坐标系是'EPSG:4326'
       zoom: 17,//当前的放大度数
       minZoom:6,//最小放大度数
       maxZoom:19//最大放大度数
   })
});     
  • 第二步:在map图层上固定你的地图(图片)

其实ol.Map中的layers属性已经介绍了。

image.png

那么,新的代码如下:

// 初始给的中心点坐标。
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, // 限制中心的程度,换句话说,中心不能超出这个范围, 前后值一样(minx=maxx, miny=maxy)的话就无法移动。
      // 设置 minZoom 和 maxZoom 一样大,就无法缩放。
}),
  logo: false, // 禁用地图标志
});
  • 第三步:在地图上描绘轨迹
1. 需要一个绘图层
//实例化一个矢量图层Vector作为绘制层
var source = new ol.source.Vector();
2. 需要一条线和它的数据
//实例一个线(标记点)的全局变量
var geometry = new ol.geom.LineString(); //线,Point 点,Polygon 面

//散列点数组,放置的点的位置数据
var coordinate = [
            [10711293.51783087, 1900921.581665377],
            [10711332.930673579, 1900920.9845010934],
            [10711337.707987847, 1900825.4382157368],
            [10711293.51783087, 1900826.0353800203],
    ];

//添加标记点
function addPonitToGeometry(arr) {
    for (var i = 0; i < arr.length; i++) {
        geometry.appendCoordinate(arr[i]);
    }
}
addPonitToGeometry(coordinate);

var LineStringFeature = new ol.Feature(geometry); //绘制线的数据

上边的代码是为了方便后边对这几个点坐标进行操作,你也可以简便的写成如下样式:

var LineStringFeature = new ol.Feature(
    new ol.geom.LineString([ //Polygon 多边形,Point 点,LineString 线
        [10711293.51783087, 1900921.581665377],

        [10711332.930673579, 1900920.9845010934],

        [10711337.707987847, 1900825.4382157368],

        [10711293.51783087, 1900826.0353800203],

        [10711293.51783087, 1900921.581665377],
    ])); //绘制多边形的数据
3. 将线添加到绘图层,然后添加到map上
//将线添加到Vector绘制层上
source.addFeature(LineStringFeature);
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.Circle({
            radius: 2,
            fill: new ol.style.Fill({
                color: '#f00'
            })
        })
    })
});
map.addLayer(vectorLayer); //将绘制层添加到地图容器中
  • 第四步:让轨迹动起来

有一个方法setCoordinates() // 设置线串的坐标,就是围绕这个方法来实现(假装)运动的效果。

// 最后一个标记点的坐标
var lngX = coordinate[3][0];
var lngY = coordinate[3][1];

var interval = setInterval(function(){
    lngX = lngX - Math.random() * 30;  
    lngY = lngY + Math.random() * 30;
    var newPoint = [lngX, lngY];
    coordinate.shift();
    coordinate.push(newPoint);
    geometry.setCoordinates(coordinate);
    }, 300);

setTimeout(function(){
    clearInterval(interval);
    }, 5000);

到此,基本的内容都已经完成了。
不过还是要注意一些内容,比如引入css/js等,比如缩放比例的控制,中心点的位置,#map .ol-zoom-in, #map .ol-zoom-out {display: none;}/* 隐藏缩放按钮 */
自己写的完整的demo放在最后,可以复制粘贴 直接运行 查看效果。

<!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" />
    <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%;
    }
    #map{
        width:100%;
        height:100%;
    }
    /* 隐藏缩放按钮 */
    #map .ol-zoom-in, #map .ol-zoom-out {display: none;}
    </style>

</head>
<body>
    <div id="map" class="map"></div>
    <script>

        // 初始给的中心点坐标。
        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, //限制中心的程度,换句话说,中心不能超出这个范围, 前后值一样(minx=maxx, miny=maxy)的话就无法移动。
                //然后设置minZoom 和 maxZoom 一样大,就无法缩放。
            }),
            logo: false, // 禁用地图标志
        });

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

        //实例一个线(标记点)的全局变量
        var geometry = new ol.geom.LineString(); //线,Point 点,Polygon 线

        //散列点数组,放置的点的位置数据
        var coordinate = [
            [10711293.51783087, 1900921.581665377],
            [10711332.930673579, 1900920.9845010934],
            [10711337.707987847, 1900825.4382157368],
            [10711293.51783087, 1900826.0353800203],
        ];

        //添加标记点
        function addPonitToGeometry(arr) {
            for (var i = 0; i < arr.length; i++) {
                geometry.appendCoordinate(arr[i]);
            }
        }
        addPonitToGeometry(coordinate);
        
        var LineStringFeature = new ol.Feature(geometry); //绘制线的数据

        //将线添加到Vector绘制层上
        source.addFeature(LineStringFeature);
        var vectorLayer = new ol.layer.Vector({
            source: source,
            style: new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.2)'
                }),
                stroke: new ol.style.Stroke({
                    color: '#f00',
                    width: 4
                }),
                image: new ol.style.Circle({
                    radius: 2,
                    fill: new ol.style.Fill({
                        color: '#f00'
                    })
                })
            })
        });
        map.addLayer(vectorLayer); //将绘制层添加到地图容器中

        // 最后一个标记点的坐标
        var lngX = coordinate[3][0];
        var lngY = coordinate[3][1];

        var interval = setInterval(function(){
            lngX = lngX - Math.random() * 30;  
            lngY = lngY + Math.random() * 30;
            var newPoint = [lngX, lngY];
            coordinate.shift();
            coordinate.push(newPoint);
            geometry.setCoordinates(coordinate);
            }, 300);

        setTimeout(function(){
            clearInterval(interval);
            }, 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);  
        } 

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

推荐阅读更多精彩内容