Shapefile 中文乱码与字段名字符截断问题分析和解决方法

本文探讨Shapefile数据格式的编码方式及其引起的中文乱码问题,并提供了解决方案,包括如何设定编码以及修复字段名截断的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、关于shapefile

        关于shapefile的局限性,可以参考这篇文章:https://blog.youkuaiyun.com/yaoxiaochuang/article/details/52465335

        Shapefile是创建于上个世纪90年代的数据格式,由于它开放易用至今仍然倍受欢迎。Shapefile文件是描述空间数据的几何和属性特征的非拓扑实体矢量数据结构的一种格式,由ESRI公司开发。

一个Shapefile文件最少包括三个文件:

        1.主文件(*.shp)、--存储地理要素的几何图形的文件。

        2.索引文件(*.shx)、--存储图形要素与属性信息索引的文件。

        3.dBASE表文件(*.dbf),--存储要素信息属性的dBase表文件。

       主文件是一个直接存取,变长记录的文件,其中每个记录描述一个实体的数据,称为shape。在索引文件中,每个记录包含对应主文件记录离主文件头开始的偏移量。dBASE表文件包含各个实体的属性特征记录。几何和属性间的一一对应关系是基于一个不重复的记录顺序代码来实现的,在dBASE表文件中的属性记录和主文件中的记录是相同顺序的。

除此之外还有可选的文件包括:

        4.空间参考文件(*.prj)、

        5.几何体的空间索引文件(*.sbn 和 *.sbx)、

        6.只读的Shapefiles的几何体的空间索引文件(*.fbn 和*.fbx)、

        7.列表中活动字段的属性索引(*.ain 和 *.aih)、

        8.可读写Shapefile文件的地理编码索引(.ixs)、

        9.可读写Shapefile文件的地理编码索引(*.mxs)、

       10.dbf文件的属性索引(*.atx)、

       11.以XML格式保存元数据(*.shp.xml)、

        12.用于描述.dbf文件的代码页,指明其使用的字符编码的描述文件(*.cpg)。

详情可以参考这篇文章:shapefile的数据结构

二、Shapefile中文乱码问题

        ArcGIS10.2之后的桌面版本ArcMAP打开之前保存的Shapefile文件,总会不时遇到中文字符出现乱码现象,这是因为新旧版本的默认编码规则变化导致:

        ArcGIS10.2.1之前版本,Shapefile根据Locale进行编码,即注册表中的My Computer\HKEY_CURRENT_USER\Software\ESRI\Desktop 10.x\下的common—codepage—dbfDefault

        ArcGIS10.2.1及之后版本,Shapefile一般是utf-8编码,ArcGIS会先读取DBF头文件LDID中的编码,然后是CPG文件,最后是CodePage

三、解决方法

        中文出现乱码的根本原因是读取文件使用的编码类型和文件实际存储的编码类型不一致。

        在ArcGIS Desktop 生产 shapefile 数据中,头文件(dBase Header)中,一般会包含shapefile使用的编码类型的信息,即 LDID ( Language Driver ID),它告诉应用程序用何种编码类型去正确读取它。

        在Shapefile的子文件中,有时我们还会发现同名 *.cpg 文件,文件中也存储了编码信息,用记事本打开,看到例如UTF-8。

        二者被ArcGIS 识别的优先顺序是,LDID 优先于 CPG文件

        shapefile是开放格式,只要了解了数据规范,完全可以脱离ArcGIS生产数据。在Windows中文语言设置下,假设你自己写代码或者使用第三方的程序生产了shapefile,默认使用 CP936(GBK)编码存储,忘记在数据头文件中约定—— “我用了936!”。如果是 ArcGIS 10.2之前的版本,那么没问题,ArcGIS 默认就是以这种方式识别,不会出现中文乱码。如果用高于 ArcGIS 10.2的版本打开这个shapefile,中文就会出现乱码,因为在缺失 LDID 和 CPG时,ArcGIS默认使用 UTF-8 来读取 shapefile。

        在shapefile文件里创建个记事本,修改为同名的*.cpg 文件,文本内容oem或者936。

四、如何检测shapefile是用什么编码

        如果不知道Shapefile的编码类型,可以使用程序检测:

        共享别人写的一个python代码:

import struct
dbf = 'D:\tShapefiles\test.dbf'
dat = open(dbf, 'rb').read(30)[29:]
id = struct.unpack('B', dat)[0] 
print(id, hex(id))

例如,得到这样的打印结果:
[b](77, '0x4d')[/b]

通过这样的 ID      编码表     中查到就是 CodelPage 936。

五、ArcGIS 10.3导出 Shapefile的字段名会被截断成3个汉字?低版本中不是至少可以存储4个汉字吗?

         这个问题仍然与编码类型有关。

        ArcGIS 10.2 以及更早的版本,ArcGIS写shapefile的时候,遇到中文默认使用Windows当前语言字符集编码(也称代码页/CodePage/OEM CodePage),例如中文一般使用的是CodePage936(GBK)。

        ArcGIS 10.2.1之后的版本,ArcGIS写shapefile的时候,默认使用的是 UTF-8 编码类型。

        这两种编码类型存储汉字所使用的字节数是不相同的, shapefile自身对字段的限制是9个字节,CP936编码的汉字通常为双字节,因此可以存储 9/2=4 个汉字;UTF-8 编码下汉字至少需要3个字节存储,因此最多只能存储 9/3=3 个汉字了。

        解决方法:

        一是使用地理数据库(GDB,SDE),放弃shapefile,避免各种截断问题。

        二是让arcgis默认用CP936编码,

    打开注册表,定位到 ‘My Computer\HKEY_CURRENT_USER\Software\ESRI\Desktop 10.x’<li>创建项 ‘Common‘, 接着在其下创建 ‘CodePage’ 项, 添加 ‘字符串’,名称: dbfDefault,健值:oem(或者 936)。

        修改完注册表之后,必须新建一个Shape文件或将已有的另存为(Export Data)新的Shape文件,才能让前面的修改生效。

        这样ArcGIS Desktop 读、写 shapefile的默认方式就将是Windows当前语言 OEM CodePage 936。

### 如何在 ArcGIS 中处理 CPG 文件 CPG 文件是一种用于指定 Shapefile 编码类型的辅助文件。当 ArcGIS 需要读取 Shapefile 的属性表时,如果没有明确的编码信息(如 LDID 或 CPG 文件),可能会导致乱码问题。以下是关于如何通过 CPG 文件解决编码问题的具体说明: #### 创建并关联 CPG 文件 1. **创建 CPG 文件** 使用记事本或其他文本编辑器新建一个纯文本文件,并将其保存为目标 Shapefile 同名的 `.cpg` 文件。例如,如果 Shapefile 名称为 `example.shp`,则应命名为 `example.cpg`。 2. **定义编码类型** 在 CPG 文件中输入对应的编码名称或编号。常见的编码有: - `936` 表示 GBK 编码。 - `utf-8` 表示 UTF-8 编码。 将该内容保存到 CPG 文件中即可[^1]。 3. **放置在同一目录下** 确保新创建的 CPG 文件 Shapefile 及其他相关文件(`.shp`, `.dbf`, `.shx` 等)位于同一目录下。ArcGIS 会在加载 Shapefile 时自动检测是否存在匹配的 CPG 文件,并依据其中的内容调整编码方式。 4. **验证效果** 打开 ArcGIS 软件,在地图文档中添加包含 CPG 文件Shapefile 数据源。此时,ArcGIS 应能够正确解析属性字段中的字符编码[^1]。 #### 注意事项 - 如果仍然存在乱码现象,请确认以下几点: - 是否已正确命名 CPG 文件对应 Shapefile 关联; - 输入的编码值是否准确无误; - 当前版本的 ArcGIS 对特定编码的支持情况。 - 不同版本的 ArcGIS 默认行为可能有所差异。例如,某些较新的版本倾向于优先采用 UTF-8 编码作为默认设置,因此建议始终提供显式的 CPG 文件以避免潜在冲突[^1]。 ```python # 示例 Python 脚本:批量生成 CPG 文件 import os def create_cpg_files(folder_path, encoding='936'): """ 在指定路径下的所有 Shapefile 自动生成 .cpg 文件 参数: folder_path (str): 存放 Shapefile文件夹路径 encoding (str): 设置的目标编码,默认为 '936' (GBK) """ for filename in os.listdir(folder_path): if filename.endswith('.shp'): base_name = os.path.splitext(filename)[0] cpg_filename = f"{base_name}.cpg" with open(os.path.join(folder_path, cpg_filename), 'w') as cpg_file: cpg_file.write(encoding) # 调用函数 create_cpg_files(r"C:\path\to\your\shapefiles", encoding='utf-8') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值