采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法
来源:互联网 发布:windows系统怎么截屏 编辑:程序博客网 时间:2024/04/29 06:30
很多GIS爱好者或ECDIS开发商在读取S57数据文件时多参考了“ISO8211lib is a C++ library for reading ISO8211-formatted files, such as SDTS and S-57 format “,S57数据NATF字段采用Unicode双字节编码国家属性字段,也就是说S57数据中只有NATF字段的解析与处理涉及了双字节数据问题,特别是NATF字段是可变长度字段,而在
ISO8211.lib的
“DDFSubfieldDefn::GetDataLength( const char * pachSourceData, int nMaxBytes, int * pnConsumedBytes )”
在处理数据长度时最初只考虑了单字节定界符 UT = 31,FT = 30,而将双字节数据当成一种错误数据处理,参考
/* We only check for the field terminator because of some buggy
* datasets with missing format terminators. However, we have found
* the field terminator is a legal character within the fields of
* some extended datasets (such as JP34NC94.000). So we don't check
* for the field terminator if the field appears to be multi-byte
* which we established by the first character being out of the
* ASCII printable range (32-127).
*/
这样会造成测算出的字段长度不正确,因为双字节的字串中的个别字节很可能会出现与界符冲突,造成数据长度错误,产生丢字问题!考虑到S57规定双字节单元定界符为(0/0) (1/15),字段定界符为(0/0)(1/14) 参见S57 3.10,实际让就是00,1F和00,1E,但在比较时,还要注意系统采用的是小尾序还是大尾序,我使用的系统环境是WINDOWS,大尾序,因此应对上述数据长度测量函数进行修改:
int DDFSubfieldDefn::GetDataLength( const char * pachSourceData,
int nMaxBytes, int * pnConsumedBytes )
{
if( !bIsVariable ) // 如果数据字段是定长字段
{
if( nFormatWidth > nMaxBytes )
{
CPLError( CE_Warning, CPLE_AppDefined,
"Only %d bytes available for subfield %s with\n"
"format string %s ... returning shortened data.",
nMaxBytes, pszName, pszFormatString );
if( pnConsumedBytes != NULL )
*pnConsumedBytes = nMaxBytes;
return nMaxBytes;
}
else
{
if( pnConsumedBytes != NULL )
*pnConsumedBytes = nFormatWidth;
return nFormatWidth;
}
}
else // 数据字段为变长字段
{
int nLength = 0;
int bCheckFieldTerminator = TRUE;
/* We only check for the field terminator because of some buggy
* datasets with missing format terminators. However, we have found
* the field terminator is a legal character within the fields of
* some extended datasets (such as JP34NC94.000). So we don't check
* for the field terminator if the field appears to be multi-byte
* which we established by the first character being out of the
* ASCII printable range (32-127).
*/
if( pachSourceData[0] < 32 || pachSourceData[0] >= 127 ) // 如果第一个字符为不可见字符,则认为数据为双字节字符集,不检查字段定界符
bCheckFieldTerminator = FALSE;
while( nLength < nMaxBytes
&& pachSourceData[nLength] != chFormatDelimeter )
{
if( bCheckFieldTerminator
&& pachSourceData[nLength] == DDF_FIELD_TERMINATOR )
break;
nLength++;
}
if( pnConsumedBytes != NULL )
{
if( nMaxBytes == 0 )
*pnConsumedBytes = nLength;
else
*pnConsumedBytes = nLength+1;
}
return nLength;
}
}
笔者认为可以这样解决(程序上文不变)
if( pachSourceData[0] < 32 || pachSourceData[0] >= 127 )
bCheckFieldTerminator = FALSE;
while( nLength < nMaxBytes)
{
if( bCheckFieldTerminator)
{
if(pachSourceData[nLength] == chFormatDelimeter)
break;
}
else
{
if(pachSourceData[nLength] == chFormatDelimeter && pachSourceData[nLength+1] == 0 )
break;
}
if(pachSourceData[nLength] == DDF_FIELD_TERMINATOR && pachSourceData[nLength+1] ) break;
nLength++;
}
if( pnConsumedBytes != NULL )
{
if( nMaxBytes == 0 )
*pnConsumedBytes = nLength;
else
*pnConsumedBytes = nLength+1;
}
return nLength;
}
实践中很好的解决了问题
第二个问题,汉字乱码
在后面的数据处理时,由于中文操作系统的汉字一般采用GB18030,也就是GBK编码,因此,在显示这些汉字时还要将NATF字段转成GBK
可以直接使用系统的转换函数:
int len = WideCharToMultiByte(54936,0,(LPCWSTR )tmpStr,m_strLength/2,tmpStr1,m_strLength,0,0);
其中54936是GB18030的CodePage代码
其实第一个问题是在处理汉字乱码问题时发现的,原来只考虑了汉字编码转换问题,而且第二个问题解决后,丢字问题才在一个偶然的时候发现,这个问题在一些商用ECDIS上也存在。
以上浅见,请大师们指正。
- 采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法
- 采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法,终极解决方案.
- 采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法-更正与补充
- java中文乱码的原因及解决方法
- 中文乱码的原因及解决方法
- Request读取中文数据乱码的原因,以及解决办法
- 采用DoGet方式提交中文,乱码产生原因分析及解决办法
- PHP中文乱码的三个原因及解决方法
- PHP中文乱码的三个原因及解决方法
- Java中文乱码原因及解决方法(转)
- Java中文乱码原因及解决方法(转)
- Java中文乱码原因及解决方法
- R 从mysql读取数据中文乱码的解决方法
- php读取mysql中文数据出现乱码的解决方法
- PHP中文乱码出现的原因及解决办法分析
- ajax中文乱码原因分析及解决方案
- ajax中文乱码原因分析及解决方案
- 关于中文乱码很透彻的分析与解决方法
- Mysql FIND_IN_SET 语句原始排序
- IM心路历程1
- 写一个函数,将两个字符串连接,即编写一strcat函数
- Numpy的tile函数
- [情感/交际] 怎么和陌生人搭讪?和陌生人搭讪的技巧经验分享
- 采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法
- 关于旋转矩阵的表示
- 8.3 参数的缺省值
- MyEclipse 2014 更改图形化编辑界面
- 开发者必备的十二大Android开发资源
- 蜘蛛们,我爱你们
- [和秋叶一起学ppt]四步搞定ppt风格标准化(笔记)
- 设计模式学习--------6.单例模式学习
- 做个测试