百度地图Api介绍

1.百度地图

https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/getkey

1.1注册账号

  • 在控制台查看ak秘钥
https://lbsyun.baidu.com/apiconsole/key#/home
  • api文档
https://lbsyun.baidu.com/jsdemo.htm#a5_2
https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html
  • 输入城市名称,拾取坐标
http://api.map.baidu.com/lbsapi/getpoint/index.html

1.2基础案列

1.2.1 基础地图

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <title>百度地图</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <script type="text/javascript">
      console.log(window.BMapGL, 'BMapGL');
      var map = new BMapGL.Map('container');
      // 创建地图实例
      var point = new BMapGL.Point(116.404, 39.915);
      // 创建点坐标
      map.centerAndZoom(point, 15);
      // 通过滚轮进行放大缩小
      map.enableScrollWheelZoom(true);
      // 初始化地图,设置中心点坐标和地图级别
    </script>
  </body>
</html>
  • 效果


    image11.png

1.2.2 异步加载基础地图

异步加载:就是在onload首屏加载完成后,创建一个script标签去加载地图js,提升首屏加载速度

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <!-- <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script> -->
    <title>异步加载百度地图</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <script>
      // 异步加载改造
      function init() {
        var map = new BMapGL.Map('container');
        // 创建地图实例
        var point = new BMapGL.Point(116.404, 39.915);
        // 创建点坐标
        map.centerAndZoom(point, 15);
        // 通过滚轮进行放大缩小
        map.enableScrollWheelZoom(true);
        // 初始化地图,设置中心点坐标和地图级别
      }
      // 页面加载完成后,首屏加载完成,进行加载地图
      window.onload = function () {
        // 在首屏加载完成后,创建一个script标签
        var script = document.createElement('script');
        script.src =
          'https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp&callback=init';
        document.body.appendChild(script);
      };
    </script>
  </body>
</html>

1.3 3D百度地图

1.3.1 3D建筑和3D地球

<body>
    <div id="container"></div>
    <script type="text/javascript">
      console.log(window.BMapGL, 'BMapGL');
      var map = new BMapGL.Map('container');
      // 创建地图实例
      var point = new BMapGL.Point(118.5, 27.5);
      // 创建点坐标
      map.centerAndZoom(point, 8);
      // 通过滚轮进行放大缩小
      map.enableScrollWheelZoom(true);
      // 初始化地图,设置中心点坐标和地图级别
      // map.setHeading(64.5);
      // map.setTilt(73);
      map.setHeading(60);
      map.setTilt(0);
      // 设置3D地图,常量BMAP_EARTH_MAP
      map.setMapType(BMAP_EARTH_MAP);
    </script>
  </body>
  • 效果


    image12.png

1.4 地图常用控件

  1. 比例尺/缩放控件
  // 3.0 创建地图实例时,通过opts方式设置地图允许的最大最小级别
      var map = new BMapGL.Map('container', {
        minZoom: 5,
        maxZoom: 20,
      });
 var scaleCtrl = new BMapGL.ScaleControl({
        anchor: BMAP_ANCHOR_TOP_LEFT, // 控制方向和位置
      }); // 添加比例尺控件
      map.addControl(scaleCtrl);
      var zoomCtrl = new BMapGL.ZoomControl({
        // 将缩放控件位置调整到左下方
        anchor: BMAP_ANCHOR_BOTTOM_LEFT,
        // 位置移动,第一个参数是x轴 第二个参数是y轴
        offset: new BMapGL.Size(100, 100),
      }); // 添加缩放控件
      map.addControl(zoomCtrl);
  1. 定位相关控件
 // 创建定位控件
        var locationControl = new BMapGL.LocationControl({
            // 控件的停靠位置(可选,默认左上角)
            anchor: BMAP_ANCHOR_TOP_RIGHT,
            // 控件基于停靠位置的偏移量(可选)
            offset: new BMapGL.Size(20, 20)
        });
        // 将控件添加到地图上
        map.addControl(locationControl);

        // 添加定位事件
        locationControl.addEventListener("locationSuccess", function(e){
            var address = '';
            address += e.addressComponent.province;
            address += e.addressComponent.city;
            address += e.addressComponent.district;
            address += e.addressComponent.street;
            address += e.addressComponent.streetNumber;
            alert("当前定位地址为:" + address);
        });
        locationControl.addEventListener("locationError",function(e){
            alert(e.message);
        });
  1. 城市列表控件
// 创建城市选择控件
        var cityControl = new BMapGL.CityListControl({
            // 控件的停靠位置(可选,默认左上角)
            anchor: BMAP_ANCHOR_TOP_LEFT,
            // 控件基于停靠位置的偏移量(可选)
            offset: new BMapGL.Size(10, 5)
        });
        // 将控件添加到地图上
        map.addControl(cityControl);
  1. 第三方版权
 var cr = new BMapGL.CopyrightControl({
            anchor: BMAP_ANCHOR_TOP_RIGHT,
            offset: new BMapGL.Size(20, 20)
        });   //设置版权控件位置
        map.addControl(cr); //添加版权控件
        var bs = map.getBounds();   //返回地图可视区域
        cr.addCopyright({
            id: 1, 
            content: "<img src='../img/baidu.jpg' width='50px' height='50px'/><a href='#' style='font-size:16px;color:#000'>@我是自定义版权控件呀</a>", 
            bounds: bs
        });
  1. 自定义控件
//定义一个控件类
        function ZoomControl() {
            this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
            this.defaultOffset = new BMapGL.Size(20, 20)
        }
        //通过JavaScript的prototype属性继承于BMap.Control
        ZoomControl.prototype = new BMapGL.Control();

        //自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回
        //在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
        ZoomControl.prototype.initialize = function(map) {
             //创建一个dom元素
            var div = document.createElement('div');
             //添加文字说明
            div.appendChild(document.createTextNode('放大2级'));
              // 设置样式
            div.style.cursor = "pointer";
            div.style.padding = "7px 10px";
            div.style.boxShadow = "0 2px 6px 0 rgba(27, 142, 236, 0.5)";
            div.style.borderRadius = "5px";
            div.style.backgroundColor = "white";
            // 绑定事件,点击一次放大两级
            div.onclick = function(e){
                map.setZoom(map.getZoom() + 2);
            }
            // 添加DOM元素到地图中
            map.getContainer().appendChild(div);
            // 将DOM元素返回
            return div;
        }
        //创建控件元素
        var myZoomCtrl = new ZoomControl();
        //添加到地图中
        map.addControl(myZoomCtrl);
  1. 地图事件
map.addEventListener('zoomstart', function (e) {
        console.log(map.getZoom());
      });
      map.addEventListener('zoomend', function (e) {
        console.log(map.getZoom());
      });

2.百度自定义样式

https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/custom
  • 获取样式发布好的样式id值
 // 更改地图样式
      map.setMapStyleV2({
        styleId: 'cf77fd96dc03349e0bf6a8e7cf52809e',
      });
  • 效果


    image13.png

3.百度地图绘图进阶

  1. 绘制图标
 var myIcon = new BMapGL.Icon(
        'https://www.youbaobao.xyz/datav-res/datav/location.png',
        new BMapGL.Size(60, 60),
        {
          anchor: new BMapGL.Size(0, 0), // 改位移
        }
      );
      // 定义地图标注
      var marker = new BMapGL.Marker(point, { icon: myIcon });

      marker.addEventListener('click', () => {
        getInfoWindow();
      });
      map.addOverlay(marker);
  1. 绘制线段
 // 绘制线条 Polyline(points: Array< Point >, opts: PolylineOptions )
      var polyline = new BMapGL.Polyline(
        [new BMapGL.Point(118.121156, 24.474621), new BMapGL.Point(118.89, 25)],
        {
          strokeColor: 'red', // 线的颜色
          strokeWeight: 5, // 线条宽度
          strokeOpacity: 0.5, // 透明度
        }
      );
      map.addOverlay(polyline);

3,绘制图形

// 绘制三角形  Polygon(points: Array< Point >, opts: PolygonOptions )
      var polygon = new BMapGL.Polygon(
        [
          new BMapGL.Point(118.121156, 24.474621),
          new BMapGL.Point(119.34, 24.57),
          new BMapGL.Point(119.45, 24.67),
        ],
        {
          strokeColor: 'red', // 线的颜色
          strokeWeight: 2, // 线条宽度
          fillColor: 'blue', // 填充色
        }
      );
      map.addOverlay(polygon);
  1. 绘制文本
 // 绘制文本  Label(content: String, opts: LabelOptions )
      var label = new BMapGL.Label('你好,地图标注', {
        position: point,
        offset: new BMapGL.Size(60, 60),
      });
      label.setStyle({
        width: '100px',
        height: '30px',
        padding: '20px',
        color: '#333',
        strokeColor: 'red', // 线的颜色
        strokeWeight: 2, // 线条宽度
        fillColor: 'blue', // 填充色
      });
      // 文本事件
      label.addEventListener('click', () => {
        console.log('打印'); // 打印
      });
      map.addOverlay(label);
  1. 绘制弹窗
  // 绘制弹窗  InfoWindow(content: String, opts: LabelOptions )
      function getInfoWindow() {
        var content = '<div style="color:red;">123444</div>';
        content += '<div style="color:yellow;">你好,点击地图标注弹窗</div>';
        var infoWindow = new BMapGL.InfoWindow(content, {
          width: '100px',
          height: '30px',
          title: '提示',
        });
        map.openInfoWindow(infoWindow, point);
      }
  • 完整测试代码
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <title>百度地图</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #container {
        width: 90%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <script type="text/javascript">
      // 3.0 创建地图实例时,通过opts方式设置地图允许的最大最小级别
      var map = new BMapGL.Map('container');
      // 创建地图实例
      var point = new BMapGL.Point(118.121156, 24.474621);
      // 创建点坐标
      map.centerAndZoom(point, 15);
      // 通过滚轮进行放大缩小
      // map.enableScrollWheelZoom(true);
      // 定义icon对象  Icon(url: String, size: Size , opts: IconOptions )
      // 更改地图样式
      map.setMapStyleV2({
        styleId: '5ec6d67c6f18b41d123361713351745d',
      });
      var myIcon = new BMapGL.Icon(
        'https://www.youbaobao.xyz/datav-res/datav/location.png',
        new BMapGL.Size(60, 60),
        {
          anchor: new BMapGL.Size(0, 0), // 改位移
        }
      );
      // 定义地图标注
      var marker = new BMapGL.Marker(point, { icon: myIcon });

      marker.addEventListener('click', () => {
        getInfoWindow();
      });
      map.addOverlay(marker);

      // 绘制线条 Polyline(points: Array< Point >, opts: PolylineOptions )
      var polyline = new BMapGL.Polyline(
        [new BMapGL.Point(118.121156, 24.474621), new BMapGL.Point(118.89, 25)],
        {
          strokeColor: 'red', // 线的颜色
          strokeWeight: 5, // 线条宽度
          strokeOpacity: 0.5, // 透明度
        }
      );
      map.addOverlay(polyline);

      // 绘制三角形  Polygon(points: Array< Point >, opts: PolygonOptions )
      var polygon = new BMapGL.Polygon(
        [
          new BMapGL.Point(118.121156, 24.474621),
          new BMapGL.Point(119.34, 24.57),
          new BMapGL.Point(119.45, 24.67),
        ],
        {
          strokeColor: 'red', // 线的颜色
          strokeWeight: 2, // 线条宽度
          fillColor: 'blue', // 填充色
        }
      );
      map.addOverlay(polygon);

      // 绘制文本  Label(content: String, opts: LabelOptions )
      var label = new BMapGL.Label('你好,地图标注', {
        position: point,
        offset: new BMapGL.Size(60, 60),
      });
      label.setStyle({
        width: '100px',
        height: '30px',
        padding: '20px',
        color: '#333',
        strokeColor: 'red', // 线的颜色
        strokeWeight: 2, // 线条宽度
        fillColor: 'blue', // 填充色
      });
      // 文本事件
      label.addEventListener('click', () => {
        console.log('打印'); // 打印
      });
      map.addOverlay(label);

      // 绘制弹窗  InfoWindow(content: String, opts: LabelOptions )
      function getInfoWindow() {
        var content = '<div style="color:red;">123444</div>';
        content += '<div style="color:yellow;">你好,点击地图标注弹窗</div>';
        var infoWindow = new BMapGL.InfoWindow(content, {
          width: '100px',
          height: '30px',
          title: '提示',
        });
        map.openInfoWindow(infoWindow, point);
      }
    </script>
  </body>
</html>
  • 效果


    image14.png

4.百度地图动画

4.1 ViewAnimation动画

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <title>百度地图</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #container {
        width: 100%;
        height: 100%;
      }
      .tools {
        top: 10px;
        left: 10px;
        position: absolute;
        z-index: 99;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <div class="tools">
      <button id="start">开始</button>
      <button id="cancel">取消</button>
    </div>
    <script type="text/javascript">
      var map = new BMapGL.Map('container');
      // 创建地图实例
      var point = new BMapGL.Point(116.404, 39.915);
      // 创建点坐标
      map.centerAndZoom(point, 14);
      // 通过滚轮进行放大缩小
      map.enableScrollWheelZoom(true);
      // 动画 ViewAnimation  ViewAnimation(keyFrames: Array<ViewAnimationKeyFrames>, opts: ViewAnimationOptions)
      var keyFrames = [
        {
          center: new BMapGL.Point(116.404, 39.915),
          zoom: 15,
          tilt: 50,
          heading: 0,
          percentage: 0,
        },
        {
          center: new BMapGL.Point(116.404, 39.915),
          zoom: 15,
          tilt: 50,
          heading: 100,
          percentage: 0.5,
        },
        {
          center: new BMapGL.Point(116.404, 39.915),
          zoom: 21,
          tilt: 50,
          heading: 200,
          percentage: 1,
        },
      ];
      var opts = {
        delay: 2000,
        duration: 7000,
        interation: 1,
      };
      var animation = new BMapGL.ViewAnimation(keyFrames, opts);
      // // 开启动画
      // map.startViewAnimation(animation);

      // 动画事件
      document.getElementById('start').addEventListener('click', function (e) {
        // 开启动画
        map.startViewAnimation(animation);
      });
      document.getElementById('cancel').addEventListener('click', function (e) {
        // 开启动画
        map.cancelViewAnimation(animation);
      });
      animation.addEventListener('animationstart', function (e) {
        console.log('start');
      });
      animation.addEventListener('animationiterations', function (e) {
        console.log('动画期间');
      });
      animation.addEventListener('animationend', function (e) {
        console.log('end');
      });
      animation.addEventListener('animationcancel', function (e) {
        console.log('cancel');
      });
    </script>
  </body>
</html>

  • 效果


    image1.png

4.2 TrackAnimation轨迹动画

// 引入百度地图库
 <script
      type="text/javascript"
      src="https://api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"
    ></script>
  • 完整demo
<!--
 * @Author: zhangmengqiong
 * @Date: 2021-05-12 14:18:00
 * @LastEditors: zhangmengqiong
 * @LastEditTime: 2021-05-13 11:05:48
-->
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"
    ></script>
    <title>百度地图轨迹动画</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #container {
        width: 100%;
        height: 100%;
      }
      .tools {
        top: 10px;
        left: 10px;
        position: absolute;
        z-index: 99;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <div class="tools">
      <button id="start">开始</button>
      <button id="cancel">取消</button>
    </div>
    <script type="text/javascript">
      var map = new BMapGL.Map('container');
      // 创建地图实例
      var point = new BMapGL.Point(116.404, 39.915);
      // 创建点坐标
      map.centerAndZoom(point, 18);
      // 通过滚轮进行放大缩小
      map.enableScrollWheelZoom(true);
      // 轨迹动画,在工具库中,第一个参数map对象 lines 数组
      var points = [
        new BMapGL.Point(116.418038, 39.91979),
        new BMapGL.Point(116.418267, 40.059246),
        new BMapGL.Point(116.307899, 40.057038),
      ];

      var lines = new BMapGL.Polyline(points);
      var opts = {
        delay: 1000,
        duration: 10000,
        tilt: 30, // 轨迹动画播放产生的倾角
        overallView: true, // 自动调整视角
      };
      // 动画事件
      document.getElementById('start').addEventListener('click', function (e) {
        // 开启动画
        trackAnimation.start();
      });
      document.getElementById('cancel').addEventListener('click', function (e) {
        // 开启动画
        trackAnimation.cancel();
      });
      var trackAnimation = new BMapGLLib.TrackAnimation(map, lines, opts);
    </script>
  </body>
</html>

  • 效果


    image2.png

5.百度地图可视化

百度地图可视化通过 mapv 和mapvgl解决

5.1散点图

  1. 初始化百度地图
  • 引入demo里面的js,方便使用
 <!-- 封装好的方法 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
  • 引入输入城市名称获取地理坐标js
 <!-- 根据城市名称获取坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
  • 初始化
    function initMapFun() {
    // 获取中心点厦门的地理坐标
        const cityCenter = mapv.utilCityCenter.getCenterByCityName('厦门');
        var map = initMap({
          center: [cityCenter.lng, cityCenter.lat],
          zoom: 6,
          tilt: 0, // 视角
          style: snowStyle, // 主题设置
        });
        return map;
      }
  1. 准备数据源
 // 准备数据源
      function initData() {
        var citys = [
          '厦门',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '郑州',
          '武汉',
          '长沙',
          '广州',
          '南宁',
          '西安',
          '银川',
          '兰州',
          '西宁',
          '乌鲁木齐',
          '成都',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        var data = [];
        var randomCount = 200; // 一起准备200个点,拿到城市的坐标进行偏移
        while (randomCount--) {
          // 获取坐标,随机获取坐标
          var cityCenter = mapv.utilCityCenter.getCenterByCityName(
            citys[parseInt(Math.random() * citys.length, 10)]
          );
          data.push({
            geometry: {
              // 地理信息
              type: 'Point',
              coordinates: [
                cityCenter.lng - 2 + Math.random() * 4, // 坐标随机
                cityCenter.lat - 2 + Math.random() * 4,
              ],
            },
            properties: {
              // 销售数据,将点和数据结合
              count: Math.random() * 40,
            },
          });
        }
        return data;
      }
  1. 绘制数据源
  • 1.创建MapVGL图层管理器
  • 2.初始化 Intensity 对象

控制点的大小和颜色

  • 3.创建点可视化图层创建,并添加到图层管理器中
  • 4.关联图层与数据,享受震撼的可视化效果
function setData(map, data) {
        // 1,第一步 创建MapVGL图层管理器
        var view = new mapvgl.View({ map });
        // 2.初始化 Intensity 对象 控制点的大小和颜色
        var intensity = new mapvgl.Intensity({
          min: 0,
          max: 100,
          minSize: 5,
          maxSize: 50,
          gradient: {
            // 颜色渐变色
            0: 'rgb(25, 66, 102, 0.8)',
            0.3: 'rgb(145, 102, 129, 0.8)',
            0.7: 'rgb(210, 131, 137, 0.8)',
            1: 'rgb(248, 177, 149, 0.8)',
          },
        });
        // 3. 创建点可视化图层创建,并添加到图层管理器中
        var pointLayer = new mapvgl.PointLayer({
          // color: 'rgba(50, 50, 200, 1)',
          blend: 'lighter',
          // size: 10,
          size: function (item) {
            // 根据数据随机大小
            // return item.properties.count;
            return intensity.getSize(item.properties.count);
          },
          color: function (item) {
            // 随机颜色
            return intensity.getColor(item.properties.count);
          },
        });
        // 4,加入
        view.addLayer(pointLayer);
        // 5. 关联图层与数据,享受震撼的可视化效果
        pointLayer.setData(data);
      }
  1. 完整代码
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <!-- 封装好的方法 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <!-- 根据城市名称获取坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.124/dist/mapvgl.min.js"></script>
    <title>百度地图散点图</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #map_container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="map_container"></div>
    <script type="text/javascript">
      const map = initMapFun();
      const data = initData();
      setData(map, data);
      // 初始化百度地图
      function initMapFun() {
        const cityCenter = mapv.utilCityCenter.getCenterByCityName('厦门');
        var map = initMap({
          center: [cityCenter.lng, cityCenter.lat],
          zoom: 6,
          tilt: 0,
          style: snowStyle,
        });
        return map;
      }

      // 准备数据源
      function initData() {
        var citys = [
          '厦门',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '郑州',
          '武汉',
          '长沙',
          '广州',
          '南宁',
          '西安',
          '银川',
          '兰州',
          '西宁',
          '乌鲁木齐',
          '成都',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        var data = [];
        var randomCount = 200; // 一起准备200个点,拿到城市的坐标进行偏移
        while (randomCount--) {
          // 获取坐标,随机获取坐标
          var cityCenter = mapv.utilCityCenter.getCenterByCityName(
            citys[parseInt(Math.random() * citys.length, 10)]
          );
          data.push({
            geometry: {
              // 地理信息
              type: 'Point',
              coordinates: [
                cityCenter.lng - 2 + Math.random() * 4, // 坐标随机
                cityCenter.lat - 2 + Math.random() * 4,
              ],
            },
            properties: {
              // 销售数据,将点和数据结合
              count: Math.random() * 40,
            },
          });
        }
        console.log(data, 'data---');
        // 只展示数据大于50的点
        data = data.filter(item => item.properties.count > 30);
        return data;
      }

      // 绘制数据源
      /*
      *1,生成mapvgl 视图view
      2,初始化mapvgl 的 Point 对象
      3,降Point对象 加入到view
      4,将data 与Point 对象进行绑定
      */
      function setData(map, data) {
        // 1,第一步 创建MapVGL图层管理器
        var view = new mapvgl.View({ map });
        // 2.初始化 Intensity 对象 控制点的大小和颜色
        var intensity = new mapvgl.Intensity({
          min: 0,
          max: 100,
          minSize: 5,
          maxSize: 50,
          gradient: {
            // 颜色渐变色
            0: 'rgb(25, 66, 102, 0.8)',
            0.3: 'rgb(145, 102, 129, 0.8)',
            0.7: 'rgb(210, 131, 137, 0.8)',
            1: 'rgb(248, 177, 149, 0.8)',
          },
        });
        // 3. 创建点可视化图层创建,并添加到图层管理器中
        var pointLayer = new mapvgl.PointLayer({
          // color: 'rgba(50, 50, 200, 1)',
          blend: 'lighter',
          // size: 10,
          size: function (item) {
            // 根据数据随机大小
            // return item.properties.count;
            return intensity.getSize(item.properties.count);
          },
          color: function (item) {
            // 随机颜色
            return intensity.getColor(item.properties.count);
          },
        });
        // 4,加入
        view.addLayer(pointLayer);
        // 5. 关联图层与数据,享受震撼的可视化效果
        pointLayer.setData(data);
      }
    </script>
  </body>
</html>
  1. 效果


    image3.png

5.2飞线动画(FlyLineLayer)

  1. 引入飞线动画库
 <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.119/dist/mapvgl.threelayers.min.js"></script>
  1. 完整代码
<!--
 * @Author: zhangmengqiong
 * @Date: 2021-05-12 14:18:00
 * @LastEditors: zhangmengqiong
 * @LastEditTime: 2021-05-13 14:32:14
-->
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <!-- 封装好的方法 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <!-- 根据城市名称获取坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.124/dist/mapvgl.min.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.119/dist/mapvgl.threelayers.min.js"></script>
    <title>百度地图飞线动画</title>
    <style type="text/css">
      html {
        width: 100%;
        height: 100%;
      }
      body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      #map_container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="map_container"></div>
    <script type="text/javascript">
      const map = initMapFun();
      const data = initData();
      setData(map, data);
      // 初始化百度地图
      function initMapFun() {
        const cityCenter = mapv.utilCityCenter.getCenterByCityName('厦门');
        var map = initMap({
          center: [cityCenter.lng, cityCenter.lat],
          zoom: 8,
          tilt: 60,
          style: purpleStyle,
        });
        return map;
      }
      function initData() {
        var citys = [
          '厦门',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        // BezierCurve通过传入起点和终点,生成带高度的贝塞尔曲线坐标集,可以用来生成飞线数据
        var randomCount = 100; // 模拟的飞线的数量
        var data = [];
        // 生成贝塞尔曲线坐标集
        // 1,实例化贝塞尔曲线
        var curve = new mapvgl.BezierCurve();
        // 2,设置起点和重点
        // var start = mapv.utilCityCenter.getCenterByCityName('厦门');
        // var end = mapv.utilCityCenter.getCenterByCityName('北京');
        // curve.setOptions({
        //   start: [start.lng, start.lat],
        //   end: [end.lng, end.lat],
        // });
        // // 3,生成贝塞尔曲线坐标集
        // var curveModelData = curve.getPoints();

        // data.push({
        //   geometry: {
        //     type: 'LineString',
        //     coordinates: curveModelData,
        //   },
        //   properties: {
        //     count: Math.random(),
        //   },
        // });
        // 构造数据
        while (randomCount--) {
          var startPoint = mapv.utilCityCenter.getCenterByCityName(
            citys[parseInt(Math.random() * citys.length, 10)]
          );
          var endPoint = mapv.utilCityCenter.getCenterByCityName(
            citys[parseInt(Math.random() * citys.length, 10)]
          );

          curve.setOptions({
            start: [startPoint.lng, startPoint.lat],
            end: [endPoint.lng, endPoint.lat],
          });
          // 3,生成贝塞尔曲线坐标集
          var curveModelData = curve.getPoints();

          data.push({
            geometry: {
              type: 'LineString',
              coordinates: curveModelData,
            },
            properties: {
              count: Math.random(),
            },
          });
        }
        return data;
      }
      // 绘制数据源
      function setData(map, data) {
        // 初始化图层
        var view = new mapvgl.View({ map });
        // 2,初始化飞线对象
        var flylineLayer = new mapvgl.FlyLineLayer({
          style: 'chaos', // 随机移动
          step: 0.3, // 默认是0.1 越大动画速度越快
          color: 'rgba(33, 242, 214, 0.3)', // 底线颜色
          textureColor: function (data) {
            return data.properties.count > 0.5 ? '#ff0000' : '#56ccdd';
          },
          textureWidth: 20, // 线条宽度
          textureLength: 40, // 飞线占整条线的长度,默认是30%
        });
        // 将飞线添加到图层
        view.addLayer(flylineLayer);
        // 绑定数据源
        flylineLayer.setData(data);
      }
    </script>
  </body>
</html>

  1. 效果


    image4.png

5.3炫酷飞线动画

  • 官方demo
https://lbsyun.baidu.com/solutions/mapvdata

5.3.1简单分析动画

  1. 先绘制以某个城市为终点的,其他城市为起点的线
// 创建数据源
      function initData() {
        var randomCount = 500;
        var data = [];
        var cities = [
          '北京',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '郑州',
          '武汉',
          '长沙',
          '广州',
          '南宁',
          '西安',
          '银川',
          '兰州',
          '西宁',
          '乌鲁木齐',
          '成都',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        // 目标点
        var targetCity = mapv.utilCityCenter.getCenterByCityName('厦门');
        // 1,实例化贝塞尔曲线
        var curve = new mapvgl.BezierCurve();

        // // 3,生成贝塞尔曲线坐标集
        // 构造数据,将其他城市的点为终点
        for (var i = 1; i < cities.length; i++) {
          var startCity = mapv.utilCityCenter.getCenterByCityName(cities[i]);
          curve.setOptions({
            start: [startCity.lng, startCity.lat],
            end: [targetCity.lng, targetCity.lat],
          });
          // 拿到要绘制的集合
          var curveModelData = curve.getPoints();
          data.push({
            geometry: {
              type: 'LineString',
              coordinates: curveModelData,
            },
          });
        }
        return data;
      }
  1. 绘制点,并沿线做轨迹运动
 // 绘制数据源,先绘制线,然后绘制点,做一个沿线运动的点运动的轨迹动画
      function setData(map, data) {
        var view = new mapvgl.View({ map });
        // 初始化LineLayer实例
        var lineLayer = new mapvgl.LineLayer({
          color: 'rgba(55, 50, 250, 0.4)',
          blend: 'lighter',
        });
        // 加入到view
        view.addLayer(lineLayer);
        lineLayer.setData(data);
        // 点运行的动画与线的数据源是一致的
        var linePointLayer = new mapvgl.LinePointLayer({
          size: 20, // 点大小
          speed: 15, // 点速度
          color: 'rgba(255, 255, 0, 0.6)', // 点的颜色
          animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_UNIFORM_SPEED, // 点动画
          shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, // 点形状
          blend: 'lighter', // 点交互时处理方式
        });
        view.addLayer(linePointLayer);
        linePointLayer.setData(data);
      }
  1. 整体demo
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>百度基础炫酷飞线地图</title>
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <!-- 封装好的方法 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <!-- 根据城市名称获取坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.124/dist/mapvgl.min.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.119/dist/mapvgl.threelayers.min.js"></script>
    <style type="text/css">
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }

      #map_container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map_container"></div>
    <script type="text/javascript">
      var map = initBMap();
      var data = initData();
      setData(map, data);
      // 初始化百度地图
      function initBMap() {
        var targetCity = mapv.utilCityCenter.getCenterByCityName('厦门');
        var map = initMap({
          tilt: 0,
          center: [targetCity.lng, targetCity.lat],
          zoom: 5,
          style: darkStyle,
        });
        return map;
      }
      // 创建数据源
      function initData() {
        var randomCount = 500;
        var data = [];
        var cities = [
          '北京',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '郑州',
          '武汉',
          '长沙',
          '广州',
          '南宁',
          '西安',
          '银川',
          '兰州',
          '西宁',
          '乌鲁木齐',
          '成都',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        // 目标点
        var targetCity = mapv.utilCityCenter.getCenterByCityName('厦门');
        // 1,实例化贝塞尔曲线
        var curve = new mapvgl.BezierCurve();

        // // 3,生成贝塞尔曲线坐标集
        // 构造数据,将其他城市的点为终点
        for (var i = 1; i < cities.length; i++) {
          var startCity = mapv.utilCityCenter.getCenterByCityName(cities[i]);
          curve.setOptions({
            start: [startCity.lng, startCity.lat],
            end: [targetCity.lng, targetCity.lat],
          });
          // 拿到要绘制的集合
          var curveModelData = curve.getPoints();
          data.push({
            geometry: {
              type: 'LineString',
              coordinates: curveModelData,
            },
          });
        }
        return data;
      }
      // 绘制数据源,先绘制线,然后绘制点,做一个沿线运动的点运动的轨迹动画
      function setData(map, data) {
        var view = new mapvgl.View({ map });
        // 初始化LineLayer实例
        var lineLayer = new mapvgl.LineLayer({
          color: 'rgba(55, 50, 250, 0.4)',
          blend: 'lighter',
        });
        // 加入到view
        view.addLayer(lineLayer);
        lineLayer.setData(data);
        // 点运行的动画与线的数据源是一致的
        var linePointLayer = new mapvgl.LinePointLayer({
          size: 20, // 点大小
          speed: 15, // 点速度
          color: 'rgba(255, 255, 0, 0.6)', // 点的颜色
          animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_UNIFORM_SPEED, // 点动画
          shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, // 点形状
          blend: 'lighter', // 点交互时处理方式
        });
        view.addLayer(linePointLayer);
        linePointLayer.setData(data);
      }
    </script>
  </body>
</html>
  1. 效果


    image6.png

5.3.2炫酷随机动画

边绑定算法 由中心发散或者汇聚,且比较流畅

var fbundling = mapv.utilForceEdgeBundling().nodes(node_data).edges(edge_data);
  • 完整demo
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>百度炫酷飞线地图</title>
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <script
      type="text/javascript"
      src="https://mapv.baidu.com/build/mapv.js"
    ></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.54/dist/mapvgl.min.js"></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.53/dist/mapvgl.threelayers.min.js"></script>
    <style type="text/css">
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }

      #map_container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map_container"></div>
    <script type="text/javascript">
      var map = initBMap();
      var data = initData();
      setData(data);

      // 初始化百度地图
      function initBMap() {
        var targetCity = mapv.utilCityCenter.getCenterByCityName('厦门');
        var map = initMap({
          tilt: 0,
          center: [targetCity.lng, targetCity.lat],
          zoom: 5,
          style: darkStyle,
        });
        return map;
      }
      // 创建数据源
      function initData() {
        // 地图上多一些点,做成随机数
        var randomCount = 500;
        // 边绑定算法 由中心发散或者汇聚,且比较流畅
        // node_data:包含所有的点
        var targetCity = mapv.utilCityCenter.getCenterByCityName('厦门');
        var node_data = [
          {
            x: targetCity.lng,
            y: targetCity.lat,
          },
        ];
        // 边
        var edge_data = [
          {
            source: 1, // 起点
            target: 0, // 终点 node_data 中的0 号元素
          },
        ];
        var cities = [
          '北京',
          '天津',
          '上海',
          '重庆',
          '石家庄',
          '太原',
          '呼和浩特',
          '哈尔滨',
          '长春',
          '沈阳',
          '济南',
          '南京',
          '合肥',
          '杭州',
          '南昌',
          '福州',
          '郑州',
          '武汉',
          '长沙',
          '广州',
          '南宁',
          '西安',
          '银川',
          '兰州',
          '西宁',
          '乌鲁木齐',
          '成都',
          '贵阳',
          '昆明',
          '拉萨',
          '海口',
        ];
        // 构造数据
        for (var i = 0; i < randomCount; i++) {
          // 开始城市位置
          var cityCenter = mapv.utilCityCenter.getCenterByCityName(
            cities[parseInt(Math.random() * cities.length)]
          );
          // 使用边绑定算法
          node_data.push({
            x: cityCenter.lng - 5 + Math.random() * 10,
            y: cityCenter.lat - 5 + Math.random() * 10,
          });
          // 往边添加数据
          edge_data.push({
            source: parseInt(i * Math.random()),
            target: 0,
          });
        }
        // 边绑定数据
        var fbundling = mapv
          .utilForceEdgeBundling()
          .nodes(node_data)
          .edges(edge_data);
        // 获取所有点数据,且是一个二维数组
        var results = fbundling();
        var data = [];
        var timeData = [];
        for (var i = 0; i < results.length; i++) {
          // 每一条线的数据
          var line = results[i];
          //
          var coordinates = [];
          // 遍历line 获取对应的xy坐标
          for (var j = 0; j < line.length; j++) {
            coordinates.push([line[j].x, line[j].y]);
            // 将所有xy坐标放到timeData,即得到点的坐标集合
            timeData.push({
              geometry: {
                type: 'LineString',
                coordinates: [line[j].x, line[j].y],
              },
              count: 1,
              time: j,
            });
          }
          data.push({
            geometry: {
              type: 'LineString',
              coordinates: coordinates,
            },
          });
        }
        return {
          pointData: timeData,
          lineData: data,
        };
      }
      // 绘制数据源
      function setData({ pointData, lineData }) {
        console.log(pointData);
        var view = new mapvgl.View({ map });
        var lineLayer = new mapvgl.LineLayer({
          color: 'rgba(55, 50, 250, 0.3)',
          blend: 'lighter', // 交错混合,显示出光亮
        });
        view.addLayer(lineLayer);
        lineLayer.setData(lineData);

        var linePointLayer = new mapvgl.LinePointLayer({
          size: 8,
          speed: 20,
          color: 'rgba(255, 255, 0, 0.6)',
          animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH, // 点动画
          shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE,
          blend: 'lighter',
        });
        view.addLayer(linePointLayer);
        linePointLayer.setData(lineData);
      }
    </script>
  </body>
</html>

  • 效果


    image7.png

5.4 3D建筑(ShapeLayer)

  • 墨卡托投影
  • 坐标转换
https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
  • 根据经纬度转换成墨卡托坐标
http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=6&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp
  • 结果
{"status":0,"result":[{"x":12716247.50382771,"y":3428274.0907844568}]}
var shaperLayer = new mapvgl.ShapeLayer({
          color: 'rgb(0, 255, 255)',
          style: 'normal',
          // opacity: 1.0, // 透明度
          riseTime: 2000, // 楼房升起动画
          enablePicked: true,
          // riseTime: 1000,
          opacity: 0.3, // 透明度
          enablePicked: true, // 是否可以拾取
          selectedIndex: -1, // 选中项
          selectedColor: '#ee1111', // 选中项颜色
          autoSelect: true, // 根据鼠标位置来自动设置选中项
          onClick: e => {
            // 点击事件
            console.log(e);
          },
        });

        view.addLayer(shaperLayer);
        shaperLayer.setData(data);
  • 完整demo
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>3D建筑</title>
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=DVPI4kwxgMqXDrTx483rHkB7c3KDRyPp"
    ></script>
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <script
      type="text/javascript"
      src="https://mapv.baidu.com/build/mapv.js"
    ></script>
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.54/dist/mapvgl.min.js"></script>
    <style type="text/css">
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }

      #map_container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map_container"></div>
    <script type="text/javascript">
      var map = initMap({
        tilt: 80,
        heading: -45.3,
        center: [106.540547, 29.564858],
        zoom: 17,
      });
      initData().then(data => {
        setData(data);
      });
      function initData() {
        // 返回promise 对象
        return fetch(
          'https://www.youbaobao.xyz/datav-res/examples/chongqing.json'
        )
          .then(res => res.json())
          .then(res => {
            var data = res;
            // 存放所有多边形的面
            var polygons = [];
            var len = data.length;
            for (var i = 0; i < len; i++) {
              // 对应的高度
              var line = data[i];
              var polygon = [];
              var pt = [line[1] * 512, line[2] * 512];
              for (var j = 3; j < line.length; j += 2) {
                // 经度
                pt[0] += line[j] / 100 / 2;
                // 维度
                pt[1] += line[j + 1] / 100 / 2;
                polygon.push([pt[0], pt[1]]);
              }
              polygons.push({
                geometry: {
                  type: 'Polygon',
                  coordinates: [polygon],
                },
                properties: {
                  height: line[0] / 2,
                },
              });
            }
            return polygons;
          });
      }
      function setData(data) {
        var view = new mapvgl.View({ map });
        var shaperLayer = new mapvgl.ShapeLayer({
          color: 'rgba(194, 147, 75, 0.8)',
          style: 'normal',
          opacity: 1.0, // 透明度
          riseTime: 2000, // 楼房升起动画
          enablePicked: true,
          riseTime: 1000,
          opacity: 0.3, // 透明度
          enablePicked: true, // 是否可以拾取
          selectedIndex: -1, // 选中项
          selectedColor: '#ee1111', // 选中项颜色
          autoSelect: true, // 根据鼠标位置来自动设置选中项
          onClick: e => {
            // 点击事件
            console.log(e);
          },
        });
        view.addLayer(shaperLayer);
        shaperLayer.setData(data);
      }
    </script>
  </body>
</html>
  • 最终结果


    image8.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容