MBTiles 是一种基于 SQLite 数据库的空间瓦片存储格式,能够将海量的地图瓦片(包括栅格瓦片、矢量瓦片、UTFGrid 交互网格)打包成单个文件,极大简化了瓦片的存储、传输和管理。@mapbox/mbtiles 作为 Mapbox 官方推出的 Node.js 工具库,为开发者提供了操作 MBTiles 文件的完整 API,同时支持与 tilelive 生态集成,满足规模化瓦片处理需求。本文将从安装、核心 API、实战案例到生态集成,全面讲解该库的使用方式。
一、核心概念与安装
1.1 什么是 MBTiles
MBTiles 本质是 SQLite 数据库文件,通过标准化的表结构(tiles 存储瓦片数据、metadata 存储元信息、grids 存储 UTFGrid)管理地图瓦片。相比零散的文件系统存储,MBTiles 具备以下优势:
- 单文件存储,便于传输和备份;
- 基于 SQLite,支持高效的瓦片查询;
- 标准化元数据,兼容主流地图引擎。
1.2 安装 @mapbox/mbtiles
该库基于 Node.js 开发,需先确保已安装 Node.js(建议 12+ 版本),然后通过 npm 安装:
bash
npm install @mapbox/mbtiles
二、核心 API 详解
2.1 实例化 MBTiles 对象
所有操作的前提是创建 MBTiles 实例,通过构造函数指定文件路径和操作模式:
javascript
const MBTiles = require('@mapbox/mbtiles');
// 实例化(支持 ro/rw/rwc 三种模式)
new MBTiles('./tiles.mbtiles?mode=rwc', (err, mbtiles) => {
if (err) throw err;
// mbtiles 实例已就绪,可调用后续方法
console.log('MBTiles 实例创建成功');
});
模式说明:
ro:只读模式,文件不存在则报错;rw:读写模式,文件不存在则报错;rwc:读写+创建模式(默认),文件不存在则自动创建。
2.2 读取操作:获取瓦片与元数据
2.2.1 获取单个瓦片(getTile)
用于读取指定 ZXY(缩放级别/横坐标/纵坐标)的瓦片数据,返回的 data 是 gzip 压缩的 Buffer(矢量瓦片通常为 PBF 格式,栅格瓦片为 PNG/JPG):
javascript
const zlib = require('zlib');
// 读取 0级 0行 0列 的瓦片
mbtiles.getTile(0, 0, 0, (err, data, headers) => {
if (err) throw err;
// 解压 gzip 格式的瓦片数据(矢量瓦片需解压)
zlib.gunzip(data, (err, unzippedData) => {
if (err) throw err;
console.log('瓦片数据解压完成', unzippedData);
});
// headers 包含 HTTP 响应头(如 Content-Type)
console.log('瓦片响应头', headers);
});
2.2.2 获取元信息(getInfo)
读取 MBTiles 文件的元数据(存储在 metadata 表),包括缩放范围、边界、矢量图层信息等,是识别瓦片文件的核心方法:
javascript
mbtiles.getInfo((err, info) => {
if (err) throw err;
console.log('MBTiles 元信息:', info);
// 典型返回结果:
// {
// name: 'demo',
// minzoom: 0,
// maxzoom: 4,
// bounds: '-180,-85.0511,180,85.0511',
// format: 'pbf',
// vector_layers: [...]
// }
});
2.2.3 获取 UTFGrid 网格(getGrid)
UTFGrid 是用于地图交互的网格数据(如点击瓦片返回属性),该方法读取指定 ZXY 的 UTFGrid 数据:
javascript
mbtiles.getGrid(0, 0, 0, (err, grid) => {
if (err) throw err;
console.log('UTFGrid 数据:', grid); // JSON 格式的网格数据
});
2.3 写入操作:新增瓦片与元数据
写入操作需先调用 startWriting 开启写入模式,操作完成后调用 stopWriting 关闭,确保数据持久化。
2.3.1 开启/关闭写入模式
javascript
// 开启写入
mbtiles.startWriting((err) => {
if (err) throw err;
console.log('开始写入数据');
// 执行写入操作(putTile/putInfo/putGrid)...
// 关闭写入(必须调用,否则数据可能丢失)
mbtiles.stopWriting((err) => {
if (err) throw err;
console.log('写入完成,数据已持久化');
});
});
2.3.2 写入单个瓦片(putTile)
将瓦片 Buffer 写入指定 ZXY 位置,建议对矢量瓦片进行 gzip 压缩后写入:
javascript
const fs = require('fs');
const zlib = require('zlib');
// 读取本地矢量瓦片文件
const tileBuffer = fs.readFileSync('./tile.mvt');
// gzip 压缩后写入
zlib.gzip(tileBuffer, (err, gzippedBuffer) => {
if (err) throw err;
// 写入 0级 0行 0列 的瓦片
mbtiles.putTile(0, 0, 0, gzippedBuffer, (err) => {
if (err) throw err;
console.log('瓦片写入成功');
});
});
2.3.3 写入元信息(putInfo)
向 metadata 表写入自定义元数据,嵌套 JSON 会自动序列化存储:
javascript
const layername = 'roads';
const info = {
name: 'hello-world',
description: '矢量瓦片示例',
format: 'pbf', // 矢量瓦片格式为 PBF
version: 2,
minzoom: 0,
maxzoom: 4,
center: '0,0,1', // 中心点(经度,纬度,缩放级别)
bounds: '-180.000000,-85.051129,180.000000,85.051129', // 全球范围
type: 'overlay',
json: JSON.stringify({
vector_layers: [{
id: layername,
description: '',
minzoom: 0,
maxzoom: 4,
fields: {} // 图层属性字段
}]
})
};
mbtiles.putInfo(info, (err) => {
if (err) throw err;
console.log('元信息写入成功');
});
2.3.4 写入 UTFGrid 网格(putGrid)
将 JSON 格式的 UTFGrid 数据写入指定 ZXY 位置:
javascript
const fs = require('fs');
// 读取本地 UTFGrid 文件
const grid = JSON.parse(fs.readFileSync('./grid.json', 'utf8'));
// 写入 0级 0行 0列 的网格
mbtiles.putGrid(0, 0, 0, grid, (err) => {
if (err) throw err;
console.log('UTFGrid 写入成功');
});
三、与 tilelive 生态集成(规模化处理)
@mapbox/mbtiles 并非孤立使用,其核心设计目标是与 tilelive 生态集成,实现瓦片的批量迁移、转换和分发。tilelive 是 Mapbox 推出的瓦片处理框架,支持多种瓦片源(MBTiles、S3、本地文件)和目标(Sink)的无缝对接。
3.1 核心场景:MBTiles 瓦片同步到 S3
以下示例将 MBTiles 文件中的瓦片批量复制到 AWS S3 存储桶:
javascript
const tilelive = require('@mapbox/tilelive');
const MBTiles = require('@mapbox/mbtiles');
const s3 = require('@mapbox/tilelive-s3');
// 注册协议(让 tilelive 识别 mbtiles:// 和 s3://)
s3.registerProtocols(tilelive);
MBTiles.registerProtocols(tilelive);
// 源:本地 MBTiles 文件
const sourceUri = 'mbtiles:///Users/demo/tiles.mbtiles';
// 目标:S3 存储桶(格式:s3://桶名/瓦片路径模板)
const sinkUri = 's3://my-tile-bucket/tiles/{z}/{x}/{y}';
// 加载源 MBTiles
tilelive.load(sourceUri, (err, src) => {
if (err) throw err;
// 加载目标 S3
tilelive.load(sinkUri, (err, dest) => {
if (err) throw err;
// 复制配置:基于 MBTiles 生成 ZXY 流
const options = {
listScheme: src.createZXYStream() // 遍历所有瓦片的 ZXY 序列
};
// 批量复制瓦片到 S3
tilelive.copy(src, dest, options, (err) => {
if (err) throw err;
console.log('所有瓦片已同步到 S3!');
});
});
});
3.2 前置条件
- 安装依赖:
npm install @mapbox/tilelive @mapbox/tilelive-s3; - 配置 AWS 凭证:通过环境变量
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY配置,或使用 AWS 配置文件。
四、完整实战案例:创建并写入 MBTiles 文件
以下是一个完整的示例,演示创建 MBTiles 文件、写入瓦片和元数据的全流程:
javascript
const MBTiles = require('@mapbox/mbtiles');
const fs = require('fs');
const zlib = require('zlib');
// 1. 创建 MBTiles 实例(rwc 模式,文件不存在则创建)
new MBTiles('./my-tiles.mbtiles?mode=rwc', (err, mbtiles) => {
if (err) throw err;
// 2. 开启写入模式
mbtiles.startWriting((err) => {
if (err) throw err;
// 3. 写入元信息
const info = {
name: 'my-first-mbtiles',
description: 'A demo MBTiles file',
format: 'pbf',
minzoom: 0,
maxzoom: 2,
bounds: '-180,-85.0511,180,85.0511',
json: JSON.stringify({
vector_layers: [{
id: 'buildings',
minzoom: 0,
maxzoom: 2,
fields: { name: 'string' }
}]
})
};
mbtiles.putInfo(info, (err) => {
if (err) throw err;
console.log('元信息写入完成');
// 4. 读取本地矢量瓦片并写入
const tilePath = './sample-tile.mvt';
const tileBuffer = fs.readFileSync(tilePath);
zlib.gzip(tileBuffer, (err, gzippedBuffer) => {
if (err) throw err;
// 写入 0/0/0 瓦片
mbtiles.putTile(0, 0, 0, gzippedBuffer, (err) => {
if (err) throw err;
console.log('瓦片写入完成');
// 5. 关闭写入模式
mbtiles.stopWriting((err) => {
if (err) throw err;
console.log('所有操作完成,MBTiles 文件已保存');
});
});
});
});
});
});
五、测试与调试
库内置了测试用例,可通过以下命令运行测试,验证环境和功能是否正常:
bash
npm test
总结
核心要点回顾
- @mapbox/mbtiles 是 Node.js 操作 MBTiles 文件的官方库,支持瓦片的读写、元数据管理和 UTFGrid 操作;
- 写入操作必须通过
startWriting/stopWriting包裹,确保数据持久化; - 与 tilelive 集成可实现瓦片的规模化处理(如批量同步到 S3);
- 矢量瓦片建议 gzip 压缩后写入,读取时需解压才能解析内容。
适用场景
- 地图瓦片的本地存储与管理;
- 瓦片批量迁移(如 MBTiles → S3/本地文件);
- 自定义瓦片生成工具的开发;
- 地图应用中瓦片的动态读写。
通过 @mapbox/mbtiles,开发者可以高效地处理 MBTiles 格式的瓦片数据,结合 tilelive 生态还能满足规模化、跨存储介质的瓦片处理需求,是 Node.js 生态中地图瓦片开发的核心工具。
书签篮