02. 环境搭建

5 阅读5分钟

MapLibre 学习指南:文章导航

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

base 代码仓库地址:

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

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

节次标题核心内容文档路径
01认识 MapLibre GL JSMapLibre 简介与生态、与 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 项目

# 使用 Vite 创建项目
pnpm create vite maplibre-base --template vue-ts

# 进入项目
cd maplibre-base

# 安装依赖
pnpm install

安装 MapLibre GL JS

pnpm add maplibre-gl

安装后 package.json 中会出现:

{
  "dependencies": {
    "maplibre-gl": "^5.x.x"
  }
}

创建第一张地图

基本步骤

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

最小示例

<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) 接受一个配置对象,以下是核心参数:

必填参数

参数类型说明
containerHTMLElement | string地图容器,可以是 DOM 元素或元素 ID
styleStyleSpecification | string地图样式,可以是 JSON 对象或样式 URL

视图参数

参数类型默认值说明
center[lng, lat][0, 0]地图中心点坐标(经度, 纬度)
zoomnumber0缩放级别(0=全球,18=建筑级别)
bearingnumber0地图旋转角度(0=正北,顺时针)
pitchnumber0地图倾斜角度(0=俯视,60=透视)
minZoomnumber0最小缩放级别
maxZoomnumber22最大缩放级别
maxPitchnumber60最大倾斜角度

交互参数

参数类型默认值说明
interactivebooleantrue是否允许交互
scrollZoombooleantrue是否允许滚轮缩放
boxZoombooleantrue是否允许框选缩放
dragRotatebooleantrue是否允许拖拽旋转
dragPanbooleantrue是否允许拖拽平移
keyboardbooleantrue是否允许键盘控制
doubleClickZoombooleantrue是否允许双击缩放
touchZoomRotatebooleantrue是否允许触摸缩放旋转

其他常用参数

参数类型说明
maxBoundsLngLatBoundsLike限制地图可视范围
fitBoundsOptionsobjectfitBounds 的默认配置
attributionControlboolean是否显示归属控件(默认 true)
hashboolean是否将地图状态同步到 URL hash
antialiasboolean是否开启抗锯齿

缩放级别含义

级别大致比例尺可见内容
01:500,000,000全球
31:70,000,000
51:18,000,000国家
81:2,000,000
101:500,000城市
131:70,000城区
151:18,000街道
171:4,000建筑
201:500详细

地图样式(Style)

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

{
  "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:

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

常用免费底图

/** 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

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

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

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

2. 组件卸载时销毁地图

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

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

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

/* ✅ 正确 */
.map-container {
  width: 100%;
  height: 100%;
}

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

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

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

本课小结

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

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