Shape--矢量数据
一. Shape文件概述
Shapefile是由ESRI公司开发的一种矢量存储格式。Shapefile用于描述几何体对象:点,折线与多边形,属于一种矢量图形格式,它能够保存几何图形的位置及相关属性。但这种格式没法存储地理数据的拓扑信息。Shapefile通常以X与Y的方式来处理地理坐标,一般X对应经度,Y对应纬度,用户必须注意X,Y的顺序。
要组成一个Shapefile,有三个是必不可少的文件,它们分别是".shp", ".shx"与 ".dbf"文件
.shp—图形格式,主文件用于保存元素的几何实体。shp格式的矢量数据图层一般只有一个,mdb和dxf等图层会有多个。
.shx—图形索引格式。几何体位置索引,记录每一个几何体在shp文件之中的位置,能够加快向前或向后搜索一个几何体的效率。
.dbf—属性数据格式,以dBase IV的数据表格式存储每个几何形状的属性数据。
在每个.shp、.shx与.dbf文件之中,图形在每个文件的排序是一致的。也就是说,.shp的第一条记录与.shx及.dbf之中的第一条记录相对应,如此类推。此外,在.shp与.shx之中,有许多字段的字节序是不一样的。因此用户在编写读取这些文件格式的程序时,必须十分小心地处理不同文件的不同字节序。
坐标文件(.shp)用于记录空间坐标信息。它由头文件和实体信息两部分构成,如下表所示:

坐标文件的文件头是一个长度固定(100 bytes)的记录段,一共有9个int型和7个double型数据,主要记录内容见表:

注:最后4个加星号特别标示的四个数据只有当这个Shapefile文件包含Z方向坐标或者具有Measure值时才有值,否则为0.0。所谓Measure值,是用于存储需要的附加数据,可以用来记录各种数据,例如权值、道路长度等信息。
二.位序
上表中位序有Little和big的区别,通常,数据的位序都是Little,但在有些情况下可能会是big,二者的区别在于它们位序的顺序相反。一个位序为big的数据,如果我们想得到它的真实数值,需要将它的位序转换成Little即可,
下面是转换代码(big->little)(目前只有C++代码后续用到补Java代码)
int OnChangeByteOrder(int indata){ char ss[9]; char ee[8]; unsigned long val = unsigned long(indata); ultoa(val, ss, 16);// 将十六进制的数(val)转到一个字符串(ss)中,itoa(val,ss,16); int i; int length = strlen(ss); if (length != 8){ for (i = 0; i<8 - length; i++) ee[i] = '0'; for (i = 0; i<length; i++) ee[i + 8 - length] = ss[i]; for (i = 0; i<8; i++) ss[i] = ee[i]; } //****** 进行倒序 int t; t = ss[0]; ss[0] = ss[6]; ss[6] = t; t = ss[1]; ss[1] = ss[7]; ss[7] = t; t = ss[2]; ss[2] = ss[4]; ss[4] = t; t = ss[3]; ss[3] = ss[5]; ss[5] = t; //****** 将存有十六进制数 (val) 的字符串 (ss) 中的十六进制数转成十进制数 int value = 0; for (i = 0; i<8; i++){ int k; if (ss[i] == 'a' || ss[i] == 'b' || ss[i] == 'c' || ss[i] == 'd' || ss[i] == 'e' || ss[i] == 'f') k = 10 + ss[i] - 'a'; else k = ss[i] - '0'; value = value + int(k*(int)pow((DOUBLE)16, 7 - i)); } return(value); }
下面是转换代码(little->big)
// 将十进制转换成十六进制,并转成big int OnChangeByteOrderTenToSixteen(int indata){ int yushu; int i = 7; char ss[8]; if (indata == 0) return 0; while (indata > 0) { yushu = indata % 16; char k; if (yushu > 9) k = 'a' + yushu - 10; else k = '0' + yushu; ss[i] = k; indata = indata / 16; i--; } //****进行倒序 for (int j = 0; j<i + 1; j++) { ss[j] = '0'; } int t, temp; t = ss[0]; ss[0] = ss[6]; ss[6] = t; t = ss[1]; ss[1] = ss[7]; ss[7] = t; t = ss[2]; ss[2] = ss[4]; ss[4] = t; t = ss[3]; ss[3] = ss[5]; ss[5] = t; for (i = 0; i < 8; i++) { if (ss[i] != '0') { temp = i; break; } } int k; int num = 0; for (i = temp; i < 8; i++) { if (ss[i] >= 'a'&&ss[i] <= 'f') k = 10 + ss[i] - 'a'; else k = ss[i] - '0'; num = num * 16 + k; } return num; }
文章借鉴:
https://www.cnblogs.com/ParanoiaApe/p/11611319.html
https://www.cnblogs.com/fan-0802-WHU/p/10157773.html

浙公网安备 33010602011771号