GIS中海量矢量数据的读取
在GIS应用中常常面对海量数据和有限的PC平台之间的矛盾,为此许多人设计了各种各样的数据索引和抽取机制,来实现低端PC访问海量数据之需;其实在Windows平台下,API提供了一种FileMapping机制来实现将文件映射到虚拟内存中,在内存中生成一个字节流指针(byte*)供程序访问,其实这个字节流指针没有占用到一点物理内存,而只是磁盘文件在虚拟内存中的一个映象,这样,就可以节省很多的内存空间;同时,开发人员的地物实例,也不用再到堆进里进行分配,直接把地物的首地址指向字节流中的某个地址就可以了。
以下代码实现了文件映射的初始化,生成了一个字节流指针——m_pFileBuf:
var
hf : THandle;
dwFileSize, m_dwSize : DWORD;
hMap : THandle;
m_pFileBuf : PChar;
nCurPos : integer; //当前文件指针
begin
hf := CreateFile(PChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS,0);
if(INVALID_HANDLE_VALUE <> hf) then begin
dwFileSize := GetFileSize(hf,nil);
hMap := CreateFileMapping(hf,nil,PAGE_READONLY,0,0,0);
if(hMap <> 0) then begin
m_pFileBuf := MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
if(m_pFileBuf <> nil) then begin
m_dwSize := dwFileSize;
bFileMapping := TRUE;
Exit;
end
else begin
CloseHandle(hMap);
hMap := 0;
end;
end;
CloseHandle(hf);
end;
以下是地物的XY坐标数组直接指向字节流中的某地址,Pts
TGeoObj(Data).Pts := Addr(m_pFileBuf[nCurPos]);
Inc(nCurPos, SizeOf(GEO_PT) * ObjHeader.PointCount);
经测试,本机制可以实现在物理内存只有512M的PC上(1.6G CPU,Windows 2000 Professional,10G左右的空余硬盘空间),访问5G的地图数据,读取时间只有1秒!!!!!(不要奇怪,其实根本没有花时间去读取,只是映射而已,哈,下面就要看你的制图机制的速度了,千万不要因为画图很慢而影响了读文件争取来的宝贵时间啊。:o))
参见附图的地图显示效果,为了减少图片尺寸,做成黑白色 了。