美文网首页开源
使用OpenLayers3来展示一段运动轨迹

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

作者: 这位网友 | 来源:发表于2017-12-08 11:10 被阅读40次

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

    不懂的就百度,然后看一下官方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>
    

    相关文章

      网友评论

        本文标题:使用OpenLayers3来展示一段运动轨迹

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