GIS比例尺计算工具 - Web墨卡托投影地图层级比例尺与距离计算
GIS比例尺计算工具
计算Web墨卡托投影(EPSG:3857)每个层级的比例尺、地面分辨率、图上距离与实地距离
距离换算计算器
纬度越高,地面分辨率越小
图上距离 → 实地距离
实地距离 → 图上距离
当前层级参数 (Zoom 10)
比例尺
1:577,791
赤道地面分辨率
152.87 米/像素
当前纬度地面分辨率
199.30 米/像素
瓦片数量
1024 × 1024
各层级参数一览
| 层级 | 比例尺 | 赤道分辨率 (米/像素) | 256px对应实地距离 | 瓦片数 |
|---|---|---|---|---|
| 0 | 1:591,657,528 | 156543.03 | 40075.02 km | 1 |
| 1 | 1:295,828,764 | 78271.52 | 20037.51 km | 2 |
| 2 | 1:147,914,382 | 39135.76 | 10018.75 km | 4 |
| 3 | 1:73,957,191 | 19567.88 | 5009.38 km | 8 |
| 4 | 1:36,978,595 | 9783.94 | 2504.69 km | 16 |
| 5 | 1:18,489,298 | 4891.97 | 1252.34 km | 32 |
| 6 | 1:9,244,649 | 2445.98 | 626.17 km | 64 |
| 7 | 1:4,622,324 | 1222.99 | 313.09 km | 128 |
| 8 | 1:2,311,162 | 611.50 | 156.54 km | 256 |
| 9 | 1:1,155,581 | 305.75 | 78.27 km | 512 |
| 10 | 1:577,791 | 152.87 | 39.14 km | 1024 |
| 11 | 1:288,895 | 76.44 | 19.57 km | 2048 |
| 12 | 1:144,448 | 38.22 | 9.78 km | 4096 |
| 13 | 1:72,224 | 19.11 | 4.89 km | 8192 |
| 14 | 1:36,112 | 9.55 | 2.45 km | 16384 |
| 15 | 1:18,056 | 4.78 | 1.22 km | 32768 |
| 16 | 1:9,028 | 2.39 | 611.50 m | 65536 |
| 17 | 1:4,514 | 1.19 | 305.75 m | 131072 |
| 18 | 1:2,257 | 0.597164 | 152.87 m | 262144 |
| 19 | 1:1,128 | 0.298582 | 76.44 m | 524288 |
计算原理
Web墨卡托投影 (EPSG:3857)
Web墨卡托投影(又称球面墨卡托、伪墨卡托)是Google Maps、百度地图等Web地图服务采用的投影方式。 它将WGS84椭球体视为半径为 R = 6378137m 的正球体,使用正轴等角圆柱投影将球面坐标映射到平面。
核心参数
- 地球半径 R = 6,378,137 m(WGS84椭球长半轴)
- 瓦片尺寸 = 256 × 256 像素
- 第0级:整个世界用 1 张 256×256 瓦片表示
- 每升一级:瓦片数量在行和列上各翻倍
- 屏幕DPI = 96(ArcGIS标准)
- 数据来源:比例尺和分辨率直接取自 ArcGIS MapServer 的 tileInfo.lods
计算公式
各层级的比例尺和赤道地面分辨率直接使用 ArcGIS MapServer 提供的精确值, 其他参数据此推导。设缩放层级为 z,ArcGIS 提供的赤道地面分辨率为 Resolution,则:
- 赤道地面分辨率(每像素对应的实地距离):
Resolution = 2πR / (256 × 2z)米/像素
(本工具直接使用ArcGIS MapServer提供的精确值) - 比例尺(ArcGIS标准,DPI=96):
Scale = 1 : (Resolution × 96 / 0.0254)
其中 0.0254 = 1英寸对应的米数(本工具直接使用ArcGIS MapServer提供的精确值) - 任意纬度的地面分辨率:
Resolutionlat = Resolution / cos(lat)米/像素
(纬度越高,cos(lat)越小,分辨率越小,表示更精细) - 瓦片数:
Tiles = 2z(行和列各 2z 张) - 单张瓦片覆盖的实地距离(赤道):
TileSpan = 256 × Resolution米
距离换算
- 图上距离 → 实地距离:
Ground Distance = Pixel Distance × Resolutionlat - 实地距离 → 图上距离:
Pixel Distance = Ground Distance / Resolutionlat
比例尺与层级的关系
在Web墨卡托投影中,比例尺是相对于赤道的。由于墨卡托投影的等角特性,在地图上任意位置的比例尺 (图上距离与实地距离的比值)在同一缩放层级下是一致的,这与传统纸质地图不同。 但需要注意,地面分辨率会随纬度变化——纬度越高,每像素代表的实地距离越短, 这是因为高纬度地区在墨卡托投影中被放大了。
代码实现
JavaScript
/**
* Web墨卡托投影比例尺与距离计算
* EPSG:3857 (球面墨卡托)
* 数据来源: ArcGIS MapServer tileInfo.lods
*/
const TILE_SIZE = 256;
// ArcGIS MapServer 提供的各层级参数 (EPSG:3857, DPI=96)
const LODS = [
{ level: 0, resolution: 156543.03392800014, scale: 591657527.591555 },
{ level: 1, resolution: 78271.51696399994, scale: 295828763.795777 },
{ level: 2, resolution: 39135.75848200009, scale: 147914381.897889 },
{ level: 3, resolution: 19567.87924099992, scale: 73957190.948944 },
{ level: 4, resolution: 9783.93962049996, scale: 36978595.474472 },
{ level: 5, resolution: 4891.96981024998, scale: 18489297.737236 },
{ level: 6, resolution: 2445.98490512499, scale: 9244648.868618 },
{ level: 7, resolution: 1222.992452562495, scale: 4622324.434309 },
{ level: 8, resolution: 611.4962262813797, scale: 2311162.217155 },
{ level: 9, resolution: 305.74811314055756, scale: 1155581.108577 },
{ level: 10, resolution: 152.87405657041106, scale: 577790.554289 },
{ level: 11, resolution: 76.43702828507324, scale: 288895.277144 },
{ level: 12, resolution: 38.21851414253662, scale: 144447.638572 },
{ level: 13, resolution: 19.10925707126831, scale: 72223.819286 },
{ level: 14, resolution: 9.554628535634155, scale: 36111.909643 },
{ level: 15, resolution: 4.77731426794937, scale: 18055.954822 },
{ level: 16, resolution: 2.388657133974685, scale: 9027.977411 },
{ level: 17, resolution: 1.1943285668550503, scale: 4513.988705 },
{ level: 18, resolution: 0.5971642835598172, scale: 2256.994353 },
{ level: 19, resolution: 0.29858214164761665, scale: 1128.497176 },
];
/**
* 获取指定层级的赤道地面分辨率
* @param {number} zoom - 缩放层级 (0-19)
* @returns {number} 地面分辨率(米/像素)
*/
function getResolution(zoom) {
const lod = LODS.find(l => l.level === zoom);
return lod ? lod.resolution : 0;
}
/**
* 计算指定层级和纬度的地面分辨率
* @param {number} zoom - 缩放层级
* @param {number} lat - 纬度(度)
* @returns {number} 地面分辨率(米/像素)
*/
function getResolutionAtLat(zoom, lat) {
return getResolution(zoom) / Math.cos(lat * Math.PI / 180);
}
/**
* 图上距离转实地距离
* @param {number} pixels - 图上距离(像素)
* @param {number} zoom - 缩放层级
* @param {number} lat - 纬度(度)
* @returns {number} 实地距离(米)
*/
function pixelToGroundDistance(pixels, zoom, lat) {
return pixels * getResolutionAtLat(zoom, lat);
}
/**
* 实地距离转图上距离
* @param {number} meters - 实地距离(米)
* @param {number} zoom - 缩放层级
* @param {number} lat - 纬度(度)
* @returns {number} 图上距离(像素)
*/
function groundToPixelDistance(meters, zoom, lat) {
return meters / getResolutionAtLat(zoom, lat);
}
// 使用示例
const zoom = 10;
const lat = 39.90923; // 北京纬度
const resolution = getResolutionAtLat(zoom, lat);
const lod = LODS.find(l => l.level === zoom);
console.log(`层级 ${zoom} 在纬度 ${lat}° 的分辨率: ${resolution.toFixed(2)} 米/像素`);
console.log(`层级 ${zoom} 的比例尺: 1:${Math.round(lod.scale)}`);
console.log(`256像素对应实地距离: ${pixelToGroundDistance(256, zoom, lat).toFixed(2)} 米`);Python
import math
# ArcGIS MapServer 提供的各层级参数 (EPSG:3857, DPI=96)
LODS = [
{"level": 0, "resolution": 156543.03392800014, "scale": 591657527.591555},
{"level": 1, "resolution": 78271.51696399994, "scale": 295828763.795777},
{"level": 2, "resolution": 39135.75848200009, "scale": 147914381.897889},
{"level": 3, "resolution": 19567.87924099992, "scale": 73957190.948944},
{"level": 4, "resolution": 9783.93962049996, "scale": 36978595.474472},
{"level": 5, "resolution": 4891.96981024998, "scale": 18489297.737236},
{"level": 6, "resolution": 2445.98490512499, "scale": 9244648.868618},
{"level": 7, "resolution": 1222.992452562495, "scale": 4622324.434309},
{"level": 8, "resolution": 611.4962262813797, "scale": 2311162.217155},
{"level": 9, "resolution": 305.74811314055756, "scale": 1155581.108577},
{"level": 10, "resolution": 152.87405657041106, "scale": 577790.554289},
{"level": 11, "resolution": 76.43702828507324, "scale": 288895.277144},
{"level": 12, "resolution": 38.21851414253662, "scale": 144447.638572},
{"level": 13, "resolution": 19.10925707126831, "scale": 72223.819286},
{"level": 14, "resolution": 9.554628535634155, "scale": 36111.909643},
{"level": 15, "resolution": 4.77731426794937, "scale": 18055.954822},
{"level": 16, "resolution": 2.388657133974685, "scale": 9027.977411},
{"level": 17, "resolution": 1.1943285668550503, "scale": 4513.988705},
{"level": 18, "resolution": 0.5971642835598172, "scale": 2256.994353},
{"level": 19, "resolution": 0.29858214164761665, "scale": 1128.497176},
]
TILE_SIZE = 256
def get_resolution(zoom: int) -> float:
"""
获取指定层级的赤道地面分辨率(来自ArcGIS MapServer)
Args:
zoom: 缩放层级 (0-19)
Returns:
地面分辨率(米/像素)
"""
lod = next((l for l in LODS if l["level"] == zoom), None)
return lod["resolution"] if lod else 0
def get_resolution_at_lat(zoom: int, lat: float) -> float:
"""
计算指定层级和纬度的地面分辨率
Args:
zoom: 缩放层级
lat: 纬度(度)
Returns:
地面分辨率(米/像素)
"""
return get_resolution(zoom) / math.cos(math.radians(lat))
def pixel_to_ground_distance(pixels: float, zoom: int, lat: float) -> float:
"""
图上距离转实地距离
Args:
pixels: 图上距离(像素)
zoom: 缩放层级
lat: 纬度(度)
Returns:
实地距离(米)
"""
return pixels * get_resolution_at_lat(zoom, lat)
def ground_to_pixel_distance(meters: float, zoom: int, lat: float) -> float:
"""
实地距离转图上距离
Args:
meters: 实地距离(米)
zoom: 缩放层级
lat: 纬度(度)
Returns:
图上距离(像素)
"""
return meters / get_resolution_at_lat(zoom, lat)
if __name__ == "__main__":
zoom = 10
lat = 39.90923 # 北京纬度
resolution = get_resolution_at_lat(zoom, lat)
lod = next(l for l in LODS if l["level"] == zoom)
print(f"层级 {zoom} 在纬度 {lat}° 的分辨率: {resolution:.2f} 米/像素")
print(f"层级 {zoom} 的比例尺: 1:{round(lod['scale'])}")
print(f"256像素对应实地距离: {pixel_to_ground_distance(256, zoom, lat):.2f} 米")