Fast Tile Database 简称 FTD,是一款基于c/c++开发的轻量级高性能跨平台地图瓦片数据
库,设计之初主要是用来解决全球卫星影像的存储管理。常见的存储方式包括本地磁盘以瓦
片坐标的形式规整存储碎片化的瓦片文件,或者使用常规数据库或空间数据库进行存储,但
需要对数据进行迁移或部分数据从原有数据中提取出来使用时,这些方式往往不够便捷或者
效率非常低下,如果让你把全球的数据进行备份,或者从全球的数据中提取某一个省的某几
个级别的数据单独使用时,你需要花费多久时间才能解决?FTD 以单文件的形式存储,它具
有空间范围,对瓦片数据的访问时间复杂度为 O(1),可以直接通过范围对数据进行遍历操
作,结构化的存储模式,可以充分利用磁盘的存储空间,节约储存硬件成本。
FTD 的存储结构趋向于 LSM 储存结构,在写入数据时以竟可能将缓存区的数据规整为顺序结
构写入磁盘。建议在向瓦片数据库写入数据时,遵循从左到右,从上到下的顺序。
示例数据
谷歌地球全球 2-10 级基础数据 【提取码 8888】
安装
快速开始
本章节将通过简单 c++ 示例代码告诉您如何创建文件,以及对文件进行写入、读取、更新、
删除操作,如果您对 c++ 熟悉并且有一些 GIS 基础,相信您可能仅需要花费几分钟就可以熟
悉 FTD 的操作。
#include "FTD.h"
MeFTDExtent exent
exent.MinX = -180.0;
exent.MinY = -90.0;
exent.MaxX = 180.0;
exent.MaxY = 90.0;
MeFTDZooms initZooms;
for(int zoom=0; zoom<10; zoom++)
initZooms.push_back(zoom);
MeFTDHandler* pFTDHandler = MeFTDHandler::FTDBuilder()
.setFileName("D:\\myftd.ftd")
.setExtent(exent)
.setFormat(FMT_JPEG)
.setZoomRange(0, 18)
.setInitRes(360.0 / 256.0)
.setInitZooms(initZooms)
.setOverwrite(true)
.setDescription("附加信息")
.build()
if(nullptr == pFTDHandler)
#define FTD_WGS_84_EPSG
Definition: MeFTDApi.h:12
注:创建文件以后,并不会立即打开文件。
if(nullptr == pFTDHandler)
return;
if(false == pFTDHandler->open(MeFTDHandler::WriteOnly))
return;
int nBufferSize = 0;
MeFTDTileData pBuffer = nullptr;
...获取缓存数据
MeFTDTileKey tileKey(0, 0, 0);
bool bOk = pFTDHandler->write(tileKey, pBuffer, nBufferSize);
if(bOk)
pFTDHandler->flush();
MeFTDHandler::destroyTileData(pBuffer);
pFTDHandler->close();
MeFTDHandler::destroy(pFTDHandler);
if(nullptr == pFTDHandler)
return;
if(false == pFTDHandler->open(MeFTDHandler::ReadOnly))
return;
int nBufferSize = 0;
MeFTDTileData pBuffer = nullptr;
MeFTDTileKey tileKey(0, 0, 0);
bool bOk = pFTDHandler->read(tileKey, &pBuffer, nBufferSize);
if(false == bOk)
{
MeFTDHandler::destroy(pFTDHandler);
return;
}
...读取成功,其它操作
MeFTDHandler::destroyTileData(pBuffer);
pFTDHandler->close();
MeFTDHandler::destroy(pFTDHandler);
if(nullptr == pFTDHandler)
return;
if(false == pFTDHandler->open(MeFTDHandler::ReadWrite))
return;
int nNewBufferSize = 0;
MeFTDTileData pNewBuffer = nullptr;
...获取新的瓦片数据
MeFTDTileKey tileKey(0, 0, 0);
bool bOk = pFTDHandler->updateTile(tileKey, &pNewBuffer, nNewBufferSize);
MeFTDHandler::destroyTileData(pNewBuffer);
nNewBufferSize = 0;
if(false == bOk)
{
MeFTDHandler::destroy(pFTDHandler);
return;
}
pFTDHandler->close();
MeFTDHandler::destroy(pFTDHandler);
if(nullptr == pFTDHandler)
return;
if(false == pFTDHandler->open(MeFTDHandler::ReadWrite))
return;
MeFTDTileKey tileKey(0, 0, 0);
bool bOk = pFTDHandler->deleteTile(tileKey);
if(bOk)
pFTDHandler->close();
MeFTDHandler::destroy(pFTDHandler);
//方式一
MeFTDHandler* pFTDHandler = MeFTDHandler::fromFile(“D:\\myftd.ftd”);
//方式二
MeFTDHandler handler(“D:\\myftd.ftd”);
handler.open(打开模式);
追加级别
FTD 需要索引来快速检索数据,这是一种用空间换时间的方式,当我们创建一个大范围高级
别的数据文件时,索引自身可能会占用较多空间,当我们暂时不需要某些级别的时候,创建
文件时可以不建立这些级别的索引信息,当后续需要的时候再通过追加的形式为其创建。通
过调用 initZoom 接口可以追加新的级别索引,下面的代码片段演示了创建方法。
MeFTDHandler* pFTDHandler = MeFTDHandler::fromFile(“D:\\myftd.ftd”, MeFTDHandler::ReadWrite);
if(nullptr == pFTDHandler)
return;
bool bOk = pFTDHandler->initZoom(11);
if(bOk)
使用迭代器
FTD 提供了读取数据迭代器,使用迭代器我们可以非常优雅的遍历指定的层级的瓦片数据,
同时迭代器允许指定一个数据范围,从而我们可以定向迭代某个级别指定范围的瓦片数据。
MeFTDHandler* pFTDHandler = MeFTDHandler::fromFile(“D:\\myftd.ftd”, MeFTDHandler::ReadOnly);
if(nullptr == pFTDHandler)
return;
MeFTDIterator* pIter = pFTDHandler->iterator(10, [范围]);
while(pIter->hasNext())
{
int nTileDataSize = 0;
MeFTDTileData pTileData = nullptr;
MeFTDTileKey tileKey = pIter->next(&pTileData, nTileData);
if(0 == nTileDataSize)
continue;
...有数据,执行其他操作
MeFTDHandler::destroyTileData(pTileData);
pTileData = nullptr;
nTileDataSize = 0;
}
pFTDHandler->close();
MeFTDHandler::destroy(pFTDHandler);
回收磁盘空间
在对瓦片数据进行频繁更新或删除操作以后,文件可能会产生大量 "死亡" 的瓦片,FTD 仅仅
是将其标记为删除,因此要完全回收这些磁盘空间,可以通过执行 vacuum 来完成。
注意:执行 vacuum 是代价高昂的操作。
联系我们