一、UTM 区域网格概述
UTM(Universal Transverse Mercator,通用横轴墨卡托投影)区域网格是一种全球标准的投影坐标系。它将地球表面的经度划分为 60 个区域(Zone),每个区域跨越 6 个经度。
核心特点
- 单位统一:与使用度(Degrees)的地理坐标系(如 EPSG:4326)不同,UTM 网格使用米(Meters)作为单位,使得在地图上计算距离、面积和周长变得简单且精确。
- 减少变形:通过将地球分为 60 个狭窄的区域,UTM 能够最大限度地减少每个区域内的形状和面积变形。
关键参数
- UTM Zone(区域编号):范围从 1 到 60。
- UTM South(南半球标识):布尔值,用于区分该区域位于北半球还是南半球。
二、实现思路
本方案使用 QGIS 的 Python 接口(PyQGIS)生成全球 UTM 区域网格的内存多边形图层。主要步骤如下:
- 创建内存图层:基于 WGS84 地理坐标系(EPSG:4326)创建多边形图层。
- 定义属性字段:记录每个区域的编号、中央经线、经度范围、半球及对应 EPSG 代码。
- 生成区域面:遍历 60 个区域,每个区域按北半球(0°–84°)与南半球(−80°–0°)生成两个独立多边形,共 120 个面。
- 设置样式:半透明蓝色填充 + 深蓝色边界。
- 加载到项目:将图层添加到当前 QGIS 项目。
三、完整代码
from qgis.core import (
QgsProject,
QgsVectorLayer,
QgsFeature,
QgsGeometry,
QgsPointXY,
QgsField,
QgsFields,
QgsCoordinateReferenceSystem
)
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtGui import QColor
# ============================================================
# 1. 创建内存多边形图层(WGS84 地理坐标系 EPSG:4326)
# ============================================================
layer_name = "UTM Zones"
crs_wgs84 = QgsCoordinateReferenceSystem("EPSG:4326")
layer = QgsVectorLayer(
f"Polygon?crs={crs_wgs84.authid()}",
layer_name,
"memory"
)
if not layer.isValid():
raise RuntimeError("无法创建内存矢量图层")
# ============================================================
# 2. 定义属性字段
# ============================================================
fields = QgsFields()
fields.append(QgsField("zone", QVariant.Int)) # UTM 区域编号 1-60
fields.append(QgsField("center_lon", QVariant.Double)) # 中央经线经度
fields.append(QgsField("lon_min", QVariant.Double)) # 西边界经度
fields.append(QgsField("lon_max", QVariant.Double)) # 东边界经度
fields.append(QgsField("hemisphere", QVariant.String)) # 半球:N 或 S
fields.append(QgsField("epsg", QVariant.String)) # 对应半球 EPSG 代码
provider = layer.dataProvider()
provider.addAttributes(fields)
layer.updateFields()
# ============================================================
# 3. 生成 60 个 UTM 区域,每个区域分南北半球两个多边形
# ============================================================
features = []
# 定义南北半球的纬度范围
hemispheres = [
{"code": "N", "lat_min": 0.0, "lat_max": 84.0, "epsg_prefix": "326"}, # 北半球
{"code": "S", "lat_min": -80.0, "lat_max": 0.0, "epsg_prefix": "327"} # 南半球
]
for zone in range(1, 61):
# 计算当前区域的经度范围
lon_min = -180.0 + (zone - 1) * 6.0
lon_max = lon_min + 6.0
center_lon = lon_min + 3.0
for h in hemispheres:
# 构建矩形面边界(顺时针闭合)
ring = [
QgsPointXY(lon_min, h["lat_min"]),
QgsPointXY(lon_max, h["lat_min"]),
QgsPointXY(lon_max, h["lat_max"]),
QgsPointXY(lon_min, h["lat_max"]),
QgsPointXY(lon_min, h["lat_min"]) # 闭合
]
# 创建要素
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPolygonXY([ring]))
feature.setAttributes([
zone,
center_lon,
lon_min,
lon_max,
h["code"],
f"{h['epsg_prefix']}{zone:02d}"
])
features.append(feature)
# 批量添加要素到图层
provider.addFeatures(features)
layer.updateExtents()
# ============================================================
# 4. 设置图层样式(半透明填充 + 深色边界)
# ============================================================
layer.setOpacity(0.35)
symbol = layer.renderer().symbol()
symbol.setColor(QColor(100, 180, 255, 128)) # 半透明蓝色填充
symbol.symbolLayer(0).setStrokeColor(QColor(30, 60, 120)) # 深蓝色边界
symbol.symbolLayer(0).setStrokeWidth(0.6)
# ============================================================
# 5. 添加到当前 QGIS 项目
# ============================================================
QgsProject.instance().addMapLayer(layer)
print(f"成功生成 {len(features)} 个 UTM 区域面(60 个北半球 + 60 个南半球),图层已添加到项目。")
四、关键实现说明
4.1 要点
- 半球拆分:每个 UTM Zone 生成两个独立多边形——北半球(0°–84°)与南半球(−80°–0°)。
- 总数:120 个面。
- EPSG 编码:北半球使用
32601–32660,南半球使用 32701–32760。
4.2 字段结构
zone(Int):UTM 区域编号(1–60)
center_lon(Double):中央经线经度
lon_min(Double):西边界经度
lon_max(Double):东边界经度
hemisphere(String):所在半球(N / S)
epsg(String):对应半球 EPSG 代码
4.3 经度范围计算
对第 zone 个区域:
- 西边界:
lon_min = -180 + (zone - 1) × 6
- 东边界:
lon_max = lon_min + 6
- 中央经线:
center_lon = lon_min + 3
4.4 EPSG 代码规则
- 北半球:
326 前缀 + 两位区域号,如 Zone 50N → EPSG:32650
- 南半球:
327 前缀 + 两位区域号,如 Zone 50S → EPSG:32750
五、运行结果
运行后,QGIS 图层面板中将出现 "UTM Zones" 图层,包含 120 个按南北半球分开的 UTM 区域面,每个面携带完整的属性信息(区域编号、经度范围、半球标识及对应 EPSG 代码),可直接用于后续的空间分析与投影转换。
更多代码问题,欢迎留言或联系我们。转载须注明出处。