vue3环境下mapbox本地部署极速入门

目录

1.前言

现在我们有这样的一个需求,将mapbox在本地部署,网上也有不少讲mapbox本地部署的教程,但是在我看来,很多都没有讲到点上,因为都是在讲字体库和图标库怎么在本地加载。试想一下,如果我要加载的底图不是矢量切片,就不用那些字体库和图标库了,那我为什么还要费那个劲去折腾呢?因此本文我们来梳理一下vue3环境下mapbox本地部署。非常灵活,加不加载字体库和图标库,都可自己设置,同样,也不需要token,更不需要去替换node_modulesmapbox的某个文件,因为根本就用不到mapbox的资源,实现真正的离线部署。

2.安装mapbox

javascript 复制代码
npm install mapbox-gl

3.vue3创建map组件

vue3环境搭建完毕之后,我们只需要新建一个map组件即可。并设置好div容器的样式

javascript 复制代码
<template>
    <div ref="mapContainer" class="map-container"></div>
</template>
<script setup>

</script>

<style scoped>
.map-container {
    flex: 1;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
}
</style>

4.完善map组件

我们现在要初始化map,但是我不想一初始化就去加载mapbox默认图层,因此在初始化map时,把layerssources全部置为空。

javascript 复制代码
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css';
let mapContainer = ref();
let map = new mapboxgl.Map({
    container: mapContainer.value,
    center: [106.741891, 34.054211],
    zoom: 3,
    style: {
        "version": 8,
        layers: [],
        sources: {},
    },
});

OK,现在map初始化好了。我们要加载我们自己的图层,或者天地图的图层,这里我们就以天地图图层为例。

javascript 复制代码
map.on('load', function () {
    map.addSource('tianDiTu', {
        type: 'raster',
        tiles: [
            'http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的token'
        ],
        tileSize: 256
    });

    // 添加天地图的 layer
    map.addLayer({
        id: 'tianDiTu-layer',
        type: 'raster',
        source: 'tianDiTu'
    });
});

看下效果

再看一下NetWork,全程没有任何请求mapbox的资源

恭喜,现在你已经实现了mapbox的本地部署了。关于图层你换成自己的就可以了。但如果你还是想使用mapbox提供的样式,那么你可以这么设置,接着往下看。

5.mapbox图标和字体本地化

这个其实非常简单,你只需要把mapbox的字体(glyphs)和图标(sprite)下载下来,放在项目中保证可以访问就可以了。如果找不到,可以去这里下载:mapbox资源下载

我将资源放到了项目的static文件夹下:

我们在浏览器里访问一下,看看能不能访问的到,确保访问OK。

我们在浏览器里访问一下,看看能不能访问的到,确保访问OK。现在重新初始化一下map

javascript 复制代码
let baseUrl = 'http://localhost:5173/src/static/mapbox1.13.3';
let map = new mapboxgl.Map({
    container: mapContainer.value,
    center: [106.741891, 34.054211],
    zoom: 3,
    style: {
        "version": 8,
        "sprite": baseUrl + "/sprites/sprite",
        "glyphs": baseUrl + "/fonts/{fontstack}/{range}.pbf",
        layers: [],
        sources: {},
    },
});

如果你这样配置了还去mapbox加载资源的话,你可以加一个transformRequest选项,处理一下访问路径,这种写法是我在官网找到的,目前还没看到有哪个讲离线部署的博文讲到这个函数,作者也算是首创了吧。

javascript 复制代码
let baseUrl = 'http://localhost:5173/src/static/mapbox1.13.3';
let map = new mapboxgl.Map({
    container: mapContainer.value,
    center: [106.741891, 34.054211],
    zoom: 3,
    style: {
        "version": 8,
        "sprite": baseUrl + "/sprites/sprite",
        "glyphs": baseUrl + "/fonts/{fontstack}/{range}.pbf",
        layers: [],
        sources: {},
    },
    transformRequest: (url, resourceType) => {
        if (resourceType === 'Glyphs') {
            url = url.split("?")[0].replace("https://api.mapbox.com/fonts/v1/mapbox", baseUrl + "/fonts")
        } else if (resourceType === 'SpriteJSON' || resourceType === 'SpriteImage') {
            url = url.split("?")[0].replace("https://api.mapbox.com/styles/v1/mapbox/streets-v12", baseUrl + "/sprites")
        }
        return { url: url };
    }
});

接下来就还是天地图图层的加载,或者矢量切片图层的加载,矢量切片可以使用GeoServer来切,比较简单,这里就不再赘述了。

6.完整代码

6.1 vue版本

javascript 复制代码
<template>
    <div ref="mapContainer" class="map-container"></div>
</template>
<script setup>
import mapboxgl from 'mapbox-gl'
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import 'mapbox-gl/dist/mapbox-gl.css';
let mapContainer = ref();

let baseUrl = 'http://localhost:5173/src/static/mapbox1.13.3';
onMounted(() => {
    let map = new mapboxgl.Map({
        container: mapContainer.value,
        center: [106.741891, 34.054211],
        zoom: 3,
        style: {
            "version": 8,
            // "sprite": baseUrl + "/sprites/sprite",
            // "glyphs": baseUrl + "/fonts/{fontstack}/{range}.pbf",
            layers: [],
            sources: {},
        },
    });
    map.on('load', function () {
        map.addSource('tianDiTu', {
            type: 'raster',
            tiles: [
                'http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的token'
            ],
            tileSize: 256
        });

        // 添加天地图的 layer
        map.addLayer({
            id: 'tianDiTu-layer',
            type: 'raster',
            source: 'tianDiTu'
        });
    });

});

</script>

<style scoped>
.map-container {
    flex: 1;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
}
</style>

6.2 原生js版本

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../static/mapbox1.13.3/mapbox-gl.js"></script>
    <link rel="stylesheet" href="../static/mapbox1.13.3/mapbox-gl.css" />
    <style>
        html,
        body {
            padding: 0;
            margin: 0;
            height: 100%;
            overflow: hidden;
        }

        #map {
            height: 100%;
            z-index: 0;
        }
    </style>
</head>

<body>
    <div id='map'></div>
    <script>
        let url = 'http://localhost:5173/src/static/mapbox1.13.3';
        let map = new mapboxgl.Map({
            container: 'map',
            center: [106.741891, 34.054211],
            zoom: 3,
            style: {
                "version": 8,
                "sprite": url+"/sprites/sprite",
                "glyphs": url+"/fonts/{fontstack}/{range}.pbf",
                "sources": {
                    "tdt-tiles": {
                        //矢量类型
                        'type': 'raster',
                        'tileSize': 256,
                        "tiles": [
                            //天地图
                            "http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的token",
                        ]
                    }
                },
                layers: [{
                    id: 'layer-tiles',
                    type: 'raster',
                    source: 'tdt-tiles'
                }]
            }
        });
    </script>
</body>

</html>

7.总结

本文详细的梳理了mapbox的本地化部署,并且讲解了mapbox中天地图图层的加载,以及矢量切片图层加载时的资源访问问题,通过transformRequest函数可以灵活的解决访问资源的问题。最后本文给出了mapbox离线环境搭建的vue版本和原生js版本,希望对读者有所帮助,回见~

相关推荐
Amd79410 天前
Nuxt.js 应用中的 build:done 事件钩子详解
部署·自定义·生命周期·nuxt·通知·构建·钩子
ccc_9wy11 天前
pikachu靶场SSRF-file_get_content测试报告
网络安全·内网·ssrf·web漏洞·中间人攻击·filegetcontents·file协议
Amarantine、沐风倩✨12 天前
实现uniapp天地图边界范围覆盖
前端·uni-app·移动端·天地图·全端
ikgade15 天前
Leaflet 接入天地图服务
javascript·html·leaflet·天地图
向上吧! 少年18 天前
docker-comapose安装部署mysql
mysql·docker·部署·docker-compose·安装
OceanBase数据库官方博客21 天前
OceanBase 4.x 部署实践:如何从单机扩展至分布式部署
部署·oceanbase·分布式数据库
Tensorrrrrr25 天前
MindSearch 部署到Github Codespace 和 Hugging Face Space
大模型·部署·提示工程·书生·书生·浦语
网络研究院25 天前
如何安全地大规模部署 GenAI 应用程序
网络·人工智能·安全·ai·部署·观点
山水阳泉曲1 个月前
FTP介绍、环境搭建、常用命令以及脚本
linux·sftp·部署·脚本·ftp·lftp