KML转SHP完整指南:坐标系、属性与几何验证
简介这份资源是面向GIS从业者与地理信息相关专业学生的KML转SHP自定义工具箱基于ArcGIS平台的Python语言开发用于解决Google Earth数字化得到的KML/KMZ矢量数据无法直接在GIS平台中使用的问题。将其添加到ArcGIS自定义工具箱后双击即可运行无需编程基础非专业用户也能快速完成格式转换。压缩包共5个文件约158KB包含两个tbx工具箱文件分别适配不同ArcGIS版本、一份Python源码脚本、一份安装指南PDF以及一份工具箱定位说明PPT兼顾直接使用与源码学习两种需求。目前已有2717人学习下载说明该工具在实际工作中具有较高的实用价值。读者既能获得开箱即用的转换工具也能通过源码与安装文档理解其实现逻辑便于后续按需修改或排查运行中的问题适合需要频繁处理KML与SHP互转的GIS学习与研究人员。1. kml 转 shp 这件事卡住你的往往不是格式本身你手里大概率有一份从地图上导出的 kml——可能是现场跑的路线、可能是划定的地块边界、也可能是别人发来的标注点。打开 QGIS 或 ArcGIS 想直接分析发现统计公里数、做渔网分割、叠加行政区划边界这些操作全都要 shp 才能顺畅跑起来。于是你搜到了「kml 格式转 shp 格式神器.zip」这类工具包想找个能双击就用的东西。先说结论kml 转 shp 本身不难难的是转完之后坐标系对不对、属性字段丢没丢、面要素有没有自相交。我见过太多人转完发现路线公里数算出来差一倍或者面要素在 ArcGIS 里报几何错误回头查半天才发现是坐标系没投影。这篇就把这条链路拆开讲清楚kml 和 shp 到底差在哪、用哪些工具转、参数怎么设、转完怎么验证、哪些坑一定会踩。适合手里有 kml 要落地成可分析矢量数据的测绘、规划、GIS 数据处理从业者新手跟着命令能跑通熟手能直接看参数边界和排错思路。2. 先搞懂 kml 和 shp 的底层差异再谈转换2.1 一个是 XML 文本一个是二进制多文件组合kml 本质是 XML用标签描述几何和样式一个文件里可以同时装点、线、面、文件夹层级、颜色、图标、甚至时间戳。它天生是给地球浏览器看的坐标系固定用 WGS84 经纬度EPSG:4326单位是度。shp 是 Esri 定义的一套二进制格式而且它不是单个文件——至少要有 .shp几何、.shx索引、.dbf属性表三个缺一个就打不开。shp 本身不绑定坐标系坐标系信息存在 .prj 文件里可以存投影坐标比如 UTM、高斯克吕格单位是米。这个差异直接决定了转换时的第一个决策你要转成经纬度的 shp还是投影后的 shp如果后续要算路线公里数、做面积统计、跑渔网分割必须转成投影坐标系否则按度算出来的长度没有物理意义。2.2 转换时到底丢了什么kml 里的样式颜色、线宽、图标、文件夹层级、描述弹窗shp 的 .dbf 字段类型有限文本、数字、日期装不下嵌套结构。所以转换过程一定会丢东西关键是你要保住几何和关键属性。常见做法是把 kml 的 name 和 description 映射到 shp 的属性字段样式直接放弃需要的话在 QGIS 里重新配符号。如果你用的是带 Folder 层级的 kml转换工具一般会把层级压平所有要素进同一个 shp这时候要提前想好怎么区分——通常靠 name 字段或者额外加一列来源标识。2.3 工具选型别迷信「神器」看你的场景「神器.zip」这类打包工具通常是某个命令行工具或 Python 脚本的封装核心能力无非几种GDAL/OGR 的 ogr2ogr、QGIS 的另存为、ArcGIS 的 KML 转图层、或者 pyshp fastkml 自己写脚本。选型逻辑很简单场景推荐工具理由单文件、偶尔转QGIS 拖进去另存为零配置能预览几何批量、要写进流程ogr2ogr 命令行可脚本化参数可控要投影算长度QGIS/ogr2ogr 投影步骤必须显式指定目标 CRS点要素带大量属性Python pyshp/fiona字段映射灵活面要素有自相交转换后必须做几何修复任何工具都救不了脏数据我一般会先拿 QGIS 打开 kml 看一眼几何类型和坐标系确认没问题再决定用哪条路径。直接上命令行不看数据翻车概率很高。3. 用 ogr2ogr 把 kml 转成 shp完整命令与参数拆解3.1 最小可用命令假设你有一个 routes.kml里面是几条路线想转成 shpogr2ogr -f ESRI Shapefile routes.shp routes.kml这条命令的逻辑-f 指定输出格式为 ESRI Shapefile第一个参数是输出文件名第二个是输入 kml。ogr2ogr 会自动读取 kml 里的几何类型生成对应的 .shp/.shx/.dbf/.prj。但这里有个坑如果 kml 里同时有点和线ogr2ogr 默认只会处理第一种几何类型后面的会被跳过。所以转换前一定要确认 kml 里是不是单一几何类型。3.2 指定图层和几何类型kml 里的 Folder 在 OGR 看来是图层。先列出所有图层ogrinfo routes.kml输出会列出 Layer name。假设图层名是 RouteLayer只转这一层ogr2ogr -f ESRI Shapefile routes.shp routes.kml RouteLayer如果 kml 里混了几何类型可以强制指定ogr2ogr -f ESRI Shapefile -nlt LINESTRING routes.shp routes.kml-nlt 参数指定几何类型可选 POINT、LINESTRING、POLYGON、MULTILINESTRING 等。这个参数在数据脏的时候特别有用但要注意强制转换可能丢要素转完必须核对数量。3.3 坐标系处理从 WGS84 到投影坐标kml 进来是 EPSG:4326。如果直接输出shp 的 .prj 就是经纬度。要算公里数得投影。以 UTM 50N 为例覆盖中国东部ogr2ogr -f ESRI Shapefile -t_srs EPSG:32650 routes_utm.shp routes.kml-t_srs 指定目标坐标系。EPSG:32650 是 UTM zone 50N单位米。转完之后在 QGIS 里用字段计算器算长度$length 出来的就是米。选哪个投影带取决于你的数据位置。中国常用高斯克吕格 3 度带或 6 度带EPSG 代码需要查对应带号。拿不准就用 QGIS 的「测量工具」先量一段已知距离验证投影对不对。3.4 属性字段映射与编码kml 的 name 和 description 默认会进 .dbf。如果中文乱码加编码参数ogr2ogr -f ESRI Shapefile -lco ENCODINGUTF-8 routes.shp routes.kml-lco 是图层创建选项ENCODINGUTF-8 保证中文正常。如果还是乱码检查源 kml 的实际编码有些导出工具写的是 GBK 但没声明。字段名超过 10 个字符会被截断这是 shp 格式的硬限制。如果 name 字段很重要转换前在 kml 里改成短名或者转完后在 QGIS 里重命名。3.5 批量转换脚本一个目录下几十个 kml写个循环#!/bin/bash for f in *.kml; do base${f%.kml} ogr2ogr -f ESRI Shapefile -t_srs EPSG:32650 \ -lco ENCODINGUTF-8 ${base}.shp $f echo done: ${base} done逻辑说明遍历当前目录所有 .kml去掉扩展名作为输出名统一投影到 UTM 50NUTF-8 编码。echo 用来确认每个文件处理完成。如果某个文件失败ogr2ogr 会报错但循环继续建议加|| echo fail: $f记录失败项。参数上唯一要改的是 -t_srs根据你的数据区域换 EPSG 代码。批量场景下不建议加 -nlt让工具自动判断更安全。4. QGIS 图形化转换适合不想碰命令行的人4.1 拖进去、另存为、选坐标系打开 QGIS把 kml 直接拖进图层面板。右键图层 → 导出 → 保存要素为。格式选 ESRI Shapefile文件名填好CRS 那里点「选择 CRS」搜 32650 或者你需要的投影带。这里有个细节QGIS 默认可能勾选「添加保存的文件到地图」转完直接能看到结果方便核对。编码选 UTF-8。图层名如果为空手动填一个英文名否则可能生成一堆 unnamed 文件。点 OK 之后QGIS 会在目标目录生成 .shp/.shx/.dbf/.prj 四个文件。如果只看到 .shp 一个说明其他文件被系统隐藏了不是没生成。4.2 转完立刻验证几何和坐标系在 QGIS 里右键新图层 → 属性 → 信息看 CRS 是不是你选的投影。然后打开属性表核对要素数量和字段。再右键 → 打开属性表 → 切换到「字段计算器」新建一个字段算长度$length如果单位显示是米且数值合理说明投影对了。如果出来是 0.00x 这种小数说明还是经纬度投影没生效。4.3 面要素的自相交检查kml 里的面经常有自相交或者环方向不对。QGIS 里用「矢量 → 几何工具 → 检查有效性」跑一遍。报错的要素可以用「修复几何」处理但修复可能改变形状重要数据要人工核对。如果面要素要用来做渔网分割或叠加分析自相交必须清零否则后续空间分析会报拓扑错误或者结果缺失。这一步没有捷径只能逐个检查。5. 转换后必做的三项验证与常见翻车排查5.1 要素数量对不上现象kml 里明明有 20 个点转完 shp 只有 15 个。原因kml 里混了几何类型或者有些要素在 Folder 层级里没被选中。ogr2ogr 默认只处理第一个图层的第一种几何类型。解决先用 ogrinfo 列出所有图层和几何类型确认数据构成。如果是多图层逐个转再合并如果是混合几何分两次转一次 -nlt POINT一次 -nlt LINESTRING最后在 QGIS 里合并图层。5.2 中文属性乱码现象.dbf 里的 name 字段显示成问号或方块。原因编码不匹配。kml 可能是 UTF-8但 ogr2ogr 默认按系统编码写 .dbf。解决加 -lco ENCODINGUTF-8。如果还不行用 QGIS 打开 .dbf 看实际编码或者在 QGIS 导出时显式选 UTF-8。ArcGIS 对 .dbf 编码更敏感必要时转成 GBK 再导入。5.3 路线公里数算出来差一倍现象QGIS 里 $length 算出来是实际距离的两倍或一半。原因坐标系没投影或者投影带选错了。经纬度下 $length 算的是度不是米。投影带选错会导致比例因子偏差。解决确认 .prj 文件里的 EPSG 代码用 QGIS 测量工具量一段已知距离对比。中国东部用 UTM 50N 或高斯 3 度带对应带号西部要换带。拿不准就查数据中心的经度范围按 6 度带公式算带号。5.4 面要素在 ArcGIS 里报几何错误现象shp 在 QGIS 里正常导入 ArcGIS 后提示「几何无效」或「自相交」。原因kml 转换过程中环方向或节点顺序不符合 Esri 的拓扑规则。解决在 QGIS 里跑「检查有效性」用「修复几何」处理。如果修复后形状变化大回到 kml 源头检查是不是导出时就带了自相交。ArcGIS 里也可以用「修复几何」工具但同样要核对结果。5.5 字段名被截断或丢失现象kml 里叫「route_name_full」的字段转完变成「route_name」。原因shp 的 .dbf 字段名上限 10 个字符。解决转换前在 kml 里把字段名改短或者转完后在 QGIS 里用「重构字段」重命名。如果字段特别多考虑转成 GeoPackage 或 GeoJSON格式限制少需要 shp 时再导出。6. 进阶把 kml 转 shp 嵌进自动化流程的几个技巧如果你不是转一次就完而是要把这一步嵌进日常数据处理流程有几个习惯能省很多事。第一永远先跑 ogrinfo 看数据。不管多急先花十秒确认图层名、几何类型、要素数量。我吃过亏直接 ogr2ogr 转完发现只出来一半数据回头查才发现 kml 里有两个 Folder。第二投影参数写成变量。批量脚本里把 EPSG 代码抽出来不同区域的数据用不同投影带别硬编码。我一般会在脚本开头定义TARGET_CRSEPSG:32650后面统一引用换区域只改一行。第三转完自动跑一遍几何检查。QGIS 有命令行工具qgis_process可以调「检查有效性」算法qgis_process run native:checkvalidity -- INPUTroutes.shp OUTPUTinvalid.gpkg这条命令会把无效几何输出到 gpkg方便后续处理。参数 INPUT 是待检查图层OUTPUT 是无效要素的输出文件。如果输出为空说明几何干净。第四保留一份原始 kml 的副本。转换过程可能丢样式、丢层级万一后面要重新映射属性原始文件是唯一的后悔药。我习惯在输出目录建一个source/子目录把 kml 原样存一份。第五属性字段映射提前规划。如果 kml 的 description 里塞了关键信息比如桩号、施工日期转 shp 前先用 Python 解析出来写成独立字段。用 fiona 读 kml、写 shp 的片段import fiona from fiona.crs import from_epsg with fiona.open(routes.kml, driverKML) as src: schema src.schema.copy() schema[properties][mileage] float with fiona.open(routes.shp, w, driverESRI Shapefile, crsfrom_epsg(32650), schemaschema) as dst: for feat in src: props dict(feat[properties]) props[mileage] 0.0 # 后续计算填充 dst.write({ geometry: feat[geometry], properties: props })这段代码的逻辑用 fiona 打开 kml复制 schema 并新增 mileage 字段创建 shp 时指定 EPSG:32650遍历要素写入。参数上 crs 决定输出坐标系schema 决定字段结构。注意 fiona 写 shp 时字段名同样受 10 字符限制mileage 刚好安全。最后说个习惯每次转完我会在 QGIS 里把 shp 和原始 kml 叠在一起看一眼确认位置重合、形状一致。这个动作花不了一分钟但能拦住大部分低级错误。希望帮到你。本文还有配套的精品资源点击获取