【百度地图可视化(MapVGL)】绘制炫酷飞线动画-强制边绑定算法的使用

绘制炫酷飞线动画 。在其中会使用强制边绑定算法 是重点。 百度地图可视化文档 MapV开发文档 (baidu.com)

炫酷飞线动画-强制边绑定算法
1. 初始化样式和引入需要的JS库
<style>
        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #map_container {
            width: 100%;
            height: 100%;
        }
    </style>

    <!-- 百度地图基础库 -->
    <script type="text/javascript"
            src="https://api.map.baidu.com/api?type=webgl&v=1.0&ak=******"></script>
    <!-- 公共的文件代码 里面包含 地图初始化 和 实用样式 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <!-- 使用根据城市名称获取城市的坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
    <!--使用mapcgl的时候需要引入-->
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.54/dist/mapvgl.min.js"></script>
2. 初始化地图容器
  1. 注意因为这里使用了 common.js进行初始化地图,所以这里的容器id为固定的map_container
<div id="map_container"></div>
3. 初始化地图
  1. 使用common.js文件中的 initMap函数对地图进行初始化。
function initMyMap() {

    // 根据城市名称获取到当前城市的中心点坐标
    let centerCity = mapv.utilCityCenter.getCenterByCityName('重庆')

    return initMap(
      {
        tilt: 0, // 地图的倾斜角
        heading: 0, // 地图旋转的角度
        center: [centerCity.lng, centerCity.lat], // 地图初始显示的中心点坐标
        style: purpleStyle, // 地图样式
        zoom: 5 // 地图初始缩放比例
      }
    )
  }
4. 准备数据
  1. 准备的数据是随机生成指定数量的一些数据,线的数据和点的数据是一致的。不同的是后面使用不同的方式进行渲染。

  2. 在准备的数据中还使用了强制边绑定算法进行实现一种各条线汇聚的效果。

/**
   * 准备数据信息
   * @returns {[]}
   */
  function initData() {

    let data = []
    // 城市数据信息
    let cities = ['北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '长春',
      '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州', '武汉', '长沙', '广州',
      '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都', '贵阳', '昆明', '拉萨', '海口', '台湾', '香港']

    // 确定一个需要汇聚所有线的目标城市
    let targetCity = mapv.utilCityCenter.getCenterByCityName('重庆')
    // 随机生成线和点的数量
    let randomCount = 1000
      /*  使用强制边绑定算法实现边的汇聚效果开始 */
    let nodeData = [
      {
        // 目标城市的经度
        x: targetCity.lng,
        // 目标城市的纬度
        y: targetCity.lat
      }
    ]
    // 边数据
    let edgeData = [
      {
        source: 1,
        target: 0
      }
    ]

    // 循环生成 随机个 点数据 和 边数据
    for (let i = 0; i < randomCount; i++) {
      // 获取每一条线的起始点坐标
      let start = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)])
      // 添加每一个点的数据
      nodeData.push(
        {
          // 这里让每个数据在渲染的时候是一种散列开的效果 是一个随机算法
          x: start.lng - 2 + Math.random() * 2,
          y: start.lat - 2 + Math.random() * 2
        }
      )

      // 边数据
      edgeData.push(
        {
          source: i + 1,
          target: 0
        }
      )
    }

    // 使用强制边绑定算法 进行强制边绑定调用该函数之后的结果是一个函数
    let bundling = mapv.utilForceEdgeBundling().nodes(nodeData).edges(edgeData)
    // 调用得到的 bundling是一个 函数 调用这个函数返回 绑定结果集
    let res = bundling()
    /* 强制边绑定算法结束 */

    // 对结果进行遍历

    for (let i = 0; i < res.length; i++) {
      // 线
      let line = res[i]
      // 坐标
      let 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
  }
5. 渲染数据
  1. 使用 mapvgl中的View创建图层管理器。
 let view = new mapvgl.View(
      {
        map
      }
    )
  1. 使用 mapvgl中的 LineLayer图层创建线图层。并将其添加到图层管理器中,和与准备的数据进行绑定。
// 创建线图层
    let lineLayer = new mapvgl.LineLayer(
      {
        color: 'rgba(255,0,0,.3)',
        width: 1,
        // 线出现重叠的时候进行高亮显示
        blend: 'lighter'
      }
    )

    // 将图层添加到图层管理器中
    view.addLayer(lineLayer)
    // 将数据与图层进行绑定
    lineLayer.setData(data)
  1. 使用 mapvgl中的LinePointLayer创建轨迹点图层,这个图层对象在官方文档中没有介绍但是可以通过官网的实现案例中找到实现方法进行实现。其他没有的图层对象也可以采用相似的方式进行查找使用。
// 创建轨迹点图层
    let linePointLayer = new mapvgl.LinePointLayer(
      {
        // 点的尺寸
        size: 5,
        // 点的运动速度
        speed: 30,
        color: 'rgba(255, 255, 255, 0.8)',
        // animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_UNIFORM_SPEED, // 这个动画是匀速的
        animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH, // 动画类型
        shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, // 形状
        blend: 'lighter'
      }
    )
    view.addLayer(linePointLayer)
    linePointLayer.setData(data)
6. 案例的完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>replay-dataV-mapVGl-Cool-Fly-Line</title>

    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #map_container {
            width: 100%;
            height: 100%;
        }
    </style>

    <!-- 百度地图基础库 -->
    <script type="text/javascript"
            src="https://api.map.baidu.com/api?type=webgl&v=1.0&ak=*******"></script>
    <!-- 公共的文件代码 里面包含 地图初始化 和 实用样式 -->
    <script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>
    <!-- 使用根据城市名称获取城市的坐标 -->
    <script src="https://mapv.baidu.com/build/mapv.js"></script>
    <!--使用mapcgl的时候需要引入-->
    <script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.54/dist/mapvgl.min.js"></script>
</head>
<body>
<div id="map_container"></div>
<!-- 复盘炫酷飞线动画 -->
<script>

  let map = initMyMap()
  let data = initData()
  setData(map, data)

  function initMyMap() {

    // 根据城市名称获取到当前城市的中心点坐标
    let centerCity = mapv.utilCityCenter.getCenterByCityName('重庆')

    return initMap(
      {
        tilt: 0, // 地图的倾斜角
        heading: 0, // 地图旋转的角度
        center: [centerCity.lng, centerCity.lat], // 地图初始显示的中心点坐标
        style: purpleStyle, // 地图样式
        zoom: 5 // 地图初始缩放比例
      }
    )
  }

  /**
   * 准备数据信息
   * @returns {[]}
   */
  function initData() {

    let data = []
    // 城市数据信息
    let cities = ['北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '长春',
      '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州', '武汉', '长沙', '广州',
      '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都', '贵阳', '昆明', '拉萨', '海口', '台湾', '香港']

    // 确定一个需要汇聚所有线的目标城市
    let targetCity = mapv.utilCityCenter.getCenterByCityName('重庆')
    // 随机生成线和点的数量
    let randomCount = 1000
      /*  使用强制边绑定算法实现边的汇聚效果开始 */
    let nodeData = [
      {
        // 目标城市的经度
        x: targetCity.lng,
        // 目标城市的纬度
        y: targetCity.lat
      }
    ]
    // 边数据
    let edgeData = [
      {
        source: 1,
        target: 0
      }
    ]

    // 循环生成 随机个 点数据 和 边数据
    for (let i = 0; i < randomCount; i++) {
      // 获取每一条线的起始点坐标
      let start = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length)])
      // 添加每一个点的数据
      nodeData.push(
        {
          // 这里让每个数据在渲染的时候是一种散列开的效果 是一个随机算法
          x: start.lng - 2 + Math.random() * 2,
          y: start.lat - 2 + Math.random() * 2
        }
      )

      // 边数据
      edgeData.push(
        {
          source: i + 1,
          target: 0
        }
      )
    }

    // 使用强制边绑定算法 进行强制边绑定调用该函数之后的结果是一个函数
    let bundling = mapv.utilForceEdgeBundling().nodes(nodeData).edges(edgeData)
    // 调用得到的 bundling是一个 函数 调用这个函数返回 绑定结果集
    let res = bundling()
    /* 强制边绑定算法结束 */

    // 对结果进行遍历

    for (let i = 0; i < res.length; i++) {
      // 线
      let line = res[i]
      // 坐标
      let 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(map, data) {
    let view = new mapvgl.View(
      {
        map
      }
    )
    // 创建线图层
    let lineLayer = new mapvgl.LineLayer(
      {
        color: 'rgba(255,0,0,.3)',
        width: 1,
        // 线出现重叠的时候进行高亮显示
        blend: 'lighter'
      }
    )
    // 将图层添加到图层管理器中
    view.addLayer(lineLayer)
    // 将数据与图层进行绑定
    lineLayer.setData(data)
    // 创建轨迹点图层
    let linePointLayer = new mapvgl.LinePointLayer(
      {
        // 点的尺寸
        size: 5,
        // 点的运动速度
        speed: 30,
        color: 'rgba(255, 255, 255, 0.8)',
        // animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_UNIFORM_SPEED, // 这个动画是匀速的
        animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH, // 动画类型
        shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE, // 形状
        blend: 'lighter'
      }
    )
    view.addLayer(linePointLayer)
    linePointLayer.setData(data)
  }

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

推荐阅读更多精彩内容