OpenLayer3动态点线和动态点的扩散实现

Posted hpugisers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenLayer3动态点线和动态点的扩散实现相关的知识,希望对你有一定的参考价值。

无论动态点的实现还是动态线的实现大多依靠canvas去是是实现的,其实我们一直在独立的canvas 的做,OL3中vectorContext子类主要为渲染矢量元素,如果下点共运用map的postcompose事件就可以做许多的动态效果,例如下面这一段ol3给出代码示例:

<!DOCTYPE html>
<html>
  <head>
    <title>动态数据</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v3.13.1/css/ol.css" type="text/css">
    <script src="https://openlayers.org/en/v3.13.1/build/ol.js"></script>
  </head>
  <body>
    <div id="map" class="map"></div>
    <script>
        var map = new ol.Map(
            layers: [
              new ol.layer.Tile(
                  source: new ol.source.MapQuest( layer: 'sat' )
              )
            ],
            target: 'map',
            view: new ol.View(
                center: [0, 0],
                zoom: 2
            )
        );

        var imageStyle = new ol.style.Circle(
            radius: 5,
            snapToPixel: false,
            fill: new ol.style.Fill( color: 'yellow' ),
            stroke: new ol.style.Stroke( color: 'red', width: 1 )
        );

        var headInnerImageStyle = new ol.style.Style(
            image: new ol.style.Circle(
                radius: 2,
                snapToPixel: false,
                fill: new ol.style.Fill( color: 'blue' )
            )
        );

        var headOuterImageStyle = new ol.style.Circle(
            radius: 5,
            snapToPixel: false,
            fill: new ol.style.Fill( color: 'black' )
        );

        var n = 200;
        var omegaTheta = 30000; // Rotation period in ms
        var R = 7e6;
        var r = 2e6;
        var p = 2e6;
        map.on('postcompose', function (event) 
            var vectorContext = event.vectorContext;
            var frameState = event.frameState;
            console.log(frameState.time);
            var theta = 2 * Math.PI * frameState.time / omegaTheta;
            var coordinates = [];
            var i;
            for (i = 0; i < n; ++i) 
                var t = theta + 2 * Math.PI * i / n;
                var x = (R + r) * Math.cos(t) + p * Math.cos((R + r) * t / r);
                var y = (R + r) * Math.sin(t) + p * Math.sin((R + r) * t / r);
                coordinates.push([x, y]);
            
            vectorContext.setImageStyle(imageStyle);
            vectorContext.drawMultiPointGeometry(
                new ol.geom.MultiPoint(coordinates), null);
            var headPoint = new ol.geom.Point(coordinates[coordinates.length - 1]);
            var headFeature = new ol.Feature(headPoint);
            vectorContext.drawFeature(headFeature, headInnerImageStyle);
            vectorContext.setImageStyle(headOuterImageStyle);
            vectorContext.drawMultiPointGeometry(headPoint, null);
            map.render();
        );
        map.render();
    </script>
  </body>
</html>

这主要实现动态数据的展示,有点3D效果。

一、动态点扩散

这是国内一大神做的插件,插件地址,牛老师稍加在此基础啊上改动适合OL3进行动态点的扩散,这个效果用上述方法稍加修改一样可以实现,有时候我们虽然不会做这些插件但是我们在大神的基础上改动代码实现我们想要的,

放张图

demo示例:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>动态点扩散</title>
    <link href="../script/ol.css" rel="stylesheet" />
    <script src="../script/ol.js"></script>
    <script src="../script/jquery-1.7.1.js"></script>
    <script src="../script/flash-marker.js"></script>
</head>
<body>
    <div id="map"></div>
    <script>
        var vec_c = getTdtLayer("vec_w");
        var cva_c = getTdtLayer("cva_w");
        var view = new ol.View(
            center: [116.46, 39.92],
            zoom: 2,
            projection: "EPSG:4326"
        );
        map = new ol.Map(
            controls: ol.control.defaults(
                attribution: false
            ),
            target: 'map',
            layers: [vec_c, cva_c],
            view: view
        );

        function getTdtLayer(lyr) 
            var url = "http://t0-7.tianditu.com/DataServer?T=" + lyr + "&X=x&Y=y&L=z";
            var layer = new ol.layer.Tile(
                source: new ol.source.XYZ(
                    url: url
                )
            );
            return layer;
        
        //数据
        var citys = [
            name: '北京',
            lnglat: ['116.3', '39.9'],
            color: '#5070FF',
            type: 'circle',
            speed: 0.5,
        , 
            name: '上海',
            lnglat: ['121.29', '31.11'],
            color: '#6EE7FF',
            type: 'ellipse',
            speed: 1,
            max: 40,
        , 
            name: '福建',
            lnglat: ['117.984943', '26.050118'],
            color: '#90EE90',
            type: 'circle',
            speed: 0.45,
        , 
            name: '广东',
            lnglat: ['113.394818', '23.408004'],
            color: '#f8983a',
            type: 'circle',
            speed: 0.9,
        , 
            name: '广西',
            lnglat: ['108.924274', '23.552255'],
            color: '#FAFA32',
            type: 'ellipse',
            speed: 0.8,
            max: 50,
        ];


        var mark = new FlashMarker(map, citys);

    </script>

</body>
</html>

二、动态线

实现一、

该插件也是上述的大神做的,具体的插件你们可以去http://blog.csdn.net/gisshixisheng/article/ 查找先放张图:

demo示例:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>动态轨迹线</title>
        <link href="../script/ol.css" rel="stylesheet" />
    <script src="../script/ol.js"></script>
    <script src="../script/jquery-1.7.1.js"></script>
    <script src="../script/move-line.js"></script>
</head>
<body>
    <div id="map"></div>
    <script>
        var vec_c = getTdtLayer("vec_w");
        var cva_c = getTdtLayer("cva_w");
        var view = new ol.View(
            center: [116.46, 39.92],
            zoom: 2,
            projection: "EPSG:4326"
        );
        map = new ol.Map(
            controls: ol.control.defaults(
                attribution: false
            ),
            target: 'map',
            layers: [vec_c, cva_c],
            view: view
        );

        function getTdtLayer(lyr) 
            var url = "http://t0-7.tianditu.com/DataServer?T=" + lyr + "&X=x&Y=y&L=z";
            var layer = new ol.layer.Tile(
                source: new ol.source.XYZ(
                    url: url
                )
            );
            return layer;
        
        var data = [
            from: 
                city: '广州',
                lnglat: [113.270793, 23.135308]
            ,
            to: 
                city: '衡山',
                lnglat: [112.612787, 27.317599]
            
        , 
            from: 
                city: '广州',
                lnglat: [113.270793, 23.135308]
            ,
            to: 
                city: '北京',
                lnglat: [116.413554, 39.911013]
            
        , 
            from: 
                city: '广州',
                lnglat: [113.270793, 23.135308]
            ,
            to: 
                city: '三亚',
                lnglat: [109.518646, 18.258217]
            
        , 
            from: 
                city: '广州',
                lnglat: [113.270793, 23.135308]
            ,
            to: 
                city: '上海',
                lnglat: [121.480237, 31.236305]
            
        , 
            from: 
                city: '广州',
                lnglat: [113.270793, 23.135308]
            ,
            to: 
                city: '韶关',
                lnglat: [113.603757, 24.816174]
            
        ];
     var mark=new MoveLine(map, 
            //marker点半径
            markerRadius: 2,
            //marker点颜色,为空或null则默认取线条颜色
            markerColor: null,
            //线条类型 solid、dashed、dotted
            lineType: 'solid',
            //线条宽度
            lineWidth: 2,
            //线条颜色
            colors: ['#F9815C', '#F8AB60', '#EDCC72', '#E2F194', '#94E08A', '#4ECDA5'],
            //移动点半径
            moveRadius: 3,
            //移动点颜色
            fillColor: '#ff0000',
            //移动点阴影颜色
            shadowColor: '#fff',
            //移动点阴影大小
            shadowBlur: 6,
            data: data
        );
    </script>
</body>
</html>

实现二、该插件和上面的插件差不多,效果比上面的好多了,但是有个缺点就是没法标注文字,还有就是线和点有偏移,地图放大放大后观看效果比较差。

放张图:

demo示例

<!DOCTYPE html>
<html>

<head>
    <title></title>
    <link href="ol.css" />
    <script src="ol-debug.js"></script>
    <script src="flyLine.js"></script>
    <style>
        html,
        body,
        #map
        
            width: 100%;
            height: 100%;
        

        *
        
            padding: 0px;
            margin: 0px;
        

        .new-canvas
        
            position: absolute;
            top: 0px;
            left: 0px;
        
    </style>
</head>

<body>

    <div id="map"></div>
    <script>



        var projection = ol.proj.get("EPSG:3857");
        var resolutions = [];
        for (var i = 0; i < 19; i++) 
            resolutions[i] = Math.pow(2, 18 - i);
        
        var tilegrid = new ol.tilegrid.TileGrid(
            origin: [0, 0],
            resolutions: resolutions
        );

        var baidu_black_source = new ol.source.TileImage(
            title: "百度街道暗黑地图",
            projection: projection,
            tileGrid: tilegrid,
            tileUrlFunction: function (tileCoord, pixelRatio, proj) 
                if (!tileCoord) 
                    return "";
                
                var z = tileCoord[0];
                var x = tileCoord[1];
                var y = tileCoord[2];

                if (x < 0) 
                    x = "M" + (-x);
                
                if (y < 0) 
                    y = "M" + (-y);
                

                return "http://api2.map.bdimg.com/customimage/tile?&x=" + x + "&y=" + y + "&z=" + z + "&udt=20180102&scale=1&ak=ZUONbpqGBsYGXNIYHicvbAbM&styles=t%3Aland%7Ce%3Ag%7Cc%3A%23081734%2Ct%3Abuilding%7Ce%3Ag%7Cc%3A%2304406F%2Ct%3Abuilding%7Ce%3Al%7Cv%3Aoff%2Ct%3Ahighway%7Ce%3Ag%7Cc%3A%23015B99%2Ct%3Ahighway%7Ce%3Al%7Cv%3Aoff%2Ct%3Aarterial%7Ce%3Ag%7Cc%3A%23003051%2Ct%3Aarterial%7Ce%3Al%7Cv%3Aoff%2Ct%3Agreen%7Ce%3Ag%7Cv%3Aoff%2Ct%3Awater%7Ce%3Ag%7Cc%3A%23044161%2Ct%3Asubway%7Ce%3Ag.s%7Cc%3A%23003051%2Ct%3Asubway%7Ce%3Al%7Cv%3Aoff%2Ct%3Arailway%7Ce%3Ag%7Cv%3Atrue%2Ct%3Arailway%7Ce%3Al%7Cv%3Atrue%2Ct%3Aall%7Ce%3Al.t.s%7Cc%3A%23313131%2Ct%3Aall%7Ce%3Al.t.f%7Cc%3A%23FFFFFF%2Ct%3Amanmade%7Ce%3Ag%7Cv%3Aoff%2Ct%3Amanmade%7Ce%3Al%7Cv%3Aoff%2Ct%3Alocal%7Ce%3Ag%7Cv%3Aoff%2Ct%3Alocal%7Ce%3Al%7Cv%3Aoff%2Ct%3Asubway%7Ce%3Ag%7Cl%3A-65%2Ct%3Arailway%7Ce%3Aall%7Cl%3A-40%2Ct%3Aboundary%7Ce%3Ag%7Cc%3A%238b8787%7Cl%3A-29%7Cw%3A1%2Ct%3Apoi%7Ce%3Al%7Cv%3Aoff%7Cc%3A%23022338";
            
        );

        var layer = new ol.layer.Tile(
            source: baidu_black_source
        );
        var vector = new ol.layer.Vector(
            source: new ol.source.Vector(),
            style: new ol.style.Style(
                image: new ol.style.Circle(
                    radius: 5,
                    fill: new ol.style.Fill(
                        color: "#FD4403"
                    )
                ),
                stroke: new ol.style.Stroke(
                    color: "#FDDA2C",
                    width: 2
                )
            )
        );

        var view = new ol.View(
            center: new ol.proj.fromLonLat([120, 33]),
            zoom: 5
        );
        var map = new ol.Map(
            layers: [layer, vector],
            view: view,
            target: "map",
            logo: false
        );


        //为两个点求出一个中间点,来展示轨迹路线
        function centerPoint(line) 
            var start = line[0];
            var end = line[1];
            var dx = start[0] - end[0];
            var dy = start[1] - end[1];
            var centerPoint = [start[0] + dx / 2, start[1] + dy / 2];
            line.splice(1, 0, centerPoint);
            return line;
        

        var lines = [[[116.324, 39.354], [111.139, 37.566], [106.325, 38.354]],
        [[116.324, 39.354], [111.40431, 31.50038], [113.270793, 23.135308]],
        [[116.324, 39.354], [117.82033, 35.016], [121.480237, 31.236305]],
        [[116.324, 39.354], [114.82033, 39.016], [108.480237, 34.436305]],
        [[116.324, 39.354], [121.08902, 44.69662], [126.49429, 45.8392]], [[117.324, 39.354], [111.139, 37.566], [106.325, 38.354]],
        [[117.324, 39.354], [111.40431, 31.50038], [113.270793, 23.135308]],
        [[117.324, 39.354], [117.82033, 35.016], [121.480237, 31.236305]],
        [[117.324, 39.354], [114.82033, 39.016], [108.480237, 34.436305]],
        [[117.324, 39.354], [121.08902, 44.69662], [126.49429, 45.8392]]];

        var ani = new flyLine(lines, vector);

        map.on('pointermove', function (evt) 
            map.forEachFeatureAtPixel(evt.pixel, function (f) 
                console.log(f.get('name'));
            );
        )

    </script>
</body>

</html>

可以实现多个原点进行扩散。

三、总结

博主现在正在尝试用vectorContext类做一些效果出来,这个毕竟ol3框架本身的渲染矢量要素的,做一些简单的效果还是可以滴。每天进步一点点,美滋滋

以上是关于OpenLayer3动态点线和动态点的扩散实现的主要内容,如果未能解决你的问题,请参考以下文章

Android 两种方式实现类似水波扩散效果

在Python中如何用matplotlib实现已知圆弧上两点和半径 来画弧

openlayer3-加载第三方地图,百度,谷歌等

横向和纵向的动态角半径

自定义view-波纹扩散(圆扩散)

Web动态按钮设计——波纹扩散