kmz本质是zip压缩包而非高级kml,解压时须用相对路径确保doc.kml在根目录,引用资源用相对路径,kml中坐标须为“经度,纬度”顺序且声明utf-8编码。

为什么KMZ不是“高级版KML”,而是必须用ZIP打开的压缩包
KMZ本质上就是.zip,只是后缀被改成.kmz——Google Earth写入时默认用ZIP压缩算法打包,不加密、无特殊结构。如果你双击它在Windows里看到“无法打开”,大概率是系统把它当普通ZIP识别了,自动改后缀成.zip,这时手动把.zip改回.kmz就能被GIS软件正常读取。
真正容易踩的坑是:用7-Zip或WinRAR解压KMZ后,如果选了“使用绝对路径”或勾了“保留文件夹结构”,可能导致doc.kml不在根目录,QGIS或Google Earth就找不到主KML文件,直接报错Invalid KMZ: no KML root file found。
- 解压时务必选“使用相对路径”,且确认
doc.kml(或root.kml)在压缩包最外层 - 不要重命名KML主文件;Google Earth生成的KMZ通常固定用
doc.kml,QGIS也优先找这个名字 - 图片/图标等资源必须用相对路径引用,比如
<href>images/marker.png</href>,不能写C:/temp/marker.png
QGIS里加载KMZ失败?先检查是不是坐标系和编码搞错了
QGIS 3.28+原生支持KMZ,但底层其实是先解压再读KML——所以失败往往不是格式问题,而是KML内部写的坐标或编码不兼容。常见现象是图层加载成功但要素全堆在0°,0°(赤道与本初子午线交点),或者中文标签显示为方块。
根本原因是:KML规范强制要求WGS84经纬度(<coordinates>经度,纬度,高度</coordinates>),但有些手工编辑的KML误写成纬度,经度顺序;另外KML声明的encoding="UTF-8"若缺失或错标为GBK,QGIS会按系统默认编码读,中文就乱码。
- 用文本编辑器打开解压后的
doc.kml,检查第一行是否有<?xml version="1.0" encoding="UTF-8"?> - 搜
<coordinates></coordinates>,确认每组值都是“经度,纬度”顺序(例如103.9,30.6,0),不是30.6,103.9,0 - QGIS加载时,在“数据源管理器”里勾选
Ignore axis orientation可绕过部分坐标轴翻转问题
Python批量解KMZ:别用shutil.unpack_archive,改用zipfile
shutil.unpack_archive对KMZ支持不稳定——它依赖后缀判断格式,遇到没后缀或后缀被改过的文件常抛ValueError: Unknown archive format;而zipfile直接按ZIP协议读,不管后缀是什么,更可靠。
另一个关键是:KMZ里可能有多个KML文件(比如嵌套NetworkLink),但QGIS/GEarth只认根目录下第一个.kml。所以提取逻辑得加一层筛选,而不是盲目解全部。
import zipfile
def extract_first_kml(kmz_path):
with zipfile.ZipFile(kmz_path) as z:
kml_list = [f for f in z.namelist() if f.lower().endswith('.kml')]
if not kml_list:
return None
# 取最短路径名(倾向根目录下的kml)
target = min(kml_list, key=len)
z.extract(target, '/tmp')
return f'/tmp/{target}'- 不用
glob遍历KMZ内容——namelist()才是正确API - 避免用
extractall(),防止覆盖同名资源文件;单个extract()更可控 - 提取后建议用
lxml校验KML语法:etree.fromstring(open(kml_path).read()),提前发现XML格式错误
谷歌地图不支持KMZ?那就转成KML再上传,但注意NetworkLink失效
Google Maps网页版确实不认KMZ,必须转KML才能通过“我的地图→导入”加载。表面看只是解压,实际有隐藏风险:KMZ里如果用了<networklink></networklink>动态加载远程KML或实时数据,解压成独立KML后这部分链接就断了——因为KML本身不带网络请求能力,只是静态快照。
还有个细节:Google Maps对KML大小有限制(目前约5MB),而KMZ压缩后可能才2MB,解压反而超限。这时候不能硬转,得先精简。
- 用
ogr2ogr -f KML out.kml in.kmz比手动解压更稳妥,GDAL会自动处理坐标转换和编码 - 若含大量
<groundoverlay></groundoverlay>(如自定义影像),转KML后URL路径可能失效,需手动补全绝对地址 - 上传前用
gzip -t xxx.kml快速验证XML是否良构,省得传到Google Maps才报错
KML和KMZ的边界其实很薄:一个能被记事本打开,一个得靠ZIP工具拆。但正是这个“薄”,让很多人在跨平台传递时栽在后缀、路径、编码这三处细节上。稍不注意,同一个文件在Google Earth里好好的,丢进QGIS就飘到太平洋中央。











