vue3项目中使用mapv

vue3项目中使用mapv

mapv是百度地图官方提供的地图数据可视化开源项目,提供了很多效果酷炫的绘图api

mapv地址在这里,示例图在这里

先解释为什么要用mapv

  1. echarts画的地图,都是行政区划,就算是geo地图,也只能在行政区划地图上添加一些地理信息点,而不能直接使用百度地图(只是个例子,也可以是高德)作为底图来展示地理信息数据
  2. 要想在使用百度地图,就得使用BMapGL
  3. BMapGL只能绘制一些比较简单的点线面图,如果想要画出复杂炫酷的地图可视化数据,就得使用mapv GL
  4. Mapv GL一般会配合MapV使用(是一般情况下,有时候也会单独用)

说来说去,就是地图可视化离不开BMapGL,而BMapG又离不开Mapv GL

目前,百度地图官方只提供了React-BMapGL文档

换句话说,如果用前端开发框架的话,得用react。当然也可以用vue,但是非常麻烦,折腾了很久,找到了一套可行的方案

先上效果,其实实现的就是mapv官网上的一个散点图例子

总体来说,要经过这么几个步骤:

  1. 网页入口文件中引入bmapgl
  2. npm安装mapv和mapv gl
  3. 组件中引入并使用bmapgl以及mapv画图

一、网页入口文件中引入bmapgl

在vue项目的根目录的index.html文件中在线引入bmapgl

如下

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
  <!-- <script type="text/javascript"
    src="https://api.map.baidu.com/getscript?v=3.0&ak=ak&services=&t=20240108120956"></script>
  <link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/webgl/10/bmap.css"> -->


  <!-- <script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.4.3/files/dist/extension/bmap.min.js"></script> -->
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
  <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=1.0&type=webgl&ak=自己的ak" async="async"></script>

</body>

</html>

这里有三个坑:

  1. 从我注释的代码中可以看出来,我尝试了在不同的地方引入百度地图,但是我最终选择在dom的最后面引入,虽然我不确认这样是不是脱坑的解决方案,但是我还是建议这么写,因为dom的渲染是从上到下的,听说要等dom渲染完成再引入会不容易报错🥶

  2. 我在引入的过程中,添加了async="async",这是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持,这么做的目的是让程序等待webgl加载完成在执行别的,其实这么做的目的和上面那个一样,都是因为控制台一直报错BMapGL未定义,查了一下,说异步导入可以解决,但是不写这个也可以,建议还是加上

  3. 官网给的引入脚本地址是https://api.map.baidu.com/api?v=1.0&type=webgl&ak=自己的ak,如果这么导入,控制台老是报警,不影响页面展示,报警内容如下:

    A parser-blocking, cross site (i.e. different eTLD+1) script, https://api.map.baidu.com/getscript?type=webgl\&v=1.0\&ak=xxx\&services=\&t=20240129120837, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details.

    如果没有强迫症的话,就不用改地址,听说改地址后会导致某些样式不起作用,也没测试过

二、mapv及mapv gl安装

没啥好说的,vue中使用,第一选择当然是通过包管理工具安装

shell 复制代码
npm i mapvgl
npm i mapv

个人安装的两个版本如下

"mapv": "^2.0.62",

"mapvgl": "^1.0.0-beta.188",

其实还有其他方式,可以通过cdn或者脚本引入,我没尝试,效果也未知

三、组件中的写法

我直接上我的完整代码(不知道为啥,搜索了网上一堆的代码,没有一个给出完整的代码,都是片段)

html 复制代码
<template>
    <div class="container">
        <div id="map" class="map"></div>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import * as mapv from 'mapv'
import * as mapvgl from 'mapvgl'
import { whiteStyle } from '@/utils/mapvCommon'
const init = () => {
    var map = new BMapGL.Map("map", {
        style: { styleJson: whiteStyle }
    });
    var point = new BMapGL.Point(105.403119, 38.028658);
    map.centerAndZoom(point, 5);
    map.enableScrollWheelZoom(true);
    const data = ref([])
    const cities = [
        '北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨',
        '长春', '沈阳', '济南', '南京', '合肥', '杭州', '南昌', '福州', '郑州',
        '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐',
        '成都', '贵阳', '昆明', '拉萨', '海口'
    ]
    let randomCount = 300
    while (randomCount--) {
        var cityCenter = mapv.utilCityCenter.getCenterByCityName(cities[parseInt(Math.random() * cities.length, 10)]);
        data.value.push({
            geometry: {
                type: 'Point',
                coordinates: [cityCenter.lng - 2 + Math.random() * 4, cityCenter.lat - 2 + Math.random() * 4]
            },
            properties: {
                count: parseInt(4 * Math.random(), 10)
            }
        });
    }
    var view = new mapvgl.View({
        map: map
    });
    var pointLayer = new mapvgl.PointLayer({
        blend: 'lighter',
        size: 10,
        color: function (item) {
            if (item.properties.count === 1) {
                return 'rgb(191, 67, 66, 0.8)';
            }
            else if (item.properties.count === 2) {
                return 'rgb(211, 139, 93, 0.8)';
            }
            else if (item.properties.count === 3) {
                return 'rgb(44, 85, 48, 0.8)';
            }
            else {
                return 'rgb(115, 158, 130, 0.8)';
            }
        }
    });

    view.addLayer(pointLayer);
    pointLayer.setData(data.value);
}
onMounted(() => {
    init()
})
</script>

<style lang="scss" scoped>
.map {
    height: 100%;
    width: 100%;
}
</style>

组件中引入了一个whiteStyle,它也是mapgl官方给的地图样式,它的地址在这里,我的写法是在utils文件夹下自己新建一个mapvCommon.js文件,然后对外按需暴露

画图的代码也是mapgl官方给的示例,地址在这里

这里依然有坑,官网给的原生js写法,我把画图写在了生命周期钩子中,因为老是报错,图也出不来。估计依然是dom渲染的问题

总结一下:

目前mapv在vue框架中的使用案例还是比较少的,官网给的示例都是原生写法,写在项目中不是这里报错就是那里报错🙈,几乎可以把人整崩溃。不知道怎么回事,百度地图的开发团队似乎更加倾向于react或者原生,而对vue的支持明显不够,对国内开发者不太友好。不管是mapv还是echarts,似乎都存在各种各样的坑,尤其是设计地图的开发展示

另外,开源是一把双刃剑,有些开源的作者简直提供的就是一堆垃圾代码,如果不能维护好,建议先不要开源(个人意见)

真的是春节前的最后一篇技术博客了,希望来源永无bug。。

相关推荐
GIS程序媛—椰子18 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00124 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端27 分钟前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x30 分钟前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
木舟100931 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439141 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习