首页 > 其他分享 >fepk文件格式说明

fepk文件格式说明

时间:2023-09-28 11:36:39浏览次数:41  
标签:说明 字节 文件 fepk 索引 文件格式 瓦片 uint 数据

 

1  卫星影像金字塔分块原理说明

 

通常我们在工作中使用的卫星影像数据,轻则几百M,重则几百个G甚至上TB级。影像数据太大,是大家经常会遇到的一个问题,尤其是想下载一个省以上数据的时候该问题尤为突出。那么该问题是否有一个比较好的解决方案呢?

以全球为例,我们以19级为例,共有2^18 * 2^17 张瓦片,如此多的瓦片会让磁盘愈来愈慢,同时也无法维护。

当影像范围比较大时,我们可以采用金字塔分块的方式进行管理,系统会自动将大范围分成若干个块,且块与块之间是可以无缝拼接的。

一般情况我们选择全球前10级别作为基础级别,因数据量不大(1G)左右,后续以10级作为基础级别,全球19级别数据被划分为 2^8 * 2^7(512 * 256)个块。每个块中包含了256 * 256 张小瓦片。

1.1  Fepk文件命名规则

 

文件说明(包含索引与数据两个文件,文件必须都配套才可以正常使用):

*.fepk          :文件中存储具体的瓦片数据。

*.fepk.idx    :文件中存储的瓦片的索引信息,当给定一个瓦片编号后,可以根据编号计算出来瓦片存在索引中的信息(大小,以及数据在8-174-138.fepk中的位置)。

名称命名规

以8-174-138.fepk为例:其中8是级别,174是列号,138是行号,文件中存储了8-174-138瓦片裂分出来的所有瓦片数据。

2  .fepk文件格式说明

我们一般不会直接采用瓦片作为管理单元,会把一个块作为管理单元,把数据划分为索引文件与数据文件,如下所示:

数据文件:world.fepk

索引文件:world.fepk.idx

 

2.1  索引文件

1文件说明

文件头

字段

文件头

char    szMagic[20]

fe.tile.store.data20字节

uint    version

版本号4字节

uint    typeId

数据类型

enum PKType

{

 PK_IMAGE ,

 PK_DEM,

 PK_VEC,

PK_QXSY,

PK_USER,

};4字节

uint    wgs84

是否是wgs84经纬投影4字节

uint    flag

4字节

uint64  timestamp

时间戳8字节

real2   vStart

经纬度最小范围8*2字节

real2   vEnd

经纬度最大范围 8*2字节

LevSnap levOff[24]

级别索引,8 * 24 字节

char    _reserve[240]

保留

级别1

int2    _start

2 * 4字节,瓦片最小行列号

int2    _end

2 * 4字节,瓦片最大行列号

uint64  _offset

8字节

uint64  _dataSize

8字节

uint    _lev

4字节

char    _reserve[216]

216字节

瓦片数据索引矩阵数据PKTLHeader

N * PKTLHeader

N = (_end.x - _start.x + 1) * (_end.y - _start.y + 1)

 

PKTLHeader

 

级别2

 

 

级别3

 

 

级别…

 

 

 

PKTLHeader定义:

PKTLHeader定义:
struct  PKTLHeader
    {
        /// 有无数据标记,即服务器上是否有该数据 0,无,1,有
        uint64  _data:2;
        /// 在本文件中是否已经存储 0,无,1,有
        uint64  _stored:2;
        /// 状态,
        uint64  _state :6;
        /// 数据地址,使用50个bit最大 2^54
        /// 单个文件最大16 K T
        uint64  _offset : 54;
        /// 如果该值!= 0xFFFF,则有效,否则无效,
        /// 使用该字段的意义在于解决网络读取问题,比如在云盘上
        /// 先读取索引,如果没有数据大小,或者数据大小存储在数据文件中,则需要
        /// 再次访问数据文件,才可以得大小,增加额外的IO,同时兼顾大小,该变量最大可以存储64K
        /// 如果超过了64K,那么一样的需要访问数据文件获取大小
   ushort  _dataSize;
};

 

共计10自字节

LevSnap定义:

struct  LevSnap
{
        uint64  _lev:8;
        uint64  _offset:56;
};

 

共计8字节

2.2  数据文件文件

文件头

字段

文件头

char    szMagic[20]

fe.tile.store.data20字节

uint    version

版本号4字节

uint    typeId

数据类型

enum PKType

{

 PK_IMAGE ,

 PK_DEM,

 PK_VEC,

PK_QXSY,

PK_USER,

};4字节

uint    wgs84

是否是wgs84经纬投影4字节

uint    flag

4字节

uint64  timestamp

时间戳8字节

real2   vStart

经纬度最小范围8*2字节

real2   vEnd

经纬度最大范围 8*2字节

LevSnap levOff[24]

级别索引,8 * 24 字节

char    _reserve[240]

保留

数据0

Int4

4*4字节,行号,列号,级别,大小

数据

 

数据1

Int4

4*4字节,行号,列号,级别,大小

数据

 

数据…

Int4

4*4字节,行号,列号,级别,大小

数据

 

 

3  如何使用数据

3.1  解压成标注金字塔瓦片

用户可以通过FEPKUNPack.exe 解压程序,将数据加压标准的金字塔瓦片,然后即可使用,导出后如下所示。

导出后可以方便的被osgEarth,cesium,argis,fastearth等软件直接加载。

缺点: 导出后,占用磁盘大小比未解压前大50%。

             导出后,维护困难,因为文件很多,拷贝能都受到影响。

 

数据截图

 

3.2  API读取瓦片

使用SDK/API访问数据,为了方便大家使用,避免数据解压,可以使用FEPKReadApi

SDK读取数据,SDK使用C语言编写,接口如下所示

extern  "C"
{
    /// <summary>
    /// 打开文件函数,可以打开索引也可以打开数据文件
    /// </summary>
    /// <param name = "fileName">文件名称</param>
    /// <return>0:失败,否则成功</return>
FEPKFile    fepkOpenFile(const char* fileName);
    /// <summary>
    /// 读取索引数据函数
    /// </summary>
    /// <param name = "file">索引文件指针</param>
    /// <param name = "x">列号</param>
    /// <param name = "y">行号</param>
    /// <param name = "z">级别</param>
    /// <param name = "header">返回文件头信息</param>
    /// <return>true:false</return>
bool        fepkReadHeader(FEPKFile file,int x,int y,int z,FEPHHeader* header);
    /// <summary>
    /// 根据文件头信息读取文件大小(瓦片数据大小)
    /// </summary>
    /// <param name = "file">索引文件指针</param>
    /// <param name = "header">文件头信息</param>
    /// <param name = "pSize">输出文件大小</param>
    /// <return>true:false</return>
bool        fepkReadDataSize(FEPKFile file,const FEPHHeader* header,uint* pSize);
    /// <summary>
    /// 读取瓦片数据函数
    /// </summary>
    /// <param name = "file">索引文件指针</param>
    /// <param name = "header">文件头信息</param>
    /// <param name = "pBuf">输入缓冲区大小</param>
    /// <param name = "nBufLen">缓冲区长度</param>
    /// <return> -1:失败,0:无数据,>0 数据的真实大小</return>
int         fepkReadData(FEPKFile file,const FEPHHeader* header,void* pBuf,uint nBufLen);
    /// <summary>
    /// 关闭文件
    /// </summary>
void        fepkCloseFile(FEPKFile file);
/// <summary>
    /// 从一个文件夹中读取瓦片的数据头,以及瓦片的大小
    /// </summary>
    /// <param name = "path">目录组,以null结束</param>
    /// <param name = "x">瓦片的编号</param>
    /// <param name = "y">瓦片的编号</param>
    /// <param name = "z">瓦片的编号</param>
    /// <param name = "header">文件头信息</param>
    /// <param name = "pSize">瓦片大小</param>
    /// <return>返回打开的文件</return>
FEPKFile    fepkReadTileHeader(const char** path,int x,int y,int z,FEPHHeader* header,uint* pSize);
    /// <summary>
    /// 从一个文件夹中读取
    /// </summary>
    /// <param name = "file">文件句柄</param>
    /// <param name = "header">文件头信息</param>
    /// <param name = "pBuf">输入/输出,从fepkReadTileHeader读取</param>
    /// <param name = "nBufLen">输入,从fepkReadTileHeader读取</param>
    /// <return>返回读取的长度-1,失败,0,文件内部错误,其他读取的长度</return>
int         fepkReadTileData(FEPKFile file,const FEPHHeader* header,void* pBuf,uint nBufLen);

}

 

使用说明:

 

#include "FEPKReaderApi.h"

#include <stdio.h>
/// 如果是SDK,非源码方式,则需要因入库
/// #pragma comment(lib,"FEPKReader.lib")
int main(int, char**)
{
    /// 1. 开发文件
    FEPKFile    file = fepkOpenFile("D:\\FE\\data\\fepk\\world.fepk");
    if (file == nullptr)
    {
        return  0;
    }
    FEPHHeader  header;
    uint        nSize = 0;
    /// 2. 读取给定瓦片编号的文件头信息
    /// 如果返回false,说明当前文件中没有给定的瓦片数据
    if (!fepkReadHeader(file, 0, 0, 0, &header))
    {
        return  0;
    }
    /// 3. 读取数据大小
    if (!fepkReadDataSize(file, &header, &nSize))
    {
        return  0;
    }
    /// 申请空间
    char*   pBuf = new char[nSize];
    /// 4. 读取数据
    if (!fepkReadData(file, &header, pBuf, nSize))
    {
        printf("read ok!\n");
    }
    /// 5. 释放内存
    delete[]pBuf;
    /// 6. 关闭文件
    fepkCloseFile(file);
    return  0;
}

 

 

标签:说明,字节,文件,fepk,索引,文件格式,瓦片,uint,数据
From: https://www.cnblogs.com/FastEarth/p/17735287.html

相关文章

  • 2023好用的7款数据库连接工具推荐!非常详细的介绍说明2000字左右
    在2023年,有许多好用的数据库连接工具可供选择。这些工具提供了方便、高效地连接和管理数据库的功能,为开发者和数据分析师提供了更好的工作体验。以下是我推荐的7款数据库连接工具,并对它们进行详细介绍说明:1.DBeaver:  -DBeaver是一款免费且功能强大的数据库连接工具,支持......
  • 【node】发送邮件及附件简要使用说明
    Nodemailer是一个用于Node.js应用程序的模块,可以轻松发送电子邮件。该项目始于2010年,当时没有合理的选项来发送电子邮件消息,如今它是大多数Node.js用户默认选择的解决方案。一、环境配置安装模块:nodemailernpminodemailer--save二、邮箱服务配置如下:lettransporter=no......
  • 关于日记内容调整说明
    关于日记内容调整说明:1.减少记流水账,以每天任务完成进度为主,分板块列举→信条部分比如早起晚睡2/88,举止厚重10/360,每日反省1/90,前面是完成天数,后面是计划天数→学习部分以表格单列每日的学习任务,以及完成情况→项目进度主要是学车,以及准备继续做的电赛项目2.更改图片,拼......
  • Markdown 图片居中显示,增加图片说明
    <center><imgsrc="https://img2023.cnblogs.com/blog/80824/202308/80824-20230808130713884-449483982.jpg"width="30%"><imgsrc="https://img2023.cnblogs.com/blog/80824/202308/80824-20230808154306335-1528301308......
  • Java中CornExpression说明
    关于cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素,从左至右,这些元素约定义如下:1、秒(0~59)2、分(0~59)3、小时(0~23)4、月份中的日期(1-31)5、月份(1-12或JAN-DEC)6、星期中的日期(1-7或SUN-SAT)7、年份(1970-2099)eg:0010,14,16**?每天10点、14点、16点0015,30,45*......
  • UCLASS是一种类说明符吗?
    我们知道,在java里有一个东西叫注解。注解的使用在spring框架里更是被用的出神入化。那么C++里呢?有没有对类进行说明的类型 第一种类说明符:Abstract。抽象类说明符将类声明为“抽象基类”,防止用户在虚幻编辑器中向世界添加此类的参与者,或在游戏中创建此类的实例。 第二种......
  • 关于企业使用企业邮箱一点体会说明
    1.企业使用邮箱最好采用同一域名,最好不要重复注册域名进行,否则跨域名邮件地址不好管理2.对于使用企业微信的企业,我们尽量使用腾讯企业邮箱可以一体化管理,提高效率真。3.对于使用钉钉同样我们选阿里准没错4.使用其他邮箱时,我们要和供应商确认好是否可以和我们常用的通讯软件支持......
  • CH573 CH582 CH579蓝牙从机(Peripheral)/主机(Central)例程讲解一(蓝牙主从机收发数据
    原文链接:https://www.cnblogs.com/risc5-ble/p/15994545.html前言:蓝牙从机,顾名思义,就是一个蓝牙从设备,可以不断发送广播等待与主机建立连接进行通信,建立连接后,可以通知主机,也可以收到主机发的信息,一般使用BLE调试助手(安卓应用市场可下载),ios可使用Lightblue来进行调试通信等......
  • 6.接口说明
    55AA包着DSRC(F1指令),里面包着cos指令55AA指令解析 55AA000008F902010500840000087B00帧0008DATA域长度(命令字后的全部字节)F9命令字022卡槽,01第一条数据,055字节0084000008命令BST(F1)55AA04001cF1FFFFFFFF500391C00385B12353ACE1CD000......
  • MySQL的配置文件中关于basedir和datadir的说明
    在MySQL的配置文件my.ini或者my.cnf文件中1、basedir参数原文说明为:Pathtoinstallationdirectory.Allpathsareusuallyresolvedrelativetothis.解释:该参数指定了安装MySQL的安装路径,填写全路径可以解决相对路径所造成的问题。例如:basedir="E:/dev/MySQL/MySQLS......