gdb中文乱码_GDAL写入FileGDB中文属性乱码问题

GDAL库中提供了两个驱动来访问FileGDB格式,一个是基于ESRI提供的FileGDBAPI库来访问gdb,支持读写,另外一个是gdal自己写的OpenFileGDB驱动来访问,只支持读,不支持写。

本文主要是针对ESRI提供的FileGDBAAPI库的驱动来说。只用FileGDB驱动创建gdb时,再写入中文属性值时,会出现乱码,下面给出解决方案。

在FileGDB的文件夹中,有个FGdbUtils.cpp的问题,其中定义了两个函数,原型如下:

std::wstring StringToWString(const std::string& s);

std::string WStringToString(const std::wstring& s);

这两个函数的目的就是宽字节和窄字节相互转换。但是在转换过程中对于编码指定的问题导致转换结果不对,从而导致写入gdb文件中的中文属性值乱码。

下面是gdal库中对于上述两个函数的实现:

/*************************************************************************/

/* StringToWString() */

/*************************************************************************/

std::wstring StringToWString(const std::string& utf8string)

{

wchar_t* pszUTF16 = CPLRecodeToWChar( utf8string.c_str(), CPL_ENC_UTF8, CPL_ENC_UCS2);

std::wstring utf16string = pszUTF16;

CPLFree(pszUTF16);

return utf16string;

}

/*************************************************************************/

/* WStringToString() */

/*************************************************************************/

std::string WStringToString(const std::wstring& utf16string)

{

char* pszUTF8 = CPLRecodeFromWChar( utf16string.c_str(), CPL_ENC_UCS2, CPL_ENC_UTF8 );

std::string utf8string = pszUTF8;

CPLFree(pszUTF8);

return utf8string;

}

从上述代码中可以看出,GDAL库中将所有的字符串全部默认为UTF-8的编码,然后直接进行了转换,如果使用中文,且没有使用UTF-8对中文进行编码,那么再使用上述两个函数进行转换时,肯定会出现乱码问题,针对这个问题,修改上面的代码中,添加了一个配置项,类似shp文件的SHP_ENCODING配置项用于指定输入的字符编码,此处配置项名称改为FILEGDB_ENCODING,将上述两个函数修改为如下:

/*************************************************************************/

/* StringToWString() */

/*************************************************************************/

std::wstring StringToWString(const std::string& utf8string)

{

const char* pszFileGDBEncoding = CPLGetConfigOption("FILEGDB_ENCODING", CPL_ENC_UTF8);

char* pszUTF8String = NULL;

if (EQUAL(pszFileGDBEncoding, CPL_ENC_UTF8))

pszUTF8String = CPLStrdup(utf8string.c_str());

else

pszUTF8String = CPLRecode(utf8string.c_str(), pszFileGDBEncoding, CPL_ENC_UTF8);

wchar_t* pszUTF16 = CPLRecodeToWChar( pszUTF8String, CPL_ENC_UTF8, CPL_ENC_UCS2);

std::wstring utf16string = pszUTF16;

CPLFree(pszUTF16);

CPLFree(pszUTF8String);

return utf16string;

}

/*************************************************************************/

/* WStringToString() */

/*************************************************************************/

std::string WStringToString(const std::wstring& utf16string)

{

char* pszUTF8 = CPLRecodeFromWChar( utf16string.c_str(), CPL_ENC_UCS2, CPL_ENC_UTF8 );

std::string utf8string = pszUTF8;

CPLFree(pszUTF8);

const char* pszFileGDBEncoding = CPLGetConfigOption("FILEGDB_ENCODING", CPL_ENC_UTF8);

if (EQUAL(pszFileGDBEncoding, CPL_ENC_UTF8))

return utf8string;

else

{

char* pszLocalString = CPLRecode(utf8string.c_str(), CPL_ENC_UTF8, pszFileGDBEncoding);

utf8string = pszLocalString;

CPLFree(pszLocalString);

return utf8string;

}

return utf8string;

}

修改完保存,重新编译GDAL,如果使用的插件,直接编译File GDB的插件dll,将生成的ogr_filegdb.dll放到gdal的插件目录即可。

在使用的时候,设置配置项FILEGDB_ENCODING=CP936(GBK)等即可。

命令行使用:–config FILEGDB_ENCODING CP936

代码中使用:CPLSetConfigOption(“FILEGDB_ENCODING”, “CP936”)

转载自:https://blog.csdn.net/liminlu0314/article/details/55508358

你可能感兴趣的:(gdb中文乱码)