MapGis点文件多属性数据快速成图

2020-12-30 09:10杨艳林刘广宁王世昌
物探化探计算技术 2020年6期
关键词:属性数据字符串字段

杨艳林, 靖 晶, 刘广宁, 王世昌

(1.中国地质调查局 武汉地质调查中心,武汉 430205; 2.中国地质大学(武汉) 环境学院,武汉 430074)

0 引言

MapGis软件是水工环地质调查中提交图件及数据库的专用软件,而图元属性是MapGis管理数据的强项,它不再是简单的纸质图形,而是图形与属性的融合,大大提升了图件的信息量与实用价值,如属性数据可为后期的空间分析、地下水水量与水质评价等方面提供数据支撑。在水工环地质调查过程中,获得了大量野外调查点及点属性的卡片(如水文地质调查中的井点卡片),包括的属性数据有:井位、井结构、井开采、井水位水质等,其数据项多达50项[1],而这些属性数据最后都要包含在管理数据库和编制图件的空间数据库中,才能进行成果提交。

通常在进行野外水工环地质测绘时,每天都会将记录的卡片数据录入到数据库中进行管理。当野外测绘完成后,在进行成果图件编制时,若采取一边投点,一边录入属性的方法,将会挤占技术人员大量宝贵的时间,而且也没有充分利用管理数据库中数据可导出再利用的特点,故非常有必要在数据库与编图之间架起一座桥梁,尤其是调查点与属性数据的关联。

在这方面,已有不少学者进行了相关研究,秦威[2]利用VC编程语言对MapGis进行二次开发,完成了属性数据的输入;汪新庆等[3]在MapGis二次开发环境下,利用VC编程语言实现了属性数据的逻辑检查,提高了图件检查验收的工作效率,并保证了数据的准确性与可靠性;张厚泉[4]利用MapGis软件中“投影变换”子系统内的“用户文件投影变换”命令实现了水井点图元批量编图;史文博[5]利用MapGis软件讨论了5种属性连接的方法;张良红等[6]利用MapGis提供的MFC类库,完成了航点生成MapGis点文件的方法。综观目前的方法主要有三种:①利用MapGis的明码文件对野外调查点进行投点,但不能将属性数据一并进行导入;②利用MapGis平台进行二次开发,但不能解决同其他软件数据的无缝转换;③利用MapGis软件提供的功能,需熟练地掌握MapGis软件,也无法完成同其他软件之间的数据共享。

目前,GIS软件产品众多,如ArcGis、MapInfo、AutoCAD、MapGis、GeoStar、SuperMap、CityStar等,不同软件平台之间的数据转换越来越频繁,特别是与MapGis数据之间的转换;而不同的GIS系统对各种地质现象的理解、描述方式、概念模型、数据结构、实现手段等互不相同,且缺少统一的数据接口,虽然可以通过一些中间文件实现互转,但极易丢失属性数据,造成GIS数据之间共享困难,形成了人力、财力上的浪费,资源得不到有效地利用[7]。闫琰等[8]在研究以直接和间接转换的方法实现ArcGis向MapGis软件的数据格式转换时,发现很难进行一次性批量转换,数据易失真,图形渲染易变样,无法实现GIS数据的无损转换;王星捷[9]以MapGis点文件的数据格式进行分析研究,并编制程序实现了MapGis点文件的读取实验,但对属性数据的处理未进行深入的研究。

鉴于此,为了充分发挥计算机的强大计算性能,从根本上解决:快速输入野外采集的属性数据、快速读取前人调查点的属性数据、MapGis多属性数据快速成图、打破不同GIS平台之间的“信息孤岛”、且不受MapGis平台限制的接口程序等方面的问题,以及有效提高成果资料的信息化和服务能力,其关键是对MapGis点文件的分析,笔者将从MapGis点文件(无TIC点)及其属性块的数据结构、存储算法和关键环节等方面进行了详细阐述,并且为了叙述的方面,对用到的数据结构、函数或算法,都以Visual C++语言的形式列出。

1 MapGis点文件

MapGis点文件是以WT为后缀名的二进制文件,主要包括空间数据与属性数据。空间数据为字符串、文本、子图、圆、弧段、图片等五种类型,参考MapGis安装目录中的baseDefine.h文件,其数据结构见表1~表6。属性数据的数据类型多达17种,常用的主要有字符串(string)、短整型(short)、长整型(long)、浮点型(float)、双精度型(double)、日期型和时间型等,属性的个数不受限制[10]。

表1 MapGis点文件中字符串的数据结构

表2 MapGis点文件中文本的数据结构

表3 MapGis点文件中子图数据结构

表4 MapGis点文件中圆的数据结构

表5 MapGis点文件中弧的数据结构

表6 MapGis中图片的数据结构

利用UltraEdit工具打开点文件,并结合MapGis软件对点文件的显示以及前人的研究[9],可将点文件存储的数据分为三个数据段:

1) 在前面的657个字节,主要用于记录点文件标识(57 4D 41 50 60 44 32 32)、地图参数(投影参数、单位及比例尺、图幅范围等)和点个数。

2) 紧接着的160字节是用于记录16个数据块的位置、长度,其中位置和长度都由4字节进行存储,后2字节是结束标记,值为-1,其数据结构如表7所示。在MapGis6.7版本中,16个数据块中目前主要使用的有5个:数据块1主要是字符串、文本、弧、圆、图片等绘制参数,每个点由93个字节组成,其数据结构见表8、表9、表10;数据块2存放的是字符串ch_struct结构中的str_text数据值,或文本text_struct结构中的str_word数据值等,其长度由表8结构中的len变量记录;数据块3是属性数据,属性数据由属性头(348个字节)、字段头(39个字节)、字段内容(为变长度,字段头中进行了定义)三部分组成;数据块4是每个点的范围数据(左下角坐标和右上角坐标);数据块5是点所在的图层和图元类型。

3)存放各数据块的数据,MapGis6.7版本中主要有5个。

表7 数据块位置数据结构

表8 MapGis点文件中点数据结构

表9 PNT_INFO_UNION数据结构

表10 D_DOT数据结构

2 MapGis点文件属性块数据结构

MapGis点文件的属性数据是各类地物特征信息的具体记录,主要用于描述实体要素的类别、特征和性质。由于各领域的专业属性差异甚大,不能用一个已知属性集描述或概括所有应用的专业属性。在水文地质调查中,记录了大量井、泉等水文地质点的属性数据,为了快速无缝地将这些属性数据加入到成果图件的空间数据库中,需准确掌握MapGis点文件属性数据的存储与读取算法,而属性数据结构是关键。

基于MapGis点文件的二进制分析,属性数据由属性头、字段头和属性数据三部分构成,属性头的数据结构(表11),占348个字节,记录的信息有:属性长度(值为426+字段数×39)、点个数、字段个数、记录长度等。为了便于理解和处理,将字段头与属性数据进行组合,其数据结构如表12所示,包括了字段名,字段类型,字段字节长度,字段字符的长度、小数位数、编辑状态,及字段值等。其中字段类型有字符串型、浮点型、长整型、短整形等10余种,字段的属性值则存放在fieldVal中。

表11 属性头数据结构

表12 字段信息数据结构

3 MapGis的点文件属性块的读写算法

为了对多属性数据进行读/写操作,将属性头数据结构(记为INFO_HEAD)与字段信息数据结构(记为FIELD_HEAD)进行组合,形成了属性块数据结构(表13)。

表13 属性块的数据结构

按照数据结构中各数据类型进行读写,在进行读写之前,需对字段分配内存空间,如fldEntry = newFIELD_HEAD[hd.numbfield];然后对属性头数据结构中的字段数据,可按fread/fwrite(&numbfield, sizeof(numfield), 1, pFile)(pFile为文件指针)进行读写操作;字段数据结构中字段名,可按fread/fwrite(fieldname, 20, 1, pFile)进行读写操作(字段名的长度不能超过20);以及字段值可按fread/fwrite(fieldVal[iField], fieldlength, 1, pFile) (iField为第几个字段)进行读写操作。

图1 野外泉点部分属性数据Fig.1 Paritial attribute data of the field springs

4 关键过程的处理

将野外调查卡片数据录入管理数据库中后,各种属性数据可直接导出为Excel或TXT文件格式。编制图件时,参考建库指南[1],筛选目标属性数据,通过类似于图1所示的交互性对话框,将目标属性数据复制到对话框上,后将其写出为所需的目标点文件。

图2 MapGis中属性结构设置Fig.2 Attribute structure settings in the MapGis

4.1 属性数据块的长度计算

为了准确写出点文件,计算属性数据块的长度十分重要,按照前面的分析,其长度可分为3个部分,属性头、字段头和属性数据,其中属性头长为348字节,字段头的长为39×字段个数(即hd.numbfield),而属性数据的长度为:数据个数╳(标识符 + 每个点数据中属性的长度)(其中标识的长度通常为一个字节),其中每个点数据的属性长度可按式1进行计算。

len=0 for (int i = 0; i

(1)

4.2 子图号与注释自动识别

在MapGis中子图号通常是用数字来进行标识,而注释通常是文字,故可依据这一点进行子图号与注释的判定。

4.3 字符串长度

在将点数据写成MapGis点文件时,若某个字段为注释,则注释的长度是变长的,图1中的地层时代,若在程序直接分配一个大大的内存来进行存储,当然是可以,但这样浪费了太多的内存空间,故需要自动识别字符串的长度。通过遍历操作地层时代,计算出该字段下的最大字符串长度,可按函数strlen(),或CString的GetLength()函数。为了处理中文的需要,常会用Unicode字符集,这时在计算字符串长度时,需利用WideCharToMultiByte函数将宽字节转变为多字节来计算字符串长度。

4.4 易被误解的地方

在使用MapGis软件编辑点文件属性结构时,常会弹出图2所示的对话框,经常会误认为字段长度就是浮点数的内存长度,其实这是一种误解。目前,在计算机内部,浮点数主要分为单精度(float)和双精度(double),其计算内存大小分别是4位和8位,有效小数位数分别是7和16。而属性结构中的字段长度是指将浮点数转为字符串时字符串的显示长度,小数位数就是字符串中显示小数的个数(图3)。

图3 浮点数内存存储及MapGis中显示对比Fig.3 Floating-point memory storage and comparison in the MapGis

4.5 小数位数及字段长度自动识别

由前面分析知,当某字段的数据类型为浮点型时,如图1中的泉流量,若直接赋为双精度类型,不会有问题,但从节约内存的角度来看,这样就有点欠妥,故需判定该字段是单精度还是双精度,并计算出浮点数的长度和小数位数等数据。这时需要遍历该字段的所有数据,按字符串形式将数据读入,计算字符串的长度,找到小数点并计算小数点位数,通过遍历找到最长字符串(记为nMaxLen,则msk_leng等于nMaxLen)和最长小数点位数长度(记为nDigit,则point_leng等于nDigit)。由于单精度浮点数的有效位数为7位,若nDigit小于7,则可赋为单精度浮点型(即fieldtype等于4,fieldlength等于4),否则为双精度浮点型(即fieldtype等于5,fieldlength等于8)。当然还需判定该数是否超过了单精度浮点数的范围(-3.4E38~3.4E38);在水工环调查中,数据通常都在单精度浮点数范围内。

图4 属性值写出过程及实例Fig.4 Attribute value writing process and example

4.6 长、短整型自动识别

短整型与长整型的主要区别是取值范围和字节大小不同。短整形所能表示的整数域为-32 768~32 767,占2字节内存;而长整型表示的整数域为-2 147 483 648~2 147 483 647,占4字节内存。若某字段数据无小数点,则为整型数,后通过遍历判断字段内的数据是否在-32 768~32 767范围内,若在范围内,则为短整型(即fieldtype等于2,fieldlength等于2),否则为长整型(即fieldtype等于3,fieldlength等于4)。

4.7 属性值快速读/写

确定了字段长度(fieldlength)后,就可以为属性值(fieldVal)分配内存,其大小为hd.num1×fieldlength。在进行属性值写出时,不能直接将属性值(fieldVal存储的)直接写出,需将属性值转换为该字段的数据类型,并按字段数据类型进行存储(图4)。若在进行属性值读入时,则是图4的逆过程。

4.8 时间、日期数据结构

通过多次MapGis软件对时间、日期数据的读入与写出,确定了时间和日期的数据结构类型分别为TIME_STR和DATE_STRU,所占内存大小分别为10字节和4字节(表14、表15)。

表14 自定义时间数据结构

表15 自定义日期数据结构

5 算法编制及实例应用

根据MapGis点文件二进制分析,尤其在点文件属性数据方面,采用面向对象可视化语言Visual C++,编制了MapGis点文件读取与写入程序,其读取过程见函数ReadMapGisWTData;并为其研发了人机交互界面(图2)。当进行点文件生成时,通过设置点数和属性数,将点数据输入到网格中,也可以直接将Excel表格中的数据复制到表格,点击“导出”即可完成。当进行点文件属性编辑时,点击“导入”即可读入已有的点文件,并将点数据显示在网格中,编辑修改后点击“导出”生成点文件。并且也提供了点文件投影参数的设置。最后,将生成的点文件加载到MapGis软件中,即可完成多属性点数据的快速成图。

通过对比分析基于交互式界面输入的点数据与MapGis中的点属性数据,结果一致,表明前面对点文件分析和程序编写的正确性(图5)。在2018年江西省清溪村幅1:50 000水文地质调查中,借助本程序,完成了井、泉、水文孔等水文地质点的属性数据从管理数据库到空间数据库的快速成图,大大提高了成图效率。

boolReadMapGisWTData(FILE* pFile)

{

ReadFileHead(pFile);//文件头- 657个字节进行读入

ReadDataHead(pFile);//数据头- 160个字节进行读入

SetSize(nLin_show);//分配数据内存空间

fseek(pFile, position[0], SEEK_SET);//子图数据

char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );

setlocale( LC_CTYPE, "chs");//读出中文

longpos = ftell(pFile);

for (inti = 0; i

{

wtData[i].ReadData(pFile, position[1]);//读取点数据

pos += 93;fseek(pFile, pos, SEEK_SET);//文件指针

}

setlocale( LC_CTYPE, old_locale); free( old_locale );//还原区域设定

fseek(pFile, position[2], SEEK_SET);

wtAttData.ReadField(pFile, nLin_show);//读取属性数据段

fseek(pFile, position[3], SEEK_SET);

for (inti = 0; i

fseek(pFile, position[4], SEEK_SET);//点图元数据段

for (inti = 0; i

{

fread(&layer[i], 2, 1, pFile); fread(&kind[i], 2, 1, pFile);

}

return 1;

}

图5 点数据写入MapGis点文件中Fig.5 Data written to the MapGis point file

6 结论与建议

1)通过对MapGis点文件的剖析,将点文件存储的数据分为三个数据段,并给出点文件中空间数据的数据结构。

2)基于点文件属性数据的分析,属性数据由属性头、字段头和属性数据三部分构成,给出了对应的数据结构,并对属性数据中各字段的读写进行了介绍。

3)针对属性数据易误解、准确写出易出错、节省内存空间等关键部分,如属性数据的长度计算、注释与子图的自动识别、常用数据类型自动识别、浮点数据类型的判定、属性数据的读入与写出、以及时间与日期数据结构等方面进行了详述,确保属性数据的准确写出。

4)利用VC++语言,研发了界面友好,使用方便、快捷、操作性强的可视化界面,明显降低了劳动强度,有效地提高了工作效率,更重要的是确保了属性数据的准确性和可靠性。

为了实现其它GIS系统的点、线、区等属性数据向MapGis的无缝转换,笔者还未对MapGis点文件中包含TIC点,以及线、区文件进行研究,这将是后面继续研究的方向。

猜你喜欢
属性数据字符串字段
带钩或不带钩选择方框批量自动换
基于文本挖掘的语词典研究
城镇地籍数据库建设过程中存在的问题和注意事项
基于GIS的房产测绘管理信息系统架构研究
无源多传感器综合数据关联算法研究
浅谈台湾原版中文图书的编目经验
属性数据分析教学改革初探
SQL server 2008中的常见的字符串处理函数
倍增法之后缀数组解决重复子串的问题
最简单的排序算法(续)