KML是严格遵循XML语法并声明OGC官方命名空间的文本文件,必须以UTF-8编码开头、使用kml 2.2命名空间、所有要素置于Placemark内、坐标顺序为经度,纬度,高度。
KML 就是带地理坐标的 XML 文件,不是“类XML”而是标准 XML
KML(Keyhole Markup Language)本质就是一份严格遵循 XML 语法、且必须声明 OGC 官方命名空间的文本文件。它不是自定义标签的简化格式,不能省略 XML 声明或乱写命名空间——否则 Google Earth 或 QGIS 会直接拒读。
必须是第一行,前面**绝对不能有空格、BOM 或换行**
第二行必须是
,用的是 KML 2.2 命名空间(当前最广泛兼容的版本)
所有地理要素(点、线、面)都必须包裹在
内,不能直接挂在
下(虽某些解析器容忍,但属非规范写法)
坐标顺序固定为
(注意:不是纬度优先),例如
用 Python minidom 手动拼出合法 KML 的关键步骤
很多人用字符串拼接写 KML,结果因引号嵌套、转义、缩进混乱导致解析失败。用
虽略 verbose,但能保证结构合法。重点不在“会不会创建节点”,而在**命名空间和子元素层级是否精准匹配 KML Schema**。
必须用
创建根节点,不能只用
是
的**唯一合法直接子元素**(KML 2.2 规范强制要求)
是
的子元素,其内容必须是纯文本节点(
),不能是子标签或属性
中文
或
需确保整个 Python 文件以 UTF-8 保存,并在 XML 声明中明确
常见解析失败错误及对应原因
不是代码报错,而是打开 KML 时 Google Earth 显示“无法读取此文件”或 QGIS 提示“无效 KML”——这类问题几乎全出在 XML 结构层面,而非地理逻辑。
Google Antigravity
谷歌推出的AI原生IDE,AI智能体协作开发
下载
→ 实际是某处
没闭合,或
写成了
(少个 s)
地标显示在赤道上或完全错位 → 坐标字符串里用了中文逗号(,)或空格分隔,应为英文半角逗号+无空格:
,不是
样式不生效(图标/颜色丢失)→
定义在
外部但未用
引用,或引用写成
却漏了开头的
文件能打开但无内容 →
被误写为
(XML 标签大小写敏感)
KML 不是万能容器,别硬塞非地理数据
KML 设计目标很明确:表达地球表面的点、路径、区域及其可视化样式。它**不支持表格数据、时间序列聚合、属性字段类型定义(如整数/日期)或空间索引**。想存“某岛2025年渔船停靠次数”,KML 只能塞进
当纯文本,无法被 GIS 工具识别为数值字段。
需要做统计分析?先转成 GeoJSON 或 Shapefile,再导入 QGIS/ArcGIS
要展示动态轨迹?用
(Google Earth 扩展),但标准 KML 解析器(如 GDAL)可能忽略
含大量图片或模型?打包成 .kmz(ZIP 压缩包),直接放
里引用相对路径即可
坐标系只能是 WGS84(EPSG:4326)——KML 没有
标签,强行写其他椭球参数会被无视
真正卡住人的,从来不是“怎么写一个点”,而是命名空间漏了冒号、coordinates 里多了一个空格、或者把
错当成可选标签。KML 的规范性比灵活性重要得多。
经度,纬度,高度-122.0822,37.4223,0xml.dom.minidomcreateElementNS("http://www.opengis.net/kml/2.2", "kml")createElement("kml")createTextNodeencoding="UTF-8"from xml.dom.minidom import Document
doc = Document()
kml = doc.createElementNS("http://www.opengis.net/kml/2.2", "kml")
doc.appendChild(kml)
document = doc.createElement("Document")
kml.appendChild(document)
placemark = doc.createElement("Placemark")
document.appendChild(placemark)
name = doc.createElement("name")
name.appendChild(doc.createTextNode("南山岛"))
placemark.appendChild(name)
point = doc.createElement("Point")
coordinates = doc.createElement("coordinates")
coordinates.appendChild(doc.createTextNode("114.321,19.876,0"))
point.appendChild(coordinates)
placemark.appendChild(point)
with open("example.kml", "w", encoding="utf-8") as f:
f.write(doc.toprettyxml(indent=" ", encoding="utf-8").decode("utf-8"))ParseError: mismatched tag"114.321,19.876,0""114.321,19.876,0"id#mystyle #.kml