1、在Windows上下载瓦片,使用的工具为: 全能电子地图下载器3.0最新版(推荐)
下载后解压,然后进入目录"全能电子地图下载器3.0最新版(推荐)\全能电子地图下载器3.0\MapTileDownloader" 在这个目录下双击imaps.exe可打开如下界面
下载完成后会弹出个框,选择否即可
进入C:\MapDownload\baidumaps\图片类型\下可以查看到自己所下载的不同类型的瓦片(这里是卫星图的瓦片)
然后安装一个全局serve, 打开终端并输入npm install -g serve 安装完成后,进入到C:\MapDownload\baidumaps(如果修改瓦片保存路径了,则找到相应位置)然后执行serve并回车,如下所示表示成功
接下来创建vue3项目:npm create vue,回车并输入名字:vue3_baidu_map_offline,其他一律回车,然后进入项目,并安装所需要的包使使用命令 cnpm i 或者npm i,安装完成后下载百度地图离线工具:
链接: https://pan.baidu.com/s/1_TqfUtVAElsrxB1J3hW-EA 提取码: vw5e
下载并解压 将static目录及其子内容全部复制到src/assets目录下,结构如下:
修改App.vue的样式:将main.js中的import ‘./assets/main.css’ 注释掉或者删除了。然后查看你下载的瓦片图的后缀类型,比如这里的jpg
打开map_load.js做响应的路径及格式修改,比如对tiles_dir的修改,如果你的瓦片保存的为"C:\MapDownload\baidumaps\satellite\10\203" 就将这里边的satellite赋值给tiles_dir
map_load.js中的内容如下:
let bmapcfg = {
// 瓦片图的后缀-修改成你的
// imgext: '.png',
imgext: '.jpg',
// 瓦片图的地址,基地址路径(默认名字)
// tiles_dir: '/roadmap',
tiles_dir: '/satellite', // 修改成你的
// 瓦片图地址-尽量使用127或者localhost-方便断网测试
tiles_path: 'http://127.0.0.1:3000/',
// 卫星瓦片图的地址-可为空
tiles_hybrid: '',
//自定义图层的地址-可为空
tiles_self: ''
}
// 下面可以保持不动
var scripts = document.getElementsByTagName('script')
var JS__FILE__ = scripts[scripts.length - 1].getAttribute('src') //获得当前js文件路径
bmapcfg.home = JS__FILE__.substr(0, JS__FILE__.lastIndexOf('/') + 1) //地图API主目录
;(function () {
window.BMap_loadScriptTime = new Date().getTime()
//加载地图API主文件
document.write(
'<script type="text/javascript" src="' +
bmapcfg.home +
'bmap_offline_api_v3.0_min.js"></script>'
)
})()
在vue项目的index.html中引入static中的三个静态文件,index.html中的内容如下:
<!DOCTYPE html>
<html lang="">
<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标签 引入的路径要写对-->
<script
type="text/javascript"
src="/src/assets/static/map_load.js"
></script>
<script
type="text/javascript"
src="/src/assets/static/TextIconOverlay_min.js"
></script>
<script
type="text/javascript"
src="/src/assets/static//MarkerClusterer_min.js"
></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
App.vue中的内容如下,内包含如何离线使用百度地图api文档:
<template>
<div id="container"></div>
</template>
<script setup>
import {onMounted, ref} from "vue";
const map = ref()
const mk = ref()
let BMap = window.BMap
let initMap = () => {
// 创建地图必须要给container设置宽高
map.value = new BMap.Map('container')
// 创建点坐标
let Point = new BMap.Point(121.248292,25.081786)
// 在地图上添加Marker
map.value.addOverlay(new BMap.Marker(new BMap.Point(121.243473,25.079847)))
map.value.addOverlay(new BMap.Marker(new BMap.Point(121.243073,25.083847)))
// 设置地图中心点,并且中心点放大级别为16级
map.value.centerAndZoom(Point, 16)
// 设置地图最小能缩放到11级
map.value.setMinZoom(11)
// 最大16级,这个看你下载的瓦片级数,和瓦片上的数字对应
map.value.setMaxZoom(16)
//可以让鼠标滚轮放大缩小
map.value.enableScrollWheelZoom(true)
// 添加控制器
map.value.addControl(
new BMap.NavigationControl({
anchor: BMAP_ANCHOR_TOP_RIGHT,
type: BMAP_NAVIGATION_CONTROL_SMALL
})
)
// 此Marker可以拖拽
mk.value = new BMap.Marker(Point, { enableDragging: true })
map.value.addOverlay(mk.value)
// 拖拽点标注事件
mk.value.addEventListener('dragend', (e)=> {
console.log('执行点位拖拽', e)
getAddrByPoint(e.point)
})
// 地图标注点击事件
map.value.addEventListener('click', (e)=> {
console.log('点击事件', e)
// 清空点标注
map.value.clearOverlays()
// 点标注
map.value.addOverlay(new BMap.Marker(e.point, { enableDragging: true }))
let circle = new BMap.Circle(e.point,500,{strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5}); //创建圆
map.value.addOverlay(circle)
console.log('e.point', e.point);
console.log('e.point.lat', e.point.lat);
let random = (Math.random()-0.5)/100
map.value.addOverlay(new BMap.Marker(new BMap.Point(e.point.lng+random,e.point.lat+random),{ enableDragging: true }))
// that.map.addOverlay(new BMap.Marker(new BMap.Point(e.point.lat,e.point.lng+0.001),{ enableDragging: true }))
// 设置地图中心点
map.value.panTo(e.point)
getAddrByPoint(e.point)
})
// 从百度地图上复制的信息窗口内容(未改动的)
// var opts = {
// width : 200, // 信息窗口宽度
// height: 100, // 信息窗口高度
// title : "故宫博物院" , // 信息窗口标题
// message:"这里是故宫"
// }
// var infoWindow = new BMapGL.InfoWindow("地址:北京市东城区王府井大街88号乐天银泰百货八层", opts); // 创建信息窗口对象
// marker.addEventListener("click", function(){
// map.openInfoWindow(infoWindow, point); //开启信息窗口
// });
// 下边这个是改成符合离线状态且符合vue3格式的信息窗口,点击地图上Point这个点即可显示信息窗口
// let opts = {
// width : 200, // 信息窗口宽度
// height: 100, // 信息窗口高度
// title : "故宫博物院" , // 信息窗口标题
// message:"这里是故宫"
// }
// let infoWindow = new BMap.InfoWindow("地址:北京市东城区王府井大街88号乐天银泰百货八层", opts); // 创建信息窗口对象
// mk.value.addEventListener("click", function(){
// map.value.openInfoWindow(infoWindow, Point); //开启信息窗口
// });
/* 总结
通过对比可以发现主要修改的地方为new BMapGL.InfoWindow改成了new BMap.InfoWindow、
marker.addEventListener改成了mk.value.addEventListener、
map.openInfoWindow改成了map.value.openInfoWindow */
}
// 逆地址解析数据暂时做不了
const getAddrByPoint = (Point)=> {
let BMap = window.BMap
console.log('new BMap.Geocoder()', new BMap.Geocoder())
// 这个api是不执行的-因为逆地址解析是需要调用地图api的-只有在public/index.html正常引入百度地图时才会生效
let geoc = new BMap.Geocoder()
geoc.getLocation(Point, rs => {
console.log('点击地址-获取信息', rs)
})
console.log('执行解析完毕')
}
onMounted(()=>{
initMap()
})
</script>
<!--vue2写法-->
<!--<script>-->
<!--export default {-->
<!-- name: 'HelloWorld',-->
<!-- data () {-->
<!-- return {-->
<!-- // 地图实例-->
<!-- map: null,-->
<!-- // 点实例-->
<!-- mk: null-->
<!-- }-->
<!-- },-->
<!-- created () {-->
<!-- // 加载地图-->
<!-- this.$nextTick(() => {-->
<!-- this.initMap()-->
<!-- })-->
<!-- },-->
<!-- methods: {-->
<!-- // 获取地图-->
<!-- initMap () {-->
<!-- // 内网使用-地图对象-在public/index.html引入文件-->
<!-- let BMap = window.BMap-->
<!-- console.log('window.BMap', window.BMap)-->
<!-- // this指向-->
<!-- const that = this-->
<!-- // 创建Map实例-->
<!-- this.map = new BMap.Map('container')-->
<!-- // 地图中心点-经纬度决定我们加载哪里的地图-->
<!-- var Point = new BMap.Point(121.24451,25.082817)-->
<!-- that.map.addOverlay(new BMap.Marker(new BMap.Point(121.243473,25.079847)))-->
<!-- that.map.addOverlay(new BMap.Marker(new BMap.Point(121.243073,25.083847)))-->
<!-- // 初始化地图中心点和放大级别-->
<!-- this.map.centerAndZoom(Point, 17)-->
<!-- // 限制地图放大等级-为什么限制-->
<!-- // 1.因为内网时我们访问不到公网百度地图数据资源-->
<!-- // 2.同时这里地图放大等级也对应着我们下载的瓦片图资源-->
<!-- this.map.setMinZoom(11)-->
<!-- this.map.setMaxZoom(17)-->
<!-- //开启鼠标滚轮缩放-->
<!-- this.map.enableScrollWheelZoom(true)-->
<!-- // 4、添加(右上角)平移缩放控件-->
<!-- this.map.addControl(-->
<!-- new BMap.NavigationControl({-->
<!-- anchor: BMAP_ANCHOR_TOP_RIGHT,-->
<!-- type: BMAP_NAVIGATION_CONTROL_SMALL-->
<!-- })-->
<!-- )-->
<!-- // 添加中心标注点-->
<!-- this.mk = new BMap.Marker(Point, { enableDragging: true })-->
<!-- this.map.addOverlay(this.mk)-->
<!-- // 拖拽点标注事件-->
<!-- this.mk.addEventListener('dragend', function (e) {-->
<!-- console.log('执行点位拖拽', e)-->
<!-- that.getAddrByPoint(e.point)-->
<!-- })-->
<!-- // 地图标注点击事件-->
<!-- this.map.addEventListener('click', function (e) {-->
<!-- console.log('点击事件', e)-->
<!-- // 清空点标注-->
<!-- that.map.clearOverlays()-->
<!-- // 点标注-->
<!-- that.map.addOverlay(new BMap.Marker(e.point, { enableDragging: true }))-->
<!-- var circle = new BMap.Circle(e.point,500,{strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5}); //创建圆-->
<!-- that.map.addOverlay(circle)-->
<!-- console.log('e.point', e.point);-->
<!-- console.log('e.point.lat', e.point.lat);-->
<!-- let random = (Math.random()-0.5)/100-->
<!-- that.map.addOverlay(new BMap.Marker(new BMap.Point(e.point.lng+random,e.point.lat+random)))-->
<!-- // that.map.addOverlay(new BMap.Marker(new BMap.Point(e.point.lat,e.point.lng+0.001),{ enableDragging: true }))-->
<!-- // 设置地图中心点-->
<!-- that.map.panTo(e.point)-->
<!-- that.getAddrByPoint(e.point)-->
<!-- })-->
<!-- },-->
<!-- // 逆地址解析数据-->
<!-- getAddrByPoint (Point) {-->
<!-- // 百度地图的原装api-->
<!--// var map = new BMapGL.Map("container");-->
<!--// map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 11);-->
<!--// // 创建地理编码实例-->
<!--// var myGeo = new BMapGL.Geocoder();-->
<!--// // 根据坐标得到地址描述-->
<!--// myGeo.getLocation(new BMapGL.Point(116.364, 39.993), function(result){-->
<!--// if (result){-->
<!--// alert(result.address);-->
<!--// }-->
<!--// });-->
<!-- //百度地图改装后的api-->
<!-- // console.log("逆地址解析")-->
<!-- // this.map.centerAndZoom(Point, 11);-->
<!-- // // 创建地理编码实例-->
<!-- // let BMap = window.BMap-->
<!-- // console.log("BMap", BMap)-->
<!-- // var myGeo = new BMap.Geocoder();-->
<!-- // console.log(myGeo)-->
<!-- // // 根据坐标得到地址描述-->
<!-- // myGeo.getLocation(Point, function(result){-->
<!-- // console.log("result", result)-->
<!-- // if (result){-->
<!-- // alert(result.address);-->
<!-- // }-->
<!-- // });-->
<!-- // 本项目原先的api-->
<!-- // 从这里可以看出来:将百度地图原先api中的new BMapGL换成window.BMap,其他都不变,-->
<!-- console.log('执行解析', Point)-->
<!-- // 内网使用-地图对象-在public/index.html引入文件-->
<!-- let BMap = window.BMap-->
<!-- console.log('new BMap.Geocoder()', new BMap.Geocoder())-->
<!-- // 这个api是不执行的-因为逆地址解析是需要调用地图api的-只有在public/index.html正常引入百度地图时才会生效-->
<!-- var geoc = new BMap.Geocoder()-->
<!-- geoc.getLocation(Point, rs => {-->
<!-- console.log('点击地址-获取信息', rs)-->
<!-- })-->
<!-- console.log('执行解析完毕')-->
<!-- }-->
<!-- }-->
<!--}-->
<!--// 须知-->
<!--// 1.内网离线情况下我们访问不了百度数据资源,所有只有把数据资源下载在本地启动服务才可以解决这个问题-->
<!--// 2.确实可以满足基本的需求-->
<!--// 3.地图放大,缩小,控件,定位-->
<!--// 4.加载那里的地图我们首先要下载地图瓦片图,然后地图中心点定位在哪里就会加载的地图-->
<!--// 5.地图的放大等级我们要控制起来,因为是下载的瓦片图要对应-->
<!--// 6.瓦片图下载等级最好下载,11-15,刚好铺满全屏,再多就下载很慢-->
<!--// 7.开发时候我们用npm下载serve,把地图资源从本机运行起来(直接serve)-->
<!--// 8.所有地址最好写127.0.0.1和localhost方便测试(因为你后续直接断开网线测试时候,你就只能访问自己)-->
<!--// 瓦片图加载报错-404解决-->
<!--// 1.瓦片图,就是把一个地图区域根据放大等级分割成等额大小图片进行加载-->
<!--// 1.首先确定地图中心点经纬度和下载地图瓦片图是否是一致的-->
<!--// 2.瓦片图下载等级和代码地图限制放大等级是否一样(比如地图放大19级,但是下载地图没有19级图片也会报错)-->
<!--// 3.用serve启动好本地图片资源后-查看map_load.js文件(一般默认不用改)-->
<!--// 4..把404图片路径复制到本机浏览器看是否能访问-->
<!--// 优点-->
<!--// 1.引入项目比较轻便-确实在内网情况下可以使用(不能访问外网情况下-离线)-->
<!--// 缺点-->
<!--// 1.鼠标滚动的时候,会调用百度的api报错,但不影响使用-->
<!--// 2.百度api会失效,比如逆地址解析,没有建立百度资源连接带身份(就是没有在public/index-正常引入百度地图)-->
<!--// 3.如果单纯地图展示看,定位-可以,要使用api不满足-目前还没找到解决方案-->
<!--</script>-->
<style >
body,html{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#container {
width: 100vw;
height: 100vh;
}
</style>