简介:面向GIS数据处理、测绘工程及竣工图批量出图场景的shp转kml专用FME工具,可将shp格式矢量数据一键转换为带名称标注的kml文件,有效解决手工转换效率低、标注易错漏的问题。工具基于FME Desktop设计,适合有一定GIS基础、需要将项目竣工图、地块边界、道路要素等shp数据转出为可加载至Google Earth等平台的数据处理人员。资源包共11个文件,压缩包仅125KB,其中核心文件为.fmw/.fme工具模板,配套shp主数据、dbf属性表、prj投影参数、shx/sbn/sbx空间索引等标准GIS数据文件,另附运行日志样例及“输入数据必含字段属性要求”png说明图,结构清晰便于按需取用。包内置一整套“项目竣工图批量转kml”示例工程文件,用户可直接替换数据路径测试运行,通过模板快速理解名称标注字段的配置方法和转换流程,尤其适合需要批量处理多幅shp图、统一生成带标签kml的实用场景。目前已有2008人学习下载,配套博文提供详细操作说明,便于用户结合案例深入理解工具配置与排错思路。 做GIS的朋友应该都遇到过这种需求:手里拿着一堆SHP数据,甲方或合作方却要求能在Google Earth里打开,最好每个村、每个点位上还带着名称标注。我上周刚处理完一批村庄边界数据,两百多个SHP文件要统一转成KML,看着简单,实操起来各种坑:要么转出来没名字,要么中文变乱码,要么图形位置直接偏出去几百米。这篇文章就把我验证过的几种转法整理出来,重点讲含名称标注怎么做,以及有哪些容易踩的坑。
1. 先把SHP和KML这两个格式搞明白,后面才不会瞎折腾
很多人一上来就找工具按钮,其实SHP转KML这件事,问题的本质不在于“转格式”,而在于“怎么把属性信息和几何信息一起搬过去”。搞清楚两个格式的差异,后面所有操作都会有方向感。
1.1 SHP不是“一个文件”,而是一组文件
SHP格式全称是Shapefile,它是ESRI公司推出的一种矢量数据存储格式,但它的数据分散在多个后缀名不同的文件里。最基础的是三个文件:
- .shp:记录几何图形,也就是点、线、面的坐标位置。
- .shx:记录几何图形的位置索引,用来加快读取速度。
- .dbf:记录属性表,也就是每个要素的名字、面积、类型等文本和数字信息。
此外还经常伴随.prj(投影信息)、.cpg(编码信息)、.sbn和.sbx(空间索引)等文件。
之所以在这里要先说清楚,是因为我在实际项目里见过太多人只复制了一个.shp给对方,结果对方打开要么是“数据源不支持”,要么有图形没属性,名称自然也就丢了。SHP转KML这个动作,本质上就是把.shp的几何信息和.dbf的属性信息合并到一个文件里去,所以只要.dbf丢了,名称标注肯定做不了。
1.2 KML里每个要素都能带一个名字
KML的全称是Keyhole Markup Language,是一种基于XML的标记语言,最早由Keyhole公司开发,后来被Google收购,成了Google Earth的地图数据标准。它之所以适合分发查看,是因为每个地物都可以通过 标签挂一个文本名称,比如“李庄村”“监测井01号”“地块A-12”。只要转换时把SHP里的某个属性字段映射成 ,Google Earth里就能直接显示出来。
这就是“含名称标注”的具体实现路径。在SHP文件里,村庄名称存放在.dbf的某个字段里,比如“乡名”“村名”“地类名”,转换工具并不会自动知道该用哪个字段当名字,你必须在转换参数里明确指定。很多朋友转出来的KML打开后光秃秃的,原因一般就是没有指定名称字段,工具默认用了一个空字段,或者干脆没映射。
1.3 坐标系是个隐形门槛
KML对坐标系统的要求非常苛刻,它要求所有坐标必须是WGS84地理坐标系(EPSG:4326),单位是经纬度、十进制度。国内的SHP数据来源五花八门:有CGCS2000(国家大地2000)、西安80、北京54,还有各种投影坐标系,比如高斯-克吕格投影、UTM投影。如果源数据的坐标系不是WGS84,转换时要先做坐标转换,否则会出现几百米甚至上千米的偏移。
这个坑在批量转换时最隐蔽。因为如果SHP带.prj文件,部分工具会自动做投影转换;但如果.prj缺失或者坐标系识别错乱,工具可能直接用错坐标。所以第一步,永远要先确认源数据的投影信息,别跳过这个环节。
2. 工具选型:QGIS、ArcGIS、Python,划重点式对比
SHP转KML的工具很多,但真正靠谱且常用的就三条路线:QGIS导出、ArcGIS图层转KML工具、Python脚本。我在不同场景下都用过,说下选型逻辑。
2.1 三条路线的优缺点对比
| 路线 | 优点 | 缺点 | 最佳使用场景 |
|---|---|---|---|
| QGIS导出 | 免费、开源、操作直观,对编码兼容性好 | 批量处理需要配合更多操作 | 单文件或少量文件临时转换 |
| ArcGIS图层转KML | 和ArcGIS生态无缝衔接,支持符号系统输出,模型构建器可批量 | 需要授权,操作步骤偏多,依赖3D Analyst扩展 | ArcGIS重度用户、企业项目、批量流程化 |
| Python(Geopandas + GDAL / SimpleKML) | 完全可定制,几十上百个文件批量处理效率最高 | 需要会写代码,对新手有门槛 | 自动化处理、重复性流水线工作 |
我的建议是:如果你只是偶尔转一两个文件,用QGIS最快;如果单位买了ArcGIS且日常就在用,那就直接用图层转KML;如果你要处理的是几十个甚至上百个SHP,或者每天都要重复做这件事,别犹豫,写个Python脚本一次搞定。
2.2 转换前必须先做的数据清理
不管用哪个工具,转换前有一件必做的事:打开属性表,检查字段和内容。这里有几个注意点:
- 名称字段是否存在,字段类型是文本还是数字。
- 字段内容里有没有特殊字符,比如斜杠、引号、换行符。
- 是否有空值和重复值,空值会导致KML里name标签为空,不显示名称。
- 同一批次数据,字段名是否统一,方便批量操作。
数据清理的时间往往比转换本身还长,但这一步不能省。我见过有人上百个SHP全转完了,结果字段名不统一,脚本跑到一半报错,只能回头改,更费时间。
3. QGIS实操:10分钟拿到带名称标注的KML
QGIS是目前开源GIS里最成熟的一款桌面软件,对SHP和KML的兼容性都很稳定,而且免费。整个操作流程可以拆成三步:检查源数据、配置导出参数、验证结果。
3.1 加载SHP后先做三件事
打开QGIS,点击菜单栏“图层”->“添加图层”->“添加矢量图层”,选择你的.shp文件。加载之后不要急着导出,先按顺序检查三件事:
第一,看属性显示是否乱码。很多国内SHP的.dbf是GBK或GB2312编码,QGIS如果默认按UTF-8读取,中文会显示成乱码。解决办法是在“数据源管理器”里手动指定编码,比如GBK或GB2312,重新加载后再看属性表。
第二,看坐标系。在“图层”面板里右键图层,选择“图层属性”->“信息”,确认坐标参考系(CRS)。如果不是WGS84 EPSG:4326,需要在导出时做转换,或者先执行“导出”->“另存为”,把CRS切换成EPSG:4326再继续。
第三,看属性表里有没有合适的名称字段。右键图层打开属性表,找一个能代表要素名称的字段,比如“村名”“名称”“name”,记下字段名,导出时要选它。
这一步我通常还顺便检查一下几何类型,因为KML对点、线、面的处理方式不一样,如果SHP是点数据,名称标注和图标设置跟面数据完全不同,提前确认一下,后面配置参数时心里有数。
3.2 导出对话框里的关键参数配置
确认源数据没问题后,右键图层,选择“导出”->“另存为”。在弹出的对话框里按以下方式配置:
- 格式:选择“Keyhole Markup Language [KML]”。
- 文件名:设置输出路径和文件名。
- CRS:选择EPSG:4326(WGS 84)。如果源数据本身是4326,保持默认即可。
- 图层选项:找一下“NameField”这类配置项(中文版可能显示“名称字段”),选中你刚才记录的字段名。部分QGIS版本这里没有明确的NameField下拉框,这种情况下你可以先把名称字段移到属性表第一列,或者通过“图层属性”->“显示”,在“使用作为显示名称”里选好字段,再导出。
有一个很容易忽略的细节:导出KML时,建议把“Sim extend”和“Save styles”这些选项看清楚,不需要的功能别乱勾选。曾经有个同事勾了某个附加选项,导出的KML里带了一堆样式代码,体积翻了好几倍,打开后反应很慢。
3.3 用Google Earth做最终验证
KML有没有成功带上名称标注,最直接的验证方式是用Google Earth打开。如果名称显示正常,说明NameField配置对了;如果地物都在,但名字不显示,先检查是不是名称字段没设置,再检查字段内容是否为空。
验证通过后,还要重点关注一下有没有图形错位、面积丢失、多部件被拆开这种情况。我在实际转换面状数据时确实遇到过,少数复杂的MultiPolygon(多部件面)在Google Earth里显示成多个独立面片,看起来散了。遇到这种问题,可以在QGIS里用“多部分转单部分”工具做一次预处理,再导出。
4. ArcGIS路线:图层转KML工具与模型构建器批量转换
ArcGIS用户没必要再去装QGIS,直接用ArcToolbox里的“图层转KML”工具就行。这个工具的好处是可以把ArcMap的符号系统一并带到KML里,输出的视觉效果比QGIS默认导出好看。
4.1 图层转KML工具怎么填参数
在ArcToolbox中定位到“转换工具”->“转为KML”->“图层转KML”,双击打开。参数里比较需要注意的是“图层输出比例”和“输出图像尺寸”。
“图层输出比例”我一般填1000或5000,这个值越大,导出的图形越精细,但KML文件体积也会越大。不需要特别高精度的时候,填1000就够用了。“输出图像尺寸”默认是2x2,如果图层里有自定义图标或符号,按需要调整。
还需要注意,这个工具要求输入是一个图层,不是直接选择一个SHP文件路径。所以如果直接选了一个未加载的文件,工具会提示必须先添加到地图文档里。操作前记得提前把SHP加载成图层。
4.2 名称标注和图层显示表达式的关系
ArcGIS里的图层转KML,名称标注的机制和QGIS不太一样。它默认取的是图层当前“显示表达式”里设置的字段。具体操作是:
- 右键图层,选择“属性”。
- 切到“常规”选项卡。
- 在“显示表达式”区域,“按字符串显示表达式”下面选择“字段”。
- 从下拉框里选中名称字段,比如“村名”,点击“确定”。
这样设置后,ArcGIS生成的KML会把每个要素的 标签自动填上对应字段的值。如果不设置,KML就只会显示空白名称,Google Earth里看到的就是一个个图形,没有文字标注。
这里有个个人建议:如果图层出图时显示表达式还涉及到拼接,比如“名称”+“编号”,那你在生成KML时也会一并带进去。这是好事,因为很多项目数据要求在Google Earth里直接显示“村名(编号)”这种格式,一步就能到位。
4.3 用模型构建器实现批量SHP转KML
如果你的SHP按乡镇、村或者其他逻辑分成了几十个文件,一个个手点图层转KML会让人崩溃。ArcGIS的模型构建器可以用来做批处理,这也是相关搜索里“arcgis模型构建器实现批量kml文件转shp”这类需求的核心场景。
模型构建器的核心思路是“迭代要素类”工具加上“图层转KML”工具。步骤大致是:
- 在ArcToolbox里右键,选择“新建”->“模型”。
- 从工具箱里拖入“迭代要素类”工具,设置好文件夹路径和通配符类型(比如*.shp)。
- 再拖入“图层转KML”工具,把迭代器的“要素类”作为图层参数输入。
- 在“输出文件”里设置路径,用内联变量拼接文件名,比如
D:\KML_Output\%Name%.kml。 - 保存模型,点击“运行”。
这里有一个比较隐晦的坑:迭代要素类通常输出的是要素类路径,而图层转KML需要输入的是图层。直接连接时可能报错,需要在模型里加一个“创建图层”工具,把要素类转成图层,再接给图层转KML。否则模型要么报参数无效,要么输出的KML是空的。
5. Python脚本转换:彻底解决编码和批量问题
如果你和我一样,经常要处理几十个SHP文件,那Python脚本才是解放生产力的正解。用库来读SHP、生成KML,整个过程完全可控,编码问题也更好排查。
5.1 用Geopandas一条命令导出KML
Geopandas是处理地理数据最常用的Python库,底层封装了GDAL/Fiona,读取SHP和导出KML都非常方便。先安装依赖:
pip install geopandas然后写脚本,核心代码很短:
import geopandas as gpd # 读取SHP,注意encoding参数,按实际编码填写 gdf = gpd.read_file("村庄边界.shp", encoding="GBK") # 统一转成WGS84坐标系 gdf = gdf.to_crs("EPSG:4326") # 把名称字段补一下空值,防止KML里name为空 gdf["name"] = gdf["村名"].fillna("未命名") # 导出KML,指定NameField gdf.to_file("村庄边界.kml", driver="KML", layer_options={"NameField": "name"})这段代码用起来很顺手,但有两个前提:第一,你的Geopandas版本要够新,GDAL版本建议在3.2以上,老版本对KML驱动的支持不稳定;第二,导出的KML里样式比较简单,如果需要复杂样式,建议用SimpleKML手动构建。
5.2 用SimpleKML做更精细的名称标注控制
SimpleKML是一个专门生成KML的Python库,它不依赖GDAL,直接通过构造XML来生成KML,所以对样式的控制更灵活。配合pyshp读取SHP,可以实现点、线、面三种几何类型的转换。示例代码如下:
import shapefile import simplekml # 读取SHP sf = shapefile.Reader("监测点.shp", encoding="GBK") # 创建KML对象 kml = simplekml.Kml() # 遍历每一个要素 for sr in sf.shapeRecords(): name = sr.record["点号"] # 名称字段 geom = sr.shape shape_type = sf.shapeType if shape_type == 1: # 点 lon, lat = geom.points[0] pnt = kml.newpoint(name=name) pnt.coords = [(lon, lat)] pnt.style.iconstyle.icon.href = "http://maps.google.com/mapfiles/kml/paddle/red-blank.png" elif shape_type == 3: # 线 line = kml.newlinestring(name=name) line.coords = geom.points line.style.linestyle.width = 3 elif shape_type == 5: # 面 poly = kml.newpolygon(name=name) poly.outerboundaryis = geom.points poly.style.polystyle.color = simplekml.Color.blue kml.save("监测点.kml")SimpleKML最省心的部分就是中文处理,它内部直接用UTF-8编码生成XML,只要在读SHP时用正确的编码把中文内容读出来,写进KML的name标签后就不会乱码。
5.3 编码问题的根源与固定解决套路
中文乱码基本都出在SHP的.dbf文件编码上。直接编辑文本没问题,但SHP的.dbf文件没有一个绝对统一的编码标准,有的数据是GBK,有的是UTF-8,甚至还有GB2312。QGIS和ArcGIS在导入时一般会在.cpg文件里记录编码,但这个文件在很多手工拷贝的数据里是缺失的。
用Python处理时,我会先做一个自动识别逻辑:优先尝试UTF-8读取,如果报错或出现乱码,自动切换成GBK。这样一批数据丢进去,能自动适配大部分情况。如果你不想写识别逻辑,也可以先用记事本或Notepad++打开.dbf的伴生.cpg文件看一眼,但这个方法仅供参考,别太依赖。
6. 高频问题与排查技巧实录
操练过几轮SHP转KML的人,基本都会遇到下面几个问题。我把常见症状、原因和解决办法整理成一张速查表,方便你直接对照。
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| KML打开后中文全部乱码 | 读取SHP时编码识别错误 | 在QGIS数据源管理器中指定GBK;Python读取时加encoding参数 |
| Google Earth里地物有图形,但名称不显示 | 没有指定名称字段,或字段内容为空 | 在导出参数里设置NameField;给空值补默认文本 |
| 图形和底图严重偏移 | 源数据坐标系不是WGS84 | 先统一转换到EPSG:4326再导出 |
| 输出的KML文件非常大 | 要素太多或几何过于精细 | 在QGIS用简化工具处理后再转;ArcGIS调整图层输出比例 |
| 多边形出现破洞或部件丢失 | 多部件面或多环面处理不当 | 先用“多部分转单部分”或“修复几何”工具预处理 |
| ArcGIS找不到“图层转KML”工具 | 3D Analyst扩展模块未启用 | 在工具菜单里打开扩展模块,勾选3D Analyst |
除了表格里这些,我再分享一个实操心得:转换前一定要先导出一个样本文件,用Google Earth打开看一眼,确认名称、位置、样式都没问题,再批量跑剩下的。批量跑之前顺手在脚本里加个简单的几何检查,比如把那些面积为零、几何无效的要素提前标记出来,很大程度上能避免返工。
还有个小技巧:如果外业需要用手机查看KML,导出的KML可以压缩成KMZ,Google Earth和手机端的Earth Viewer都能直接打开,而且KMZ体积小很多,发送起来更方便。ArcGIS的图层转KML工具自带KMZ输出选项,QGIS导出时也可以选择KMZ格式,这一步本身不复杂,但很多人容易忽略。
我个人在实际项目中已经形成了固定流程:先检查坐标系和编码,然后根据文件数量决定走QGIS还是Python,最后导出样本验证一次。这套流程跑下来,几乎没有再因为SHP转KML的问题加过班。
本文还有配套的精品资源,点击获取