Vue3 + OpenLayers(OL) 加载天地图超详细教程(新手友好|可直接复制运行)

该文章已生成可运行项目,

Vue3 + OpenLayers(OL) 加载天地图超详细教程(新手友好|可直接复制运行)

在Vue3项目中做地图开发,天地图是国内合规、免费、稳定的首选地图源,而OpenLayers(简称OL)是功能强大的开源地图库——两者结合,既能享受天地图的合规性,又能借助OL轻松实现遮罩、省份高亮、标记点等复杂功能,比天地图原生API更灵活、更好用。

本文从「天地图Key申请」开始,一步步教你完成Vue3 + OL加载天地图,全程带代码、带截图(示意图)、避坑指南,新手也能一次成功,复制代码就能直接运行!

一、前置准备:申请天地图Key(必做)

天地图所有接口都需要Key(也称TK)才能调用,申请完全免费,步骤简单,全程1分钟搞定。

1. 进入天地图云中心

打开天地图云中心官网:https://cloudcenter.tianditu.gov.cn/

示意图(可自行截图补充):进入后点击右上角「登录/注册」,没有账号的话,用手机号注册即可,实名认证免费(仅用于合规校验,不收费)。

2. 创建应用,获取Key

  1. 登录后,点击顶部导航「开发管理 → 应用管理」,再点击「创建应用」;
    在这里插入图片描述

  2. 填写应用信息:
    在这里插入图片描述

    • 应用名称:随便填(如「Vue3+OL天地图测试」);

    • 应用类型:必须选「浏览器端」(重点!选其他类型会导致调用失败);
      在这里插入图片描述

    • 备注:可选填,方便后续管理;

  3. 点击「创建」,创建成功后,就能看到你的「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&gt>
  <!-- 地图容器:必须设置宽高,否则地图无法显示 -->
  <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_wcva_w
卫星影像图img_wcia_w
地形晕渲图ter_wcta_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 生成)

本文章已经生成可运行项目
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jieyucx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值