用过arcmap的小伙伴经常会碰到过打开shp文件发现中文有乱码的问题。之所以会出现乱码,就是因为文件的编码方式不被软件支持或者文件编码方式不正确。
编码
ASCII编码
大家知道,计算机只能读懂0和1,也就是二进制。如果想让计算机能够看懂我们的文字,就必须进行编码,转变成计算机可以认识的格式。所以无论是文字、字母、标点符号甚至是对计算机的一系列操作,都要转变成二进制。
一开始计算机只是在美国使用,一个字节八位,从00000000-11111111,一共可以有256种组合,这么多组合应对英文的字符,绰绰有余。那么他们就把每一个字母、数字、标点符号等都编好对应的二进制编码,约定俗成。相当于做了一本字典,在这本字典里可以查看每一个字符的二进制。这就是ASCII编码,全称:American Standard Code for Information Interchange,美国信息互换标准代码。然而ASCII码只用了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。比如空格"SPACE"是32(二进制00100000),大写的字母A是65(二进制01000001)。
中文编码
英语用128个符号就够用了,但是其他国家的语言怎么办?因此ASCII编码这个标准就不能满足需求了。一开始许多其它国家都利用了ASCII编码没有的另外128位,也就是八位二进制第一位为1的二进制。但是等中国开始使用计算机后,已经没有可以利用的字节状态表示汉字。退一万步讲,即使把那256中组合全给中文,也只能有256个汉字被表示,而汉字远远不止256个。ASCII编码是一个字节表示一个字符。那如果是两个字节表示一个字节呢,这样的话理论上可以有256*256=65536个符号。这就是一开始的针对中文的编码方案GB2312,后来因为少数名族语言和繁体字等原因,又出现了GBK和GB18030。
Unicode
当时每个国家都有自己的编码方案,大家都不相互支持。因此同一个二进制数字(如10110010),在不同的编码下会被表示成不同的字符。这时有一个叫ISO组织(国际标准化组织),废了所有的地区性编码方案,重新搞了一个Unicode的集合,将世界上所有的符号都纳入其中,估计有上百万个字符。但是这里有一个问题要着重一下,Unicode只是标记着字符和码位之间的关系。这里的码位是U+开头,范围是U+000000 ~ U+10FFFF(16进制)总共有216∗17=1114112个码位。所以Unicode并不涉及字符在计算机中是如何存储的,只是为每个字符给定一个唯一的标识,既没有为每个字符指定二进制,也没有规定每个字符是几个字节存储。位置靠前的字符,一个字节就可以存储,位置最后的字符,需要三个字节存储(10FFFF=>100001111111111111111共计21位)。所以针对这样的情况就有多种编码方式。
如果定长存储,比如"A3中¥",这四个字符的Unicode编码值(十六进制)分别是2A、31、DA49、BB672C。那么他们在内存的存储方式是:

缺点就是存储和传输时浪费空间。
如果压缩存储,还是上面的字符,可以这样存储:

这样的存储方式确实减少了存储空间,但是计算机如何知道2A是一个字符,还是2A31是一个字符。
针对以上的问题,分别出现了UTF-8,UTF-16,UTF-32三种编码方案
UTF-8:一种变长的编码方案,使用 1~6 个字节来存储;
UFT-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;.
UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。
具体以上几种方式是如何编码的,这里就不详细说了。整个编码的世界大概的情况如下:

Arcgis中文编码问题
通过ArcGIS产生的shp文件,会在同一个文件夹内生成同名的.cpg文件,记事本打开这个文件显示UTF-8或者其他的编码方式,这就是显示的告诉用户这个文件具体的编码方式。同时会在头文件(dBase Header)中,包含shapefile使用的编码类型的信息,即 LDID ( Language Driver ID),它告诉应用程序用何种编码类型去正确读取它。如果LDID和.cpg冲突,LDID的优先级高于.cpg文件。
由ArcGIS生产的shp文件,即使把.cpg文件删除或者改里面的编码格式,其它软件打开都不会产生乱码,因为有LDID约束着。但是在非ArcGIS生产的shp文件,不会有LDID,中文默认基本是以GBK编码生产数据,此时如果拷贝的shp文件中没有.cpg文件,那么用ArcGIS10.2之前的版本打开不会出现乱码,因为ArcGIS10.2之前中文默认的编码方式就是GBK。但是如果用ArcGIS10.2之后的版本打开,会出现乱码,因为10.2之后的版本中文默认的编码方式就是UTF-8。
中文乱码问题解决方法
ARCGIS
在shp文件的同级目录,建立同名的.cpg文件,在文件中填写正确的编码方式,如果是GBK,就写936;如果是UTF-8,就写UTF-8。这样能够指定arcmap以什么编码方式打开shp文件,而不是用默认的编码方式打开。
QGIS
QGIS是一款比较轻量级的GIS软件,大数据量渲染速度,要比Arcmap快很多。在QGIS上可以指定数据打开的编码方式。如下图所示:

同样,在QGIS上也可以把shp文件转换成另外一种编码方式。但是一定要确保在QGIS是以正确的编码方式打开。转换方式为:右键单机图层->属性:

FME
FME是一块功能强大的数据处理和转换的软件,支持多种数据格式。在FME上也可以指定打开shp文件的编码方式。读模块加载要素后,在左侧导航栏中可以查看并设置读模块的参数。如图所示:

当然,FME也能将数据转换成其它的编码方式。利用转换器AttributeEncoder,不仅可以设置全部字段的编码方式,可以设置指定字段的编码方式。

最后,如果你尝试了许多的编码方式,中文还是不能正常显示,那就很有可能这个文件一开始就是以错误的编码方式打开,然后经过转码后(比如GBK转UTF-8)另存为一份新的文件。大家有没有觉得,编码跟GIS中的坐标系很像,无论你给这个数据指定什么坐标系,其实并没有改变数据本身的坐标,只是给它了一个标签(无论你给这个数据指定了什么编码格式,并没有改变数据内部的存储机制,只是因为不同的编码方式解析这个文件,显示的内容不同罢了)。但是如果你给这个数据指定了一个坐标系,并且把它经过坐标系转换后变成了另外一个坐标系,则数据本身的坐标已经发生了改变。(如果你给数据指定了GBK编码方式,然后以另一份编码方式保存,则数据内部的存储已经发生改变)
4210

被折叠的 条评论
为什么被折叠?



