在File Geodatabase API 开发中,对Geometry的读取是其中最核心的内容,但不幸的是File Geodatabase API并没有提供直接对Geometry读写的类,只在Row类中提供了GetGeometry的方法来获取ShapeBuffer。
long GetGeometry(ShapeBuffer& shapeBuffer);
ShapeBuffer包含两部分,一个是shapeBuffer,用来存储Geometry的二进制内同,另外一部分是inUseLength,存储该shapeBuffer的长度。
对于shapeBuffer,我们是陌生的,因为其只是一个二进制流,并不知道其内部结构,在File Geodatabase API 的sample中只给了读写点类型数据的例子,对于更复杂的线和面并没有给出相应的例子。因此我们要读写线和面要素,必须破解这两种二进制流,转换成我们想要的线和面对象。
下面首先来看一下读取点的代码:
ShapeBuffer geometry;
double x, y;
memcpy(&x, geometry.shapeBuffer + 4, sizeof(x));
memcpy(&y, geometry.shapeBuffer + 12, sizeof(y));
通过上面的代码我们可以发现,点类型数据的坐标存储在shapeBuffer中的4-11Byte(x)和12-17 Byte(y),0-3字节没有使用。
通过对shapeBuffer的分析,此处省略一万字…。可以得到下面的几何对象的存储结构示意图:
其中点比较简单,前四位存储几何类型,点的类型为1;
线的前四位同样存储几何类型,线的类型为3,后面32为存储该集合对象的外包络矩形,分别为double类型的xmin,ymin,xmax,ymax。再后面四位存储path的个数。接下来的四位存储总的坐标个数。再后面的4*nPath为存储的是每个path的起始坐标在总的坐标中的下标。最后 8*2*nPoints位存储的坐标序列。
面和线的存储方式基本相同,将path换做ring即可。
通过上面的分析,我们就可以使用File GDB API将FileGeoDatabase中数据转换成自定义的格式了