Vue3 + OpenLayers(OL) 加载天地图超详细教程(新手友好|可直接复制运行)
在Vue3项目中做地图开发,天地图是国内合规、免费、稳定的首选地图源,而OpenLayers(简称OL)是功能强大的开源地图库——两者结合,既能享受天地图的合规性,又能借助OL轻松实现遮罩、省份高亮、标记点等复杂功能,比天地图原生API更灵活、更好用。
本文从「天地图Key申请」开始,一步步教你完成Vue3 + OL加载天地图,全程带代码、带截图(示意图)、避坑指南,新手也能一次成功,复制代码就能直接运行!
一、前置准备:申请天地图Key(必做)
天地图所有接口都需要Key(也称TK)才能调用,申请完全免费,步骤简单,全程1分钟搞定。
1. 进入天地图云中心
打开天地图云中心官网:https://cloudcenter.tianditu.gov.cn/
示意图(可自行截图补充):进入后点击右上角「登录/注册」,没有账号的话,用手机号注册即可,实名认证免费(仅用于合规校验,不收费)。
2. 创建应用,获取Key
-
登录后,点击顶部导航「开发管理 → 应用管理」,再点击「创建应用」;

-
填写应用信息:

-
应用名称:随便填(如「Vue3+OL天地图测试」);
-
应用类型:必须选「浏览器端」(重点!选其他类型会导致调用失败);

-
备注:可选填,方便后续管理;
-
-
点击「创建」,创建成功后,就能看到你的
「Key(TK)」,复制保存好,后续会用到。
避坑提醒:创建应用后,可点击「设置」,配置「域名白名单」(本地开发可填localhost,线上项目填实际域名),避免跨域或调用失败。
二、项目准备:Vue3 + Vite 环境搭建(已有项目可跳过)
本文基于Vue3 + Vite开发(主流组合),如果已有Vue3项目,直接跳过这一步;如果没有,先快速搭建环境:
# 1. 创建Vue3项目(Vite)
npm create vite@latest vue3-ol-tianditu -- --template vue
# 2. 进入项目目录
cd vue3-ol-tianditu
# 3. 安装依赖
npm install
# 4. 启动项目
npm run dev
三、核心步骤:安装OpenLayers(OL)
OpenLayers是开源地图库,需要通过npm安装,命令如下(项目根目录执行):
npm install ol
安装完成后,无需额外配置,直接在组件中引入即可,Vite会自动处理依赖。
四、完整实现:Vue3 + OL 加载天地图
新建地图组件(推荐新建 components/TiandituMap.vue),复制下面代码,只需替换自己的天地图Key,就能直接运行,每一步都有详细注释,新手也能看懂。
1. 组件完整代码(可直接复制)
<template>>
<!-- 地图容器:必须设置宽高,否则地图无法显示 -->
<div ref="mapContainer" class="map-container"></div>
</template>
<script setup>
// 引入Vue3核心钩子
import { ref, onMounted, onUnmounted } from 'vue'
// 引入OpenLayers核心模块
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile' // 瓦片图层(加载天地图核心)
import XYZ from 'ol/source/XYZ' // XYZ数据源(适配天地图瓦片格式)
import { fromLonLat } from 'ol/proj' // 坐标转换(天地图经纬度转OL坐标)
// 地图容器DOM引用
const mapContainer = ref(null)
// 地图实例(全局保存,方便后续操作)
let map = null
// 替换成你自己的天地图Key(重点!)
const TIANDITU_KEY = '你的天地图Key'
// 组件挂载后初始化地图(必须在DOM渲染完成后执行)
onMounted(() => {
initMap()
})
// 初始化地图核心函数
function initMap() {
// 1. 加载天地图矢量底图(最常用,可切换成影像图、地形图)
const tiandituVecLayer = new TileLayer({
source: new XYZ({
// 天地图矢量底图瓦片地址(球面墨卡托投影,适配OL)
url: `https://t{0-7}.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${TIANDITU_KEY}`,
// 天地图二级域名(t0-t7),随机切换,避免单域名限流
tileLoadFunction: (tile, url) => {
tile.setSrc(url.replace('{0-7}', Math.floor(Math.random() * 8)))
}
})
})
// 2. 加载天地图注记层(文字、道路名称、地名,必须单独加载,否则底图没有文字)
const tiandituLabelLayer = new TileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=${TIANDITU_KEY}`,
tileLoadFunction: (tile, url) => {
tile.setSrc(url.replace('{0-7}', Math.floor(Math.random() * 8)))
}
})
})
// 3. 创建地图实例
map = new Map({
target: mapContainer.value, // 挂载到DOM容器
layers: [tiandituVecLayer, tiandituLabelLayer], // 加载底图 + 注记层(顺序不能乱)
view: new View({
center: fromLonLat([106.5, 33]), // 地图中心点(中国地理中心经纬度)
zoom: 4, // 初始缩放级别(3-18可调,数字越大越清晰)
minZoom: 3, // 最小缩放级别(避免缩太小看到国外)
maxZoom: 18, // 最大缩放级别(天地图最大支持18级)
projection: 'EPSG:3857' // 球面墨卡托投影(OL默认,适配天地图)
})
})
}
// 组件销毁时,销毁地图实例(避免内存泄漏)
onUnmounted(() => {
if (map) {
map.setTarget(null) // 解除地图与DOM的绑定
map = null // 清空实例
}
})
</script>
<style scoped>
/* 地图容器必须设置宽高,否则无法显示 */
.map-container {
width: 100%;
height: 80vh; /* 占视口高度80%,可自行调整 */
}
</style>
2. 组件使用(在页面中引入)
在App.vue中引入上面创建的地图组件,即可在页面中显示天地图:
<template>
<div class="app">
<h1>Vue3 + OL 加载天地图</h1>
<TiandituMap />
</div>
</template>
<script setup>
import TiandituMap from './components/TiandituMap.vue'
</script>
<style>
.app {
padding: 20px;
}
</style>
3. 运行效果
执行 npm run dev 启动项目,打开浏览器,就能看到:
-
天地图矢量底图正常显示,带有地名、道路文字;
-
支持鼠标滚轮缩放、拖拽地图;
-
默认显示中国全貌,缩放后能看到详细的省市、道路。
示意图(可自行截图补充):页面顶部标题 + 下方完整天地图,可正常操作。
五、扩展功能:切换天地图图层(矢量/影像/地形)
天地图支持多种图层类型,只需修改瓦片地址中的「图层标识」,就能切换不同风格的地图,以下是常用图层配置,直接替换代码中的底图和注记地址即可:
| 图层类型 | 底图瓦片地址(替换vec_w) | 注记瓦片地址(替换cva_w) |
|---|---|---|
| 矢量底图(默认) | vec_w | cva_w |
| 卫星影像图 | img_w | cia_w |
| 地形晕渲图 | ter_w | cta_w |
| 示例:切换为卫星影像图 |
// 卫星影像底图
const tiandituVecLayer = new TileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/img_w/wmts?xxx&tk=${TIANDITU_KEY}`, // 替换vec_w为img_w
tileLoadFunction: (tile, url) => {
tile.setSrc(url.replace('{0-7}', Math.floor(Math.random() * 8)))
}
})
})
// 卫星影像注记
const tiandituLabelLayer = new TileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/cia_w/wmts?xxx&tk=${TIANDITU_KEY}`, // 替换cva_w为cia_w
tileLoadFunction: (tile, url) => {
tile.setSrc(url.replace('{0-7}', Math.floor(Math.random() * 8)))
}
})
})
六、常见问题避坑指南(新手必看)
很多新手加载失败,都是踩了以下坑,提前规避,一次成功:
1. 地图空白,不显示任何内容
-
原因1:天地图Key错误,或应用类型不是「浏览器端」;
-
原因2:地图容器没有设置宽高(必须给.map-container设置width和height);
-
解决:检查Key是否正确、应用类型,确认容器宽高设置。
2. 底图显示,但没有文字(地名、道路)
-
原因:只加载了底图图层,没有加载注记图层(cva_w/cia_w);
-
解决:必须同时加载「底图图层 + 注记图层」,顺序不能乱(底图在前,注记在后)。
3. 控制台报错「跨域」
-
原因:没有配置域名白名单,天地图限制了非法域名调用;
-
解决:进入天地图云中心 → 应用管理 → 对应应用 → 设置 → 添加域名白名单(本地开发填localhost,线上填实际域名)。
4. 地图加载缓慢、卡顿
-
原因:没有使用随机二级域名(t0-t7),单域名限流;
-
解决:保留代码中的tileLoadFunction,实现随机切换二级域名,提升加载速度。
七、进阶功能预告(后续可扩展)
基于本文的基础配置,还能轻松实现以下常用功能(适合后续扩展):
-
只显示中国地图(添加遮罩,隐藏国外区域);
-
加载省份边界GeoJSON,实现点击省份高亮;
-
添加标记点、弹窗、轨迹线;
-
限制地图拖动范围,禁止拖出中国;
-
实现地理编码(地址转经纬度)、POI搜索。
八、总结
Vue3 + OpenLayers 加载天地图的核心流程:申请天地图Key → 安装OL → 动态加载天地图瓦片 → 初始化地图,全程没有复杂配置,复制代码就能运行。
相比天地图原生API,OL的优势在于功能更强大,后续扩展省份高亮、遮罩等功能更简单,而且完全免费、开源,适合Vue3前端地图开发的各种场景(个人项目、企业项目都适用)。
如果觉得本文有用,欢迎收藏、转发,后续会更新进阶功能教程,帮助大家快速实现复杂地图需求~
(注:文档部分内容可能由 AI 生成)

&spm=1001.2101.3001.5002&articleId=160153130&d=1&t=3&u=4600bd77167d4389bea457ca495d0cd1)
2329

被折叠的 条评论
为什么被折叠?



