Introducción al desarrollo de mapas de Baidu (5): ejemplo de animación de línea voladora

¡Acostúmbrate a escribir juntos! Este es el quinto día de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .

Explique otra aplicación común: animación de línea voladora, utilizada principalmente para mostrar el flujo de datos.

lbsyun.baidu.com/solutions/m…

1. Dibuja una sola línea de vuelo

La curva aquí se puede dibujar con la ayuda del generador de curvas de Baidu: lbsyun.baidu.com/solutions/m…

<body>

    <div id="map_container"></div>

    <script>

        const map = initBMap();

        const data = initData();

        setData(data, map);



        // 初始化百度地图

        function initBMap() {

            // 引入的common库所作的处理

            // mapv提供了api,根据名称获取坐标

            const cityCenter = mapv.utilCityCenter.getCenterByCityName('上海');

            const map = initMap({

                center: [cityCenter.lng, cityCenter.lat],

                zoom: 6,

                style: purpleStyle,

                tilt: 30

            })

            return map;



        }





        // 准备数据源

        function initData() {

            let data = [];

            // 生成贝塞尔曲线坐标集 - 关键要素

            // 1. 实例化贝塞尔曲线对象

            const curve = new mapvgl.BezierCurve();

            // 2. 设置起始和终点坐标

            const start = mapv.utilCityCenter.getCenterByCityName('上海');

            const end = mapv.utilCityCenter.getCenterByCityName('北京');

            curve.setOptions({

                start:[start.lng, start.lat],

                end:[end.lng, end.lat]

            });

            // 3. 生成贝塞尔曲线坐标集

            const curveData = curve.getPoints();

            data.push({

                geometry:{

                    type: 'LineString',

                    coordinates: curveData

                }

            })

            return data;

        }





        // 绘制数据源 

        function setData(data, map) {

           const view = new mapvgl.View({map});

           // 初始化飞线对象并添加到图层中

            const flyLine = new mapvgl.FlyLineLayer({

                // 更多配置项可以看文档

                color: 'red',

                textureColor: 'blue',

                textureWidth: 20,

                textureLength: 80,

                style: 'chaos',

                step: 0.5

            });

            view.addLayer(flyLine);

            flyLine.setData(data);



        }

    </script>

</body>
复制代码

// 绘制数据源 

        function setData(data, map) {

           const view = new mapvgl.View({map});

           // 初始化飞线对象并添加到图层中

            const flyLine = new mapvgl.FlyLineLayer({

                // 更多配置项可以看文档

                color: 'rgba(33,242,214,0.3)',

                textureColor: '#ff0000',

                textureWidth: 20,

                textureLength: 10,

                style: 'chaos',

                step: 0.3

            });

            view.addLayer(flyLine);

            flyLine.setData(data);



        }
复制代码

2. Añade más líneas

// 准备数据源

        function initData() {

            let data = [];

            const cities = [

                '北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨',

                '长春', '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州',

                '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐',

                '成都', '贵阳', '昆明', '拉萨', '海口'

            ];

            let randomCount = 100;

            // 生成贝塞尔曲线坐标集 - 关键要素

            // 1. 实例化贝塞尔曲线对象

            const curve = new mapvgl.BezierCurve();

            while (randomCount--) {

                // 2. 设置起始和终点坐标

                const start = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)]);

                const end = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)]);

                curve.setOptions({

                    start: [start.lng, start.lat],

                    end: [end.lng, end.lat]

                });

                // 3. 生成贝塞尔曲线坐标集

                const curveData = curve.getPoints();

                data.push({

                    geometry: {

                        type: 'LineString',

                        coordinates: curveData

                    }

                })

            }



            return data;

        }
复制代码

3. ejemplo de mapv transplant mapvgl - gráfico de líneas de convergencia de puntos

De hecho, mapv (el predecesor de mapvgl) tiene muchos casos buenos de diagramas de líneas voladoras como referencia, pero el oficial ya no se mantiene, pero aún podemos aprenderlo, por ejemplo aquí: mapv.baidu.com/examples/#b…

Después de hacer clic en el código fuente, puede ver el código fuente de su implementación, pero debe tenerse en cuenta que la ruta del script debe cambiarse a una ruta absoluta. El ejemplo predeterminado es una ruta relativa:

imagen.png

El caso anterior es la versión antigua de mapv, de hecho, no se recomienda aprender y el código no se explicará en detalle.

mapv se basa en la representación del lienzo, se congelará al mover el ángulo de visualización, mapvgl se implementa en función de webgl, no habrá problemas anteriores

Pero podemos trasplantarlo a mapvgl como un todo. De hecho, el contenido de esta imagen todavía es relativamente grande. En realidad, está compuesto de puntos en movimiento y líneas estáticas.

Implementar una capa de línea estática

Esto implica principalmente el trasplante de un algoritmo de convergencia. Primero implementamos una línea de convergencia multipunto en Beijing, y luego vemos si hay una capa que implemente una línea estática. Aquí se puede implementar en base a LineLayer: lbsyun.baidu.com /soluciones/m…

<body>

    <div id="map_container"></div>

    <script>

        const map = initBMap();

        const data = initData();

        setData(data, map);



        // 初始化百度地图

        function initBMap() {

            // 引入的common库所作的处理

            // mapv提供了api,根据名称获取坐标

            const cityCenter = mapv.utilCityCenter.getCenterByCityName('北京');

            const map = initMap({

                center: [cityCenter.lng, cityCenter.lat],

                zoom: 5,

                style: purpleStyle,

                tilt: 0

            })

            return map;



        }





        // 准备数据源

        function initData() {

            let data = [];

            const cities = [

                '北京', '天津', '上海'

            ];

            let randomCount = 100;

            const targetCity = mapv.utilCityCenter.getCenterByCityName('北京');

            const curve = new mapvgl.BezierCurve();

            for (let i = 1; i < cities.length; i++) {

                const startCity = mapv.utilCityCenter.getCenterByCityName(cities[i]);

                curve.setOptions({

                    start: [startCity.lng, startCity.lat],

                    end: [targetCity.lng, targetCity.lat]

                })

                const curveData = curve.getPoints();

                data.push({

                    geometry: {

                        type: 'LineString',

                        coordinates: curveData

                    }

                });



            }





            return data;

        }





        // 绘制数据源 

        function setData(data, map) {

            const view = new mapvgl.View({ map });

            // 初始化linelayer实现静态线

            const lineLayer = new mapvgl.LineLayer({

                color: 'rgba(55,50,250,0.3)'

            });

            view.addLayer(lineLayer);

            lineLayer.setData(data);



        }







    </script>

</body>
复制代码

Implementar capa de punto móvil

Cabe señalar aquí que la trayectoria de la capa de puntos en movimiento es en realidad la misma que la línea estática, es decir, los datos detrás de ella son los mismos. La capa no se encuentra en el sitio web oficial, sino en la demostración de demostración. encontramos un mapa de trayectoria, que contiene muchos puntos en movimiento: mapv .baidu.com/gl/examples…

Su parte trasera en realidad se basa en LinePointLayer, pero la documentación oficial no tiene esta información de capa, solo podemos referirnos al método de demostración para lograrlo:

// 绘制数据源 

        function setData(data, map) {

            const view = new mapvgl.View({ map });

            // 初始化linelayer实现静态线

            const lineLayer = new mapvgl.LineLayer({

                color: 'rgba(55,50,250,0.3)'

            });

            const linePointLayer = new mapvgl.LinePointLayer({

                size: 8, // 点大小

                speed: 12, // 点运动速度

                color: 'rgba(255, 255, 0, 0.6)',

                animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH, // 点动画类型

                shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, //点形状

                blend: 'lighter' // 交会时处理

            });

            view.addLayer(lineLayer);

            view.addLayer(linePointLayer)

            lineLayer.setData(data);

            linePointLayer.setData(data);



        }
复制代码

conseguir mas puntos

Aquí, algunos objetivos de agregación de puntos aleatorios todavía se generan en función de números aleatorios:

// 准备数据源

        function initData() {

            let data = [];

            const cities = [

                '北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨',

                '长春', '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州',

                '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐',

                '成都', '贵阳', '昆明', '拉萨', '海口'

            ];

            let randomCount = 500;

            const targetCity = mapv.utilCityCenter.getCenterByCityName('北京');

            const curve = new mapvgl.BezierCurve();

            for (let i = 0; i < randomCount; i++) {

                const startCity = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)]);

                curve.setOptions({

                    start: [startCity.lng - 5 + 10 * Math.random(), startCity.lat - 5 + 10 * Math.random()],

                    end: [targetCity.lng, targetCity.lat]

                })

                const curveData = curve.getPoints();

                data.push({

                    geometry: {

                        type: 'LineString',

                        coordinates: curveData

                    }

                });



            }





            return data;

        }
复制代码

Implementación del algoritmo de enlace de bordes

Este algoritmo puede ayudar a reducir el desorden del gráfico y servir como una función de agregación de bordes. Por ejemplo, una determinada línea de posición está muy cerca y puede ayudarlo a converger para alcanzar la meta blog.csdn.net/gdp12315_gu… :

No hemos implementado la vinculación de bordes en este momento, y el efecto no es tan bueno como el ejemplo anterior. Echemos un vistazo al método de herramienta de mapv para la vinculación de bordes.

        // 准备数据源

        function initData() {

            let data = [];

            const cities = [

                '北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨',

                '长春', '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州',

                '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐',

                '成都', '贵阳', '昆明', '拉萨', '海口'

            ];

            const targetCity = mapv.utilCityCenter.getCenterByCityName('北京');

            let nodeData = [{

                x: targetCity.lng,

                y: targetCity.lat

            }]; // 点

            let edgeData = [{

                source: 0, // 0表示的是nodeData的第0号元素

                target: 0 // 0 - 0号元素的线

            }]; // 边,表示点点关系

            // 我们需要生成一系列node和edge数据





            let randomCount = 500;

            const curve = new mapvgl.BezierCurve();

            for (let i = 0; i < randomCount; i++) {

                const startCity = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)]);

                nodeData.push({

                    x: startCity.lng + 5 - Math.random() * 10,

                    y: startCity.lat + 5 - Math.random() * 10

                });

                edgeData.push({

                    source: i + 1, // source为上面新push的node

                    target: 0

                })

            }

            // 基于百度边绑定API获取需要的数据

            const bundling = mapv.utilForceEdgeBundling().nodes(nodeData).edges(edgeData);

            const results = bundling(); // 获取所有线沿途的点数据 - 一个二维数组

            for (let i = 0; i < results.length; i++) {

                const line = results[i];

                const coordinates = [];

                for (let j = 0; j < line.length; j++) {

                    coordinates.push([line[j].x, line[j].y])



                }

                data.push({

                    geometry: {

                        type: 'LineString',

                        coordinates

                    }

                });



            }

            return data;

        }





        // 绘制数据源 

        function setData(data, map) {

            const view = new mapvgl.View({ map });

            // 初始化linelayer实现静态线

            const lineLayer = new mapvgl.LineLayer({

                color: 'rgba(55,50,250,0.5)'

            });

            const linePointLayer = new mapvgl.LinePointLayer({

                size: 5, // 点大小

                speed: 12, // 点运动速度

                color: 'rgba(255, 255, 0, 0.6)',

                animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH, // 点动画类型

                shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, //点形状

                blend: 'lighter' // 交会时处理

            });

            view.addLayer(lineLayer);

            view.addLayer(linePointLayer)

            lineLayer.setData(data);

            linePointLayer.setData(data);



        }
复制代码

más el efecto de convergencia

// 初始化linelayer实现静态线

            const lineLayer = new mapvgl.LineLayer({

                color: 'rgba(55,50,250,0.5)',

                blend: 'lighter' 

            });
复制代码

A menudo se utiliza la aplicación práctica del algoritmo de unión de bordes.

Supongo que te gusta

Origin juejin.im/post/7084820895709003807
Recomendado
Clasificación