shp文件转换为KML文件 (第二版) 支持不同的坐标系、不完全支持中文属性表

文摘   2024-09-14 22:13   广东  

这个shp的中文属性表快把我逼疯了。

1 介绍

之前写的shp文件转换为KML文件,其实默认了shp文件的坐标系为wgs84。

因为KML是google开发的,而google earth只支持WGS84坐标系,所以,写入KML文件的数据必须是WGS84坐标系的数据。

最近遇到这个情况。

2 初步思路

这个情况有解决办法,检测输入文件是否是84坐标,如果不是,则先生成一个WGS84坐标的中间文件(也是shp格式),然后将这个中间文件转为KML格式。

arcgis它应该也是这样做的,只是具体的处理细节,美国人不会暴露出来给我们。但是但是,从结果倒推,acrgis大概率也是这样的处理流程。

首先检测shp是否是WGS1984坐标系。这里的检测很简单,判断WGS84的字符串是否在矢量文件的WKT中就可以实现了(思路很简单,但是存在一定的漏洞)

代码如下:

def check_is_84(file):    ds = ogr.Open(file)    layer = ds.GetLayer()    spatial_ref = layer.GetSpatialRef()
wkt = spatial_ref.ExportToPrettyWkt()
if 'WGS_1984' in wkt: return True else: return False


那非wgs84的矢量文件如何转为WGS84坐标呢?

其实之前写过类似内容。

矢量文件坐标转换:2000坐标系转换为wgs84坐标系,具体代码实现

3 中文乱码

至此,一切都很顺利。但是,但是...

在上面的矢量文件的坐标转换的代码,我们使用了gdal.VectorTranslate函数,这个函数对中文不友好!

在QGIS打开转换后的shp,它的属性表如下:

再放大一点:

这个属性表原先是中文的,现在变为乱码了。

这也是shp文件的缺点。虽然shp文件很好用,但是因为这样那样的不舒服感,使我吐槽过shp file,并且在个人使用的角度上批判过shp格式的丑陋。

KML与shp相比,优势在于...

为什么看好Geopackage而不是shapefile或Geojson



shp格式把数据分开存储,坐标点数据存放在.shp中,属性表的数据放在.dbf中,有时候二者的数量对不上直接打不开shp文件。之前写过怎么修复破损的shp

修复破损shp文件 | 工具下载 | 代码分享

4 解决思路

那现在怎么会变成乱码了呢?

经过一番排查,如果属性表数据存在中文,则gdal.VectorTranslate会把属性表数据以ISO-8859-1的编码方式存放在,dbf中

在QGIS右击转换后的shp文件,点击属性,点击Source,可以查看。

如果想单个文件的将乱码修复,则点击上面的按钮,选择GBK,然后再点击应用即可。


我们rstool处理工具,为了适配中文的属性表,必须要用编程的方法实现修复乱码问题,

这里主要关注的是.shp, .shx(索引文件)以及.dbf(数据表文件)这三个文件,因为这些是构成一个Shapefile的主要部分。

.shp, .shx是二进制文件,与编码无关。而dbf文件是我们重点的关注对象。

在坐标系转换前,我们把属性表信息读取出来,以字典的形式进行存储。等坐标系转换完成后,再把这些属性表赋予回去shp文件。

这里要判断dbf的编码格式,gbk、utf8或者其他。

我们更新一下shp转为kml的流程图,整体处理流程如下:

所以我们需要更改原先的shp2kml代码,原先的代码是直接利用ogr读取shp,顺带获取属性表数据。

如果dbf的编码是GBK,则使用dbfread库读取dbf文件;

如果dbf的编码是GBK,则改为ogr读取shp,

如果是其他类型,则不支持中文属性表,不更新保持空白。

最后将属性表赋予给kml文件

测试数据如下:一个2000坐标系的矢量文件在QGIS打开如下所示:

属性表如下:

在rstool处理完成时如下:

输入结果保存在输入结果所在的文件夹。

输入结果在google earth 打开如下。

中文属性表测试:


柏林:


至此,rstool支持不同坐标系的矢量文件转换为KML文件,且支持中文的属性表,确保中文不乱码。

今天先到这里了,如果需要rstool,还是老规则,在后台回复rstool获取链接。




remote sensing
一个专注于测绘、地信、遥感的公众号
 最新文章