02. 环境搭建

MapLibre 学习指南:文章导航

在线预览地址:env-00jy66xyyn4y-static.normal.cloudstatic.cn/maplibre-ba...

base 代码仓库地址:

如果这个系列对你有帮助,欢迎给仓库点一个 Star,代码仓库可以拉取到完整的学习代码,在docs目录下有规划良好的.md学习文档,希望可以帮助到你(请给个免费的start哦)。你的支持是我持续更新和完善 MapLibre 学习内容的动力,也能帮助更多正在学习 WebGIS / MapLibre 的前端同学找到这份资料。个人微信: 1576554007 欢迎一起学习交流

第一阶段:入门基础(第 1-4 节)

节次 标题 核心内容 文档路径
01 认识 MapLibre GL JS MapLibre 简介与生态、与 Mapbox 的关系、开源许可、应用场景、与其他地图库(Leaflet/OpenLayers/Cesium)对比 src/docs/stage1/01.认识MapLibre.md
02 环境搭建与第一张地图 Vue3+Vite 项目创建、安装 MapLibre GL JS、创建第一张地图(Map 构造函数参数详解)、地图容器与响应式尺寸 src/docs/stage1/02.环境搭建与第一张地图.md
03 地图基础操作 缩放/平移/旋转/倾斜、flyTo/easeTo/jumpTo 动画方法、fitBounds 自适应范围、地图事件监听(click/move/zoom/load) src/docs/stage1/03.地图基础操作.md
04 地图控件 NavigationControl、ScaleControl、GeolocateControl、FullscreenControl、AttributionControl、自定义控件(IControl 接口) src/docs/stage1/04.地图控件.md

02. 环境搭建与第一张地图

环境准备

前置要求

  • Node.js ≥ 18(推荐使用 LTS 版本)
  • 包管理器:pnpm(推荐)/ npm / yarn
  • IDE:VS Code(推荐安装 Vue - Official 扩展)

创建 Vue 3 + TypeScript 项目

bash 复制代码
# 使用 Vite 创建项目
pnpm create vite maplibre-base --template vue-ts

# 进入项目
cd maplibre-base

# 安装依赖
pnpm install

安装 MapLibre GL JS

bash 复制代码
pnpm add maplibre-gl

安装后 package.json 中会出现:

json 复制代码
{
  "dependencies": {
    "maplibre-gl": "^5.x.x"
  }
}

创建第一张地图

基本步骤

  1. 创建一个 HTML 容器元素
  2. 引入 MapLibre GL JS 和 CSS
  3. 使用 new maplibregl.Map() 初始化地图

最小示例

vue 复制代码
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import maplibregl from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'  // 必须引入 CSS

/** 地图容器 DOM 引用 */
const mapContainer = ref<HTMLElement>()
/** 地图实例 */
let map: maplibregl.Map | null = null

onMounted(() => {
  if (!mapContainer.value) return

  map = new maplibregl.Map({
    container: mapContainer.value,  // 容器元素
    style: {                         // 地图样式
      version: 8,
      sources: {
        osm: {
          type: 'raster',
          tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
          tileSize: 256
        }
      },
      layers: [{
        id: 'osm-layer',
        type: 'raster',
        source: 'osm'
      }]
    },
    center: [116.39, 39.91],  // 中心点 [经度, 纬度]
    zoom: 10                   // 缩放级别
  })
})

onBeforeUnmount(() => {
  if (map) {
    map.remove()  // 销毁地图,释放资源
    map = null
  }
})
</script>

<template>
  <div ref="mapContainer" style="width: 100%; height: 100vh;"></div>
</template>

⚠️ 重要 :必须引入 maplibre-gl/dist/maplibre-gl.css,否则地图控件样式会异常。


Map 构造函数参数详解

new maplibregl.Map(options) 接受一个配置对象,以下是核心参数:

必填参数

参数 类型 说明
container `HTMLElement string`
style `StyleSpecification string`

视图参数

参数 类型 默认值 说明
center [lng, lat] [0, 0] 地图中心点坐标(经度, 纬度)
zoom number 0 缩放级别(0=全球,18=建筑级别)
bearing number 0 地图旋转角度(0=正北,顺时针)
pitch number 0 地图倾斜角度(0=俯视,60=透视)
minZoom number 0 最小缩放级别
maxZoom number 22 最大缩放级别
maxPitch number 60 最大倾斜角度

交互参数

参数 类型 默认值 说明
interactive boolean true 是否允许交互
scrollZoom boolean true 是否允许滚轮缩放
boxZoom boolean true 是否允许框选缩放
dragRotate boolean true 是否允许拖拽旋转
dragPan boolean true 是否允许拖拽平移
keyboard boolean true 是否允许键盘控制
doubleClickZoom boolean true 是否允许双击缩放
touchZoomRotate boolean true 是否允许触摸缩放旋转

其他常用参数

参数 类型 说明
maxBounds LngLatBoundsLike 限制地图可视范围
fitBoundsOptions object fitBounds 的默认配置
attributionControl boolean 是否显示归属控件(默认 true)
hash boolean 是否将地图状态同步到 URL hash
antialias boolean 是否开启抗锯齿

缩放级别含义

级别 大致比例尺 可见内容
0 1:500,000,000 全球
3 1:70,000,000 洲
5 1:18,000,000 国家
8 1:2,000,000 省
10 1:500,000 城市
13 1:70,000 城区
15 1:18,000 街道
17 1:4,000 建筑
20 1:500 详细

地图样式(Style)

MapLibre 的样式是一个 JSON 对象,遵循 Style Specification。最简结构如下:

json 复制代码
{
  "version": 8,
  "sources": {
    "source-name": {
      "type": "raster",
      "tiles": ["https://tile-server/{z}/{x}/{y}.png"],
      "tileSize": 256
    }
  },
  "layers": [
    {
      "id": "layer-name",
      "type": "raster",
      "source": "source-name"
    }
  ]
}

使用在线样式 URL

除了手写 JSON,也可以直接传入样式 URL:

ts 复制代码
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://demotiles.maplibre.org/style.json'  // MapLibre 官方演示样式
})

常用免费底图

ts 复制代码
/** OSM 标准底图 */
const osmStyle = {
  version: 8,
  sources: {
    osm: {
      type: 'raster',
      tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
      tileSize: 256
    }
  },
  layers: [{ id: 'osm', type: 'raster', source: 'osm' }]
}

/** ESRI 卫星影像 */
const satelliteStyle = {
  version: 8,
  sources: {
    satellite: {
      type: 'raster',
      tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'],
      tileSize: 256
    }
  },
  layers: [{ id: 'satellite', type: 'raster', source: 'satellite' }]
}

/** CARTO 暗色底图 */
const darkStyle = {
  version: 8,
  sources: {
    dark: {
      type: 'raster',
      tiles: ['https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png'],
      tileSize: 256
    }
  },
  layers: [{ id: 'dark', type: 'raster', source: 'dark' }]
}

Vue 3 中使用 MapLibre 的注意事项

1. 不要将 Map 实例存为 reactive/ref

ts 复制代码
// ❌ 错误:会导致 Vue 深度代理 Map 对象,严重影响性能
const map = ref<maplibregl.Map>()

// ✅ 正确:使用普通变量
let map: maplibregl.Map | null = null

MapLibre Map 实例内部有大量 WebGL 上下文和事件监听器,Vue 的响应式代理会干扰其内部状态。

2. 组件卸载时销毁地图

ts 复制代码
onBeforeUnmount(() => {
  if (map) {
    map.remove()  // 释放 WebGL 上下文和事件监听
    map = null
  }
})

3. 容器必须有明确的宽高

地图容器 必须 有确定的宽度和高度,否则地图不会渲染:

css 复制代码
/* ✅ 正确 */
.map-container {
  width: 100%;
  height: 100%;
}

/* ❌ 错误 - 高度为 auto 时容器高度为 0 */
.map-container {
  width: 100%;
}

4. 地图加载完成后再操作

ts 复制代码
map.on('load', () => {
  // 在这里添加数据源、图层等
  map.addSource('my-source', { ... })
  map.addLayer({ ... })
})

本课小结

  • MapLibre GL JS 通过 npm/pnpm 安装,必须同时引入 CSS
  • new maplibregl.Map(options) 是一切的起点
  • 核心参数:container、style、center、zoom
  • Vue 中注意:不要用 ref() 包裹 Map 实例,卸载时要 map.remove()
  • 容器必须有明确的宽高

📌 上一节:01. 认识 MapLibre 📌 下一节:03. 地图基础操作

相关推荐
jay神14 分钟前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神22 分钟前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat26 分钟前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss1 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan2 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真2 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment2 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan2 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么2 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技3 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue