跳到主要内容
本地瓦片地图服务器搭建与配置指南 | 极客日志
编程语言 Node.js 大前端 java
本地瓦片地图服务器搭建与配置指南 获取地图瓦片资源的多种方法(工具、脚本、命令行),并详细阐述了搭建本地瓦片地图服务器的方案(HTTP、TileServer-GL、Nginx、Docker、Express)。同时提供了 OpenLayers 前端集成配置示例及常见问题解决方案,涵盖跨域、投影系统及性能优化建议。
下载地图瓦片资源的几种方法
下载地图瓦片资源是构建离线地图应用或进行地理空间分析的基础工作。以下是几种常用的地图瓦片下载方法:
1. 使用专业地图下载工具
(1) Mobile Atlas Creator (MOBAC)
特点 :开源工具,支持多种地图源
支持格式 :SQLite MBTiles、OruxMaps、OsmAnd 等
下载方式 :
选择地图源(如 Google Maps、OpenStreetMap)
框选下载区域
设置缩放级别范围
选择输出格式并下载
(2) QGIS + QTiles 插件
步骤 :
1. 安装 QGIS 和 QTiles 插件
2. 设置地图范围和缩放级别
3. 选择输出目录和格式
4. 执行下载
2. 使用 Python 脚本下载
(1) 使用 requests 库直接下载
import os
import requests
def download_tiles (z, x_range, y_range, url_template, output_dir ):
os.makedirs(output_dir, exist_ok=True )
for x in x_range:
for y in y_range:
url = url_template.format (z=z, x=x, y=y)
response = requests.get(url, stream=True )
tile_path = os.path.join(output_dir, f"{z} _{x} _{y} .png" )
with open (tile_path, 'wb' ) as f:
for chunk in response.iter_content(1024 ):
f.write(chunk)
( )
download_tiles( , ( , ), ( , ), , )
print
f"Downloaded {tile_path} "
12
range
3420
3426
range
1670
1676
"https://mt.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"
"tiles"
(2) 使用 mercantile 库计算瓦片坐标 import mercantile
import requests
bbox = (116.3 , 39.8 , 116.5 , 40.0 )
zoom = 14
for tile in mercantile.tiles(*bbox, zooms=zoom):
url = f"https://a.tile.openstreetmap.org/{tile.z} /{tile.x} /{tile.y} .png"
response = requests.get(url)
with open (f"{tile.z} _{tile.x} _{tile.y} .png" , "wb" ) as f:
f.write(response.content)
3. 使用 Node.js 工具
(1) tile-downloader const TileDownloader = require ('tile-downloader' );
const downloader = new TileDownloader ({
minZoom : 10 ,
maxZoom : 14 ,
bounds : [116.3 , 39.8 , 116.5 , 40.0 ],
urlTemplate : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' ,
subdomains : ['a' , 'b' , 'c' ],
output : './tiles' ,
parallelDownloads : 5
});
downloader.start ();
4. 命令行工具
(1) 使用 wget 批量下载
for x in {3420..3425}; do
for y in {1670..1675}; do
wget "https://mt.google.com/vt/lyrs=m&x=${x} &y=${y} &z=15" -O "15_${x} _${y} .png"
done
done
5. 浏览器扩展方法
(1) 使用 Leaflet.Download 插件 L.tileLayer .downloader ('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' , {
subdomains : ['a' , 'b' , 'c' ],
minZoom : 10 ,
maxZoom : 18 ,
bounds : [[39.8 , 116.3 ], [40.0 , 116.5 ]]
}).addTo (map);
注意事项
遵守服务条款 :商业地图服务 (如 Google Maps) 通常禁止未经授权的瓦片下载
下载限制 :避免高频请求导致 IP 被封
存储组织 :建议按 z/x/y 或 z/x_y.png 格式组织瓦片
投影系统 :确保下载的瓦片与目标投影系统一致 (通常是 Web 墨卡托 EPSG:3857)
版权问题 :OpenStreetMap 等开源地图需遵守署名要求
高级技巧
增量下载 :先下载低级别瓦片,再根据需要下载高级别
多线程下载 :使用 Python 的 concurrent.futures 或 Node.js 的 cluster 模块加速
断点续传 :记录已下载瓦片,避免重复下载
瓦片合并 :使用 GDAL 将下载的瓦片拼接成单张大图
选择哪种方法取决于您的技术栈、下载规模和使用场景。对于小范围下载,Python 脚本或浏览器扩展比较方便;大规模下载建议使用专业工具或分布式爬虫方案。
搭建本地瓦片地图服务器 有了瓦片地图资源后,您可以通过多种方式搭建地图服务器。以下是几种常见方案,从简单到复杂排列:
1. 使用简易 HTTP 服务器(快速测试)
Python 内置 HTTP 服务器
python3 -m http.server 8000
访问方式:http://localhost:8000/tiles/{z}/{x}/{y}.png
Node.js http-server npm install -g http-server
http-server -p 8000
2. 专业瓦片服务器方案
(1) 使用 TileServer-GL(推荐)
支持 MBTiles、GeoJSON、GPKG 等多种格式
自动生成 OpenLayers/Leaflet 示例
提供 WMTS、TMS 等标准服务
npm install -g tileserver-gl
tileserver-gl your_tiles.mbtiles
tileserver-gl -c config.json
{
"options" : {
"paths" : {
"root" : "/path/to/your/tiles" ,
"mbtiles" : ""
}
} ,
"data" : {
"your-map" : {
"tilejson" : {
"tiles" : [ "http://localhost:8080/data/your-map/{z}/{x}/{y}.png" ]
}
}
}
}
(2) 使用 GeoServer(Java)
安装 GeoServer
进入 "Tile Caching" 设置
添加新的 "Gridset"(Web Mercator EPSG:3857)
创建 "Tile Layer" 指向您的瓦片目录
3. 使用 Nginx 高效服务静态瓦片 server {
listen 80;
server_name localhost;
location /tiles/ {
alias /path/to/your/tiles/;
# 启用 CORS
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET';
# 缓存控制
expires 30d;
# 支持 URL 重写(如果使用 {z}/{x}/{y} 结构)
rewrite ^/tiles/([0-9]+)/([0-9]+)/([0-9]+)\.(png|jpg)$ /$1/$2/$3.$4 last;
}
}
4. 使用 Docker 容器化部署 docker run -it -v /path/to/tiles:/data -p 8080:80 klokantech/tileserver-gl
docker run -v /path/to/tiles:/usr/share/nginx/html/tiles -p 80:80 nginx
5. 完整技术栈方案(Node.js + Express) const express = require ('express' );
const path = require ('path' );
const fs = require ('fs' );
const app = express ();
app.use ('/tiles' , express.static (path.join (__dirname, 'tiles' ), {
setHeaders : (res ) => {
res.set ('Access-Control-Allow-Origin' , '*' );
res.set ('Cache-Control' , 'public, max-age=86400' );
}
}));
app.get ('/' , (req, res ) => {
res.sendFile (path.join (__dirname, 'map-example.html' ));
});
app.listen (3000 , () => {
console .log ('Tile server running on port 3000' );
});
前端调用示例(OpenLayers) <!DOCTYPE html >
<html >
<head >
<title > 本地瓦片地图</title >
<link rel ="stylesheet" href ="https://cdn.jsdelivr.net/npm/ol/ol.css" >
<style > #map { width : 100% ; height : 100vh ; }</style >
</head >
<body >
<div id ="map" > </div >
<script src ="https://cdn.jsdelivr.net/npm/ol/ol.js" > </script >
<script >
new ol.Map ({
target : 'map' ,
layers : [
new ol.layer .Tile ({
source : new ol.source .XYZ ({
url : 'http://localhost:3000/tiles/{z}/{x}/{y}.png' ,
tileSize : 256
})
})
],
view : new ol.View ({
center : ol.proj .fromLonLat ([116.4 , 39.9 ]),
zoom : 10
})
});
</script >
</body >
</html >
高级功能实现
1. 动态瓦片生成
app.get ('/tiles/:z/:x/:y.png' , (req, res ) => {
const { z, x, y } = req.params ;
const tilePath = path.join (__dirname, 'tiles' , z, x, `${y} .png` );
if (fs.existsSync (tilePath)) {
res.sendFile (tilePath);
} else {
res.status (404 ).send ();
}
});
2. 瓦片访问控制
app.use ('/tiles' , (req, res, next ) => {
if (req.query .key === 'YOUR_SECRET_KEY' ) {
next ();
} else {
res.status (403 ).send ('Forbidden' );
}
});
性能优化建议
启用 Gzip 压缩 :减少传输数据量
设置缓存头 :Cache-Control: public, max-age=31536000
使用 CDN :将静态瓦片部署到 CDN
懒加载 :只返回请求范围内的瓦片
日志监控 :记录瓦片请求情况
常见问题解决
跨域问题 :确保服务器返回正确的 CORS 头
404 错误 :检查 URL 路径和实际文件路径是否匹配
瓦片错位 :确认投影系统(通常是 EPSG:3857)
性能瓶颈 :考虑使用 Nginx 缓存或分布式存储
选择哪种方案取决于您的技术栈、性能需求和安全要求。对于简单场景,静态文件服务器足够;复杂场景建议使用 TileServer-GL 或 GeoServer 等专业解决方案。
配置本地瓦片地图在 OpenLayers 中 要在 OpenLayers 中配置本地瓦片地图服务,你可以使用 ol.source.XYZ 或 ol.source.TileImage。根据你提供的 URL 格式,这是一个标准的 XYZ 瓦片服务接口。
this .map = new ol.Map ({
layers : [
new ol.layer .Tile ({
source : new ol.source .XYZ ({
url : 'http://localhost:26737/tile/local?z={z}&x={x}&y={y}' ,
tileSize : 256 ,
minZoom : 0 ,
maxZoom : 19
})
})
],
target : this .mapId ,
view : new ol.View ({
center : ol.proj .fromLonLat ([0 , 0 ]),
zoom : 2
}),
interactions : ol.interaction .defaults ({
mouseWheelZoom : true ,
doubleClickZoom : true
})
});
注意事项
跨域问题 :如果你的 OpenLayers 应用和瓦片服务不在同一个域名下,可能会遇到 CORS 问题。确保你的瓦片服务设置了正确的 CORS 头。
投影设置 :默认情况下,OpenLayers 使用 EPSG:3857(Web 墨卡托投影)。如果你的瓦片使用其他投影(如 EPSG:4326),需要额外配置。
性能优化 :如果瓦片服务支持,可以考虑设置 crossOrigin: 'anonymous' 以便浏览器缓存瓦片。
new ol.source .XYZ ({
url : '...' ,
tileLoadFunction : function (tile, src ) {
tile.getImage ().src = src;
tile.getImage ().onerror = function ( ) {
};
}
})
瓦片坐标系 :确认你的本地瓦片服务使用的是标准的 XYZ 瓦片坐标系。如果是 TMS 坐标系,y 坐标需要反转:
url : 'http://localhost:26737/tile/local?z={z}&x={x}&y={-y}'
如果你的瓦片服务有特殊要求或使用非标准配置,可能需要进行相应的调整。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online