翻出原来自己做的一些研究,分享给大家吧!(MapInfo Tab/Map文件格式详解,最后有源码)(0分)

  • 主题发起人 主题发起人 吕雪松
  • 开始时间 开始时间

吕雪松

Unregistered / Unconfirmed
GUEST, unregistred user!
[h2]
MapInfo Tab 数据格式研究
[/h2]
吕雪松 2001年​
我们常说的Tab数据格式是MapInfo软件内部使用的二进制格式, 它其实是由下列一组文件构成:
1,.TAB,ASCII码格式的表结构定义文件;
2,.DAT,二进制格式的属性数据文件;
3,.MAP,空间图形数据存储文件;
4,.ID,与map相关的文件;
5,.IND,二进制格式的索引文件;
这其中,dat文件其实就是dBASE IV文件(和Shape文件类似),id文件中的32位整形ID号其实就是完成将图形对象和属性数据一一对应,这些都很好解决,最关键的难点在.Map文件。
经过参考多种零零碎碎的资料,又经过自己的悉心研究(方法很土,就是用UltraEdit打开二进制看,再用VC试编代码,一点点地积累),最后终于算是搞定了。
先从简单的方向来说吧,Map文件是由“块”(Block)来构成的,每一个块都是512(0x200h)的整数倍。说一种最简单的情况吧,第一个“块头”是二个常规块的大小:512*2=1024字节,其余的块都是512字节大小。
0x00000h---------------------------------------------------
Header Block 1024个字节
0x00400h---------------------------------------------------
Object Coordinate Definition Block 512个字节
0x00600h---------------------------------------------------
Coordinate Definition Block 512个字节
--------------------------------------------------------------
其它Block 512个字节
--------------------------------------------------------------
以下是一个Map文件片断的示例:
00000000h: 00 0A 0E 15 0E 16 1B A2 A6 AB 1A 2A 2F A5 A9 B5
.......ⅵ?*/ォ?
00000010h: A7 B5 D9 0F 17 23 13 1F 2B 0F 17 23 4F 57 63 9C
У?.#..+..#OWc?
00000020h: A4 A9 A0 A8 AD A4 A8 AD 16 1A 39 0D 11 37 A5 A9
ぉ牗?ō..9..7ォ 0x000~0x3FF,头块
00000030h: B5 A4 A8 AD B2 B6 DC BD BD F4 00 00 00 00 00 00
丹ō捕芙紧......

00000400h: 02 00 26 00 7D F4 01 00 3F AB 01 00 00 06 00 00
..&.}?.??.....
00000410h: 00 06 00 00 08 01 00 00 00 08 06 00 00 18 00 00
................ 0x400~0x5FF,地物定义
00000420h: 00 D2 A1 09 00 FC 77 FA FF 38 FD F7 FF FC 77 FA
.摇..黽?8?
 
直奔主题吧!怎么从Header Block开工读取呢?
别急,先还是来看几个基本的类型定义吧!
struct LongMBR
{
int nMinX, nMinY,nMaxX,nMaxY;
};

struct ShortMBR
{
__int16 nMinX, nMinY,nMaxX,nMaxY;
};
这是TAB文件的两种整型精度的外接矩形定义。
接下来看一个大的结构:
struct HeaderBlock{
byte ObjectLengthArray[52];
//000h - 033h
byte Fill[204]; //034h - 0FFh

int MagicCooki;
//100h 42424242
WORD wVersion; //104h
WORD wBlockSize; //106h
double dCoord2DistUnits; //108h
LongMBR FileMBR, defaultView; //110h, //120h
int nFirstIndexBlock;
//130h
int nFirstGarbageBlock;
//134h
int nFirstResourceBlock;
//138h
int nPointCount; //13Ch
int nLineCount; //140h
int nRegionCount; //144h
int nTextCount; //148h
int nMaxCoordBufSize;
//14Ch
byte UnknownA[14]; //140h
byte bDistUnitsCode;
//15Eh
byte bMBR_ResBlockFlag;
//15Fh
byte bCoordPrecision;
//160h Value:6 for Lat/Long maps
//Value:8 for Cartesian maps
//Value:1 for Projected maps
byte bCoordOriginQuadrant;
//161h
byte bReflectXAxisCoord;
//162h
int nObjLenArraySize;
//163h
int nPenDefs; //164h
int nBrushDefs; //165h
int nSymbolDefs; //166h
int nFontDefs; //167h
int nResourceBlocks;
//168h
byte bUnknown; //16Ch
byte bProjectionCode;
//16Dh
byte bDatumCode; //16Eh
byte bProjectionUnitsCode;
//16Fh
double dXScale,dYScale,dX0,dY0;
//170h
double ProjParms[6];
//190h
double DatumParms[7];
//1C0h
double AffineParms[6];
//1F8h
}
这个结构就是Header Block对应到Map文件的内容,意思也应该很好理解吧,看变量名称就差不多知道了。大家一个个去对吧,会对死人的。其实除了几个比较重要的数值以外,其余的大部分都没什么用(是我觉得没什么用,估计MapInfo的人还是很有用的)。
0x100h 的那个整形,总是42424242,是不是和Shape的那个9999一样暗藏什么秘密?不知道,反正每个Map文件都是一样的,我就用它来判断文件是否是有效的Map文件。
0x104h 文件版本,如500,注意不是MapInfo的版本号,二者大多数情况下都是不同的。
0x106h 块尺寸,通常都是0x200h(我没见过不是0x200h的)
0x110h 全图外接尺寸,很有用,不用一个个去算。
0x13ch 这以下的几个值很有用,加起来就是地图中的地物总数;
我还有些不知道怎么用,只是读出来放在那里。
读好了文件头,下面先试试读地物吧。
地物定义是在Object Definition Block块中定义的,开头字节为0x0002h,看看下面的结构定义:
struct ObjectBlock {
WORD BlockCode; //总是2,并且通常位于0x00400h
WORD ByteCount; //标明地物定义的长度,这个字节数是从object链表的第一个字节算起的。
int BlockOrigX; //没有用到的
int BlockOrigY;
int CoordBlockStartNumber;
int CoordBlockEndNumber;

object Objects[…] //地物链表
}
说到地物这部分就复杂了,先看一下地物类型定义表吧。这不是我的功劳,而是摘自著名的《http://spatialnews.geocomm.com/features/mif_format/#bl3》
---------------------------------------------------------------
ShortPoint [ID 1] (length: &HA): [?]
&H0 1 1 Identifier (Value: &H1) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 2 2 Coordinate value
&H9 1 1 Symbol type number from Resource Block

LongPoint [ID 2] (length: &HE):
&H0 1 1 Identifier (Value: &H2) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 2 Coordinate value
&HD 1 1 Symbol type number from Resource Block

ShortLine [ID 4] (length: &HE):
&H0 1 1 Identifier (Value: &H4) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 2 Coordinate value
&HD 1 1 Line type number from Resource Block

LongLine [ID 5] (length: &H16):
&H0 1 1 Identifier (Value: &H5) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 4 MBR
&H15 1 1 Line type number from Resource Block

ShortPolyline [ID 7] (length: &H1A):
&H0 1 1 Identifier (Value: &H7) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of coordinate data in Coordinate Definition Block
&H9 4 1 Bytes to read for coordinates from Coordinate Definition Block [?]
&HD 2 2 Label location coordinates
&H11 2 4 MBR
&H19 1 1 Line type number from Resource Block

LongPolyline [ID 8] (length: &H26):
&H0 1 1 Identifier (Value: &H8) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of coordinate data in Coordinate Definition Block
&H9 4 1 Bytes to read for coordinates from Coordinate Definition Block [?]
&HD 4 2 Label location coordinates
&H15 4 4 MBR
&H25 1 1 Line type number from Resource Block

ShortArc [ID 10] (length: &H16):
&H0 1 1 Identifier (Value: &HA) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 2 MBR of defining ellipse
&HD 4 2 MBR of the arc
&H15 1 1 Line type number from Resource Block

LongArc [ID 11] (length: &H26):
&H0 1 1 Identifier (Value: &HB) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 4 MBR of defining ellipse
&15 4 4 MBR of the arc
&H25 1 1 Line type number from Resource Block

ShortRegion [ID 13] (length: &H25):
&H0 1 1 Identifier (Value: &HD) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of coordinate data in Coordinate Definition Block
&H9 4 1 Bytes to read for coordinates from Coordinate Definition Block [??]
&HD 2 1 Section count
&HF 4 2 Label X,Y
&H13 4 4 MBR
&H23 1 1 Line type number from Resource Block
&H24 1 1 Brush type number from Resource Block

LongRegion [ID 14] (length: &H29):
&H0 1 1 Identifier (Value: &HE) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of coordinate data in Coordinate Definition Block
&H9 4 1 Bytes to read for coordinates from Coordinate Definition Block [??]
&HD 2 1 Section count
&HF 4 2 Label X,Y
&H17 4 4 MBR
&H27 1 1 Line type number from Resource Block
&H28 1 1 Brush type number from Resource Block

ShortText [ID 16] (length: &H27)
&H0 1 1 Identifier (Value: &H10) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of text body in Coordinate Definition Block
&H9 2 1 Number of characters in text body
&HB 2 1 Justification spacing arrowtype:
flag 2^1 - centered text
flag 2^2 - right aligned text
flag 2^3 - line spacing 1.5
flag 2^4 - line spacing 2.0
flag 2^5 - label line: simple
flag 2^6 - label line: arrow
&HD 2 1 Text rotation angle (0.1 degrees)
&HF 1 1 FontStyle #1:
flag 2^0 - bold text
flag 2^1 - italic text
flag 2^2 - underlined text
flag 2^3 - overlined text
flag 2^4 - unknown
flag 2^5 - shadowed text
&H10 1 1 FontStyle #2:
flag 2^0 - box background
flag 2^1 - halo background
flag 2^2 - All Caps
flag 2^3 - Expanded
&H11 3 1 Foreground color
&H14 3 1 Background color
&H17 2 2 Arrow endpoint coordinates
&H1B 2 1 Height
&H1D 1 1 Font name index
&H1E 2 4 MBR
&H26 1 1 Pen type from Resource Block

LongText [ID 17] (length: &H32)
&H0 1 1 Identifier (Value: &H11) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 Offset of text body in Coordinate Definition Block
&H9 2 1 Number of characters in text body
&HC 2 1 Justification spacing arrowtype:
flag 2^1 - centered text
flag 2^2 - right aligned text
flag 2^3 - line spacing 1.5
flag 2^4 - line spacing 2.0
flag 2^5 - label line: simple
flag 2^6 - label line: arrow
&HD 2 1 Text rotation angle (0.1 degrees)
&HF 1 1 FontStyle #1:
flag 2^0 - bold text
flag 2^1 - italic text
flag 2^2 - underlined text
flag 2^3 - overlined text
flag 2^4 - unknown
flag 2^5 - shadowed text
&H10 1 1 FontStyle #2:
flag 2^0 - box background
flag 2^1 - halo background
flag 2^2 - All Caps
flag 2^3 - Expanded
&H11 3 1 Foreground color
&H14 3 1 Background color
&H17 4 2 Arrow endpoint coordinates
&H1F 1 4 Height
&H20 1 1 Font name index
&H30 4 4 MBR
&H31 1 1 Pen type from Resource Block

ShortRectangle [ID 19] (length: &HF):
&H0 1 1 Identifier (Value: &H10) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 2 4 MBR
&HD 1 1 Line type number in Resource Block
&HE 1 1 Brush type number in Resource Block

LongRectangle [ID 20] (length: &H17):
&H0 1 1 Identifier (Value: &H17) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 4 MBR
&H15 1 1 Line type number from Resource Block
&H16 1 1 Brush type number from Resource Block

ShortRoundRectangle [ID 22] (length: &H13):
&H0 1 1 Identifier (Value: &H16) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 2 1 XRadius
&H7 2 1 YRadius
&H9 2 4 MBR
&H11 1 1 Line type number from Resource Block
&H12 1 1 Brush type number from Resource Block

LongRoundRectangle [ID 23] (length: &H1F):
&H0 1 1 Identifier (Value: &H16) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 1 XRadius
&H9 4 1 YRadius
&HD 4 4 MBR
&H1D 1 1 Line type number from Resource Block
&H1E 1 1 Brush type number from Resource Block

ShortEllipse [ID 25] (length: &HF):
&H0 1 1 Identifier (Value: &H1A) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 2 4 MBR
&HD 1 1 Line type number from Resource Block
&HE 1 1 Brush type number from Resource Block

LongEllipse [ID 26] (length: &H17):
&H0 1 1 Identifier (Value: &H1A) [!]
&H1 4 1 RowID - Validity: (+0 = Valid;
+&H40000000 = Deleted)
&H5 4 4 MBR
&H15 1 1 Line type number from Resource Block
&H16 1 1 Brush type number from Resource Block

看晕菜了吧,也可以先看一下这个定义,比较简单一点:
Feature Object Codes
------- ------------
Point 1, 2
Line 4, 5
PolyLine 7, 8
Arc 10, 11
Region 13, 14
Text 16, 17
Rectangle 19, 20
RndRect 22, 23
Ellipse 25, 26
MultiPline 37, 38
TrueTypeSymbol 40, 41
CustomSymbol 43, 44
LargeMultiPline 46, 47
LargeRegion 49, 50

注意Object Codes这部分有两个数字,一般来说,前一个数字是ShortInt类型,双字节,后一个是长整型,四个字节。

实践一下,看一个例子吧:

00000400h: 02 00 24 00 BE 63 06 00 EF E7 00 00 00 00 00 00
..$.綾..镧......
00000410h: 00 00 00 00 05 01 00 00 00 FA 1D 10 00 F4 D1 07
.........?..粞.
00000420h: 00 82 A9 FC FF EA FD F9 FF 00 02 02 00 00 00 23
.偐?挲?......#
00000430h: 92 21 00 C3 B3 FE FF 01 00 00 00 00 00 00 00 00
?.贸?.........
00000440h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................

这是一个很简单的Map文件Object Definition Block,包含了一个单直线(两个点)地物和一个点地物。
第1和2个字节02 00 = 2表明这是一个Object Block,第3和第3字节24 00 = 36表明从0x00414h开始往后36个字节包含了所有定义的地物。0x00414h一个字节05表示这是一个单直线,0x00415h往后的一个整形值01 00 00 00 = 1,表示这是一个和DAT文件中第1条属性记录相对应。然后从0x00419h开始往后,每四个字节是一个整形的坐标值,代表了一个LongMBR外接矩形,对于一个只有二个点的单直线来说,这也就能描述它的所有点坐标了。MBR到0x00428h为止,再往后0x00429h的一个字节 00代表的是线型.再往后0x0042Ah的02就是代表下一个地物,点地物开始了。再往后的四个字节的2代表这是DAT表中的第二条记录。
 
好帖要支持,谢谢!!!!!!
 
顶一下!
有个问题,关于《基于OOP的串行口类实现》,我有个问题,麻烦您有时间赐教一下,谢谢!
http://www.delphibbs.com/keylife/iblog_comment.asp?xid=1588

我把内容直接拷到这里了:

2003-7-15 22:52:32 real_clq 发表评论。
我觉得串口不难,还是直接用好一些.

2003-7-16 12:37:43 吕雪松 发表评论。
你说得没错,串口通讯本身不难,你要么自已写,要么用控件,轻松搞定。我本文的意思不是强调串口通讯本身,而是侧重于串口数据语义簇的解析与包装。这可能是与我们的业务有关,如果你永远仅仅是和一种设备一种通讯协议打交道,那么你根本没必要象我这样考虑问题,而我们的业务中有4五种设备,每种设备又有1到多种通讯协议,在编写一个灵活健壮的接口的时候就会有代码重用和平行开发的需求。那么,用OOP的方式是非常好的解决方案。

注:其实我们的这个类包括了串口和网络通讯接口,也就是说,无论是串口、并口还是TCPIP、IPX、HTTP等协议,都可以从此TGeoComm基类继承并实现新的接口。

2007-11-28 11:26:58 skyjacker 发表评论。
现在 TGeoComm 还能满足你的要求吗?

“串口、并口还是TCPIP、IPX、HTTP等协议”放在哪一层?
 
后退
顶部