我一直在编写shapefile解析库,并且在规范中遇到了一些我尚未立即理解的设计决策。我希望周围有一个老谋深算的ESRI开发人员,他可以告诉我为什么这些都是它们的样子。


主记录文件(.shp)具有混合字节序。具体来说,标头的某些部分具有大尾数字节顺序,但记录全都是小尾数。我通常在比字节和位更高的级别上工作,但是到目前为止,我所读到的有关字节序的所有内容都将其标记为异常。为什么不指定文件具有统一的字节顺序?


“文件长度”字段以及其他长度和位置字段都以16位字记录。 (从我有限的角度来看)8位定位。我是如何达成此决定的?


我在Stack Overflow上发布了类似的问题,但未得到任何回应。如果对于其他人来说这太离题了,我可以支持将其关闭。

评论

GeospatialPython.com的Joel Lawhead致力于解决Shapefile之谜已有一段时间了。

不完全相关,但整齐!我希望能弄清楚。

#1 楼

shapefile的开发与ArcView的开发同时进行,后者专门设计为独立于平台。 (实际上,这是它的败笔:依靠在独立于平台的GUI中开发的称为“ Neuron Data”的界面,它无法利用许多Windows功能。最终反映出所有系统中最糟糕的系统尽管shapefile规范从一开始就很怪异,但在此设计框架内却显得有些loop回:因为shapefile适用于许多平台,所以它们的规范不应偏向任何一个平台,因此同样令人讨厌对于所有说服力的程序员。

第二个问题似乎是基于一个不正确的假设。例如,“文件长度”字段出现在主标头中的字节偏移量24处,并且是一个(有符号的)四字节(32位)整数,因为它必须表示最大2 ^ 31- 1。它的前面是一个四字节的“文件代码”,还有五个供以后使用的四字节字段:当您保留此类空间时,您当然希望将这些字段尽可能地大些,这在当时为32位,以保持最大的灵活性。在字边界上对齐文件中的数字字段也有帮助:用于解析它们的机器级代码更容易编写,并且可以避免高层编译器可能会自动填充其STRUCT到的潜在(细微)问题与单词或双字对齐。

评论


:)正是我想要的。当我说“文件长度”字段是“以16位字记录的”时,我要说的是32位整数的值以16位字记录的文件长度。 (根据规范:“文件长度的值是文件的总长度,以16位字为单位”)。看起来它可以表示2 * 2 ^ 31-1的字节长度,看起来约为4 GB。 .shx文件中的值也是如此。看起来它应该能够支持最大2 * 2 ^ 31-1字节的文件长度。我想念什么?

– canisrufus
2012年1月18日17:28

好点-我错过了。实际上,设计可以很容易地使文件长度和偏移量(.shx文件中的指针)达到四字节字,从而将.shp文件的可能大小增加到4 *(2 ^ 31-1) (约80亿字节)。我不知道他们为什么选择两个字节的字,甚至不知道为什么他们始终使用有符号整数,而无符号整数既更合适,又提供了两倍的存储空间。

– hu
2012年1月18日在21:08



我想知道16位奇数是否与当时使用的本地int是16位的16位计算机有关。

– Mike T
2012年1月18日在22:54

@Mike总是有可能的。但是,即使是80286 PC(约1984年),本机也支持32位整数,它们使用寄存器对对它们进行算术运算。

– hu
2012年1月18日22:57

埃斯里(Esri)的一位同事说,他记得端序混合是故意的。类似于“由于跨平台问题,我们将使开发人员直接处理它”。但是,当然,这都是假的。

– mkennedy
2012年1月20日15:33

#2 楼

外面的人知道这些答案,甚至更多,但他们没有说话。

我一直在与未记录的sbn和sbx文件进行解码的团队发现了
许多古怪的东西,它们既相似,又更加奇怪。

大多数shapefile结构都是逻辑高效的,这表明ESRI开发人员会仔细考虑。就像他们有一群精明的开发人员一样,他们陷入了一个疯子。

我一直怀疑16位字是节省空间的简便方法。您会发现在处理文件时必须将16位字值保留在内存中。甚至在今天,以二进制格式计算值以节省空间的策略也很普遍。但是Mike的本地int建议也有可能。

endian-flipping太奇怪了。我没有看到一个很好的答案。

dbf格式从1960年代的dbase III格式中删除。从那时起,它已被广泛使用,并且可以以其他名称(包括foxpro和xbase)找到。进行其他任何替换尝试都过于简单,无法进行简单的矢量存储或过于专有。甚至ESRI都认为shapefile会成为一种玩具,它将使初学者转向ArcINFO,coverage和地理数据库。互联网可能与格式的腾飞有关。

我学到了很多写pyshp的知识。编写解析器是一种学习格式的绝妙方法。

评论


嗯好答案。我不明白使用16位字如何节省空间。就我的目的(在javascript中构建ArrayBufferViews)而言,它的全部工作是迫使我乘以2以获取正确的偏移量:我烧掉多余的循环没有任何好处。你会详细说明吗?

– canisrufus
2012年1月19日13:55



是的-因为他们使用带符号的整数,所以这些值的上限是32,767,因此它们可以在2字节中存储更大的数字,而不是4。如我所说,分配给16位字的值是您最终持有的值使用shapefile进行读写操作时的RAM。提出一种节省双打空间的方案(我在其他二进制格式中已经看到过)总是很丑陋和复杂。因此,他们只是坚持使用简单的数据大小值方案。

– GeospatialPython.com
2012年1月19日17:28

另外-我在最初感到难过的shx文件中发现了。 SHX文件具有用于映射到256x256整数网格的要素的边界框。此技术在索引编制中很常见,但在这么小的网格上却不常见。他们将坐标另存为1字节字符,而不是整数。这就是为什么网格只有256x256。现在,即使在1990年代,记忆力也一直很低落!当然,还有许多其他效率,例如使用索引的零件隐含分组。没错-这些技术给程序员带来了更多负担。因此,必须优先使用内存。

– GeospatialPython.com
2012年1月19日在17:38

是的,我读了你的文章。您在那件事上做得很好;)我热切期待您的最终分析。关于16位问题,我不确定您的观点是否成立。 1.在SHP和SHX文件中,没有16位字段,除非我非常误解。 2.表示16位值而不是8位值只会使可描述的长度(2 * 2 ^ 15)加倍,这可以通过使用无符号int(2 ^ 16)轻松实现。最终不会节省任何空间。

– canisrufus
2012年1月19日20:56

当您提到“内存使用情况”时,很难说出您的意思是RAM还是磁盘。在90年代初期,一个2 GB的驱动器和16-32 MB的RAM相当高端:节省一些文件空间(或网络带宽)仍然很重要。负责任的软件工程师希望仔细考虑时空权衡对他们未来客户的影响。事后看来,除非选择显然是非常无效的,否则我会给他们带来疑问的好处。

– hu
2012年1月23日19:40



#3 楼

这是我的看法。

Shapefile格式最有可能是从ARC / INFO演变而来的,其历史可以追溯到其FORTRAN / PR1ME的起源。所有ARC / INFO格式都具有此100字节的标头,并且文件代码和文件长度(例如Coverage,TIN)都具有很大的首尾性。进入Microsoft Windows市场,Shapefile格式的其余部分主要集中在PC的字节序上。

字节序之间的不断切换,大概是需要支持旧版起源,同时期望获得突破性收益进入平台。

评论


这听起来很合理。感谢您的见识!

– hu
2012年1月19日14:42

这是我最喜欢的关于字节序的猜想。现在,我们所需要的只是Dangermond发布“ ESRI全部讲述,技术版”,以查看您是否正确!

– canisrufus
2012年1月19日20:57

如果shapefile格式是从ARC / INFO格式演变而来的,则它早于v7。 1994年,当我进入ESRI时,AV2已经发布,并且正在进行ARC / INFO 7的开发工作。

– mkennedy
2012年1月20日15:30

好点,梅利塔。这个答复的症结-某些格式选择最终可能起源于Fortran-一直到原始的Arc和Info应用程序一直都是正确的。

– hu
2012年1月23日19:36

感谢@mkennedy,我删除了对v7的引用。我仍然记得原始ARC / INFO用户手册(v3..v6时代)有标头的日子,我相信这些标头取自FORTRAN代码。

–Stephen Quan
2012年1月23日在21:40

#4 楼

我一直认为,字节序分配是由两个团队组成的,一个团队在Sun Workstations上,另一个团队在PC上,直到开发过程快要结束时他们才碰面。

我很想知道真正发生了什么。

评论


我认为ESRI的协调性要强于此。确实,如果有的话,他们的软件有一种趋势,好像委员会过多参与了其设计。

– hu
2012年1月18日下午16:35

#5 楼

我想在后面的某个地方,我听到了有关dbf / foxpro起源的一些信息。
那可能只是我梦dream以求的梦想。

评论


此处讨论的.shp和.shx部件是完全独立于.dbf格式而设计的,该格式已经存在了近20年。

– hu
2012年1月18日在16:30

#6 楼

您必须了解Shapefile是20年前引入的,当时有无数种不一致且设计不良的文件格式,因此shapefile也不例外。我自己编写了一个shapefile解析器,不得不说,与shapefile(.SHP)本身相比,在解析DBF格式时遇到了更多的问题。