SHAPE 文件格式
SDE,ARC/INFO,PC ARC/INFO,Data Automation Kit(DAK)和ArcCAD提供了shape 到coverage的数据转换器,ARC/INFO同样提供了coverage到shape的转换器。为了和其他数据格式交换,shape文件的格式在本报告中被出版。其他数据流,比如来自全球定位系统(GPS)接收机的数据能同样被存为shape文件或X,Y事件表。
Shape文件描述计算机程序能通过使用本节的技术描述来产生,读,写shape文件。
一个ESRI的shape文件包括一个主文件,一个索引文件,和一个dBASE表。主文件是一个直接存取,变量记录长度文件,其中每个记录描述一个有它自己的vertices列表的shape。在索引文件中,每个记录包含对应主文件记录离主文件头开始的偏移,dBASE表包含一feature一个记录的feature的特征。几何和属性间的一一对应关系是基于记录数目的。在dBASE文件中的属性记录必须和主文件中的记录是相同顺序的。
命名习惯所有文件名都符合83命名习惯。主文件,索引文件和dBASE文件有相同的前缀。前缀必须是由字符或数字(a-Z,0-9)开始,后跟0到7个字符(a-Z,0-9,_,)主文件的后缀是shp,索引文件的后缀是shx,dBASE表的后缀是dbf。文件名中的所有字母在对文件名敏感的 *** 作系统中都是小写的。
例子
主文件:countiesshp 索引文件:countiesshx dBASE表: ountiesdbf数字类型一个shape文件存储整数和双精度数,本文档的余数指以下类型:
整数:有符号32位整数(4字节)
双精度:有符号64位IEEE双精度浮点数(8字节)浮点数必须是数字的值。负无穷,正无穷和非数字(NaN)值在shape文件不被允许。然而shape文件支持'没有数据'的值这样的概念,但是只用于衡量。某些小于-1038被shape文件读取程序用来代表'没有数据'的值。
下面的第一节描述shape文件的总体结构和组织。第二节描述shape文件支持的每种shape类型的记录内容。
主文件的组织
主文件(shp)由固定长度的文件头和接着的变长度记录组成。每个变长度记录是由固定长度的记录头和接着的变长度记录内容组成。图1图解了主文件的结构。
图 1 主文件的结构
文件头
记录头 记录内容
记录头 记录内容
记录头 记录内容
记录头 记录内容
……
……
记录头 记录内容
Shape文件中所有的内容可以被分为二类:
与数据相关的:
。主文件记录内容
。主文件头的数据描述域(Shape 类型,边界盒等)
与文件管理相关的:
。文件和记录长度
。记录偏移等
整数和双精度整数在文件头中组成数据描述域,在主文件的记录内容是小ndian(PC或Intel)字节顺序。组成文件的其余部分和文件管理的整数和双精度浮点数是大endian(Sun或Motorola)字节顺序。
主文件头
主文件头100字节长。表1显示带有字节位置,值,类型和字节顺序的文件头中的域。
在此表中,位置是相对于文件的开始。
表 1 主文件头的描述
位置 域 值 类型 字节顺序
0字节 文件代码 9994 整数 大
4字节 未被使用 0 整数 大
8字节 未被使用 0 整数 大
12字节 未被使用 0 整数 大
16字节 未被使用 0 整数 大
20字节 未被使用 0 整数 大
24字节 文件长度 文件长度 整数 大
28字节 版本 1000 整数 小
32字节 Shape类型 Shape类型 整数 小
36字节 边界盒 Xmin 双精度 小
44字节 边界盒 Ymin 双精度 小
52字节 边界盒 Xmax 双精度 小
60字节 边界盒 Ymax 双精度 小
68字节 边界盒 Zmin 双精度 小
76字节 边界盒 Zmax 双精度 小
84字节 边界盒 Mmin 双精度 小
92字节 边界盒 Mmax 双精度 小
未被使用,值为00,若没有被衡量或是Z轴。
文件长度的值是在16位字下文件的总长度(包括组成文件头的50个16位字)。在shape文件中的所有非空shape被需要是同种shape类型。Shape类型的值如下:
值 shape类型
0 空shape
1 点
3 多线
5 多边形
8 多点
11 点Z
13 多线Z
15 多边形Z
18 多点Z
21 点M
23 多线M
25 多边形M
28 多点M
31 多斑块
没有被定义的Shape 类型值(2,4,6等直到33)为将来可能的使用而保留。目前shape文件被局限于包含以上定义的同种shape类型。在将来shape文件可以被允许包含多于一种shape类型。若混合shape类型被实现,文件头中的shape类型将标识该文件。
主文件头的边界盒存储文件中shape的实际幅度。最小边界X和Y直交的(潜在的M,Z)长方形包含了所有的shape。若shape文件是空的(没有记录),min,Ymin,Xmax,Ymax的值是未被定义的。Mmin和Mmax能包含shape文件用来衡量不包含衡量的shape类型的'没有数据'的值(参见2页的数字类型),记录头
每个记录的头存储了记录的数目和记录内容的长度。记录头有一个固定长度8字节。表 2显示文件记录头中域的字节位置,值,类型和字节顺序。在表中,位置是相对于记录的开始的。
表 2 主文件记录头文件的描述
位置 域 值 类型 字节顺序
0字节 记录数目 记录数目 整数 大
4字节 内容长度 内容长度 整数 大
记录数目从1开始。
一个记录的内容长度是按16位字衡量的记录内容长度。每个记录因此为文件的总长度贡献(4+内容长度)个16位字,正如文件头是24字节一样。
主文件记录内容
Shape文件记录内容包含一个shape类型和接着的该shape的几何数据。记录内容的长度依赖于在一个shape中部分和vertices的数目。对每种shape类型,我们首先描述该shape然后是它在磁盘上的存储镜像。在表3到16,位置是相对于记录内容的开始。
空shape
shape类型为0指代一种不带几何数据的空shape,每种要素类型(点,线,多边形等)都支持空,在同一个shape文件中有点和空的点是有效的。常常空shape是放东西的地方;在shape文件产生时被使用和在产生后更被广泛地使用。
表 3 空shape记录内容
位置 域 值 类型 数目 字节顺序
0字节 shape类型 0 整数 1 小
在X,Y位置的Shape类型
点 一个点包括一对以X,Y顺序排列的双精度的坐标
Point
{
Double X //X坐标
Double Y //Y坐标
}
表 4 点记录内容
位置 域 值 类型 数目 字节顺序
0字节 shape类型 1 整数 1 小
4字节 X X 双精度 1 小
12字节 Y Y 双精度 1 小
多点 一个多点代表一个点的集合:
MultiPoint
{
Double[4] Box //边界盒
Integer NumPoints //点的数目
Point[NumPoints] Points //在集合中的点
}
边界盒以Xmin,Ymin,Xmax,Ymax存储。
表 5 多点记录内容
位置 域 值 类型 数目 字节顺序
0字节 shape类型 8 整数 1 小
4字节 Box Box 双精度 4 小
36字节 NumPoints NumPoints 整数 1 小
40字节 Points Points 点 NumPoints 小
PolyLine 一条PolyLine是指一条包含一个或多个部分的有序的vertices的集合。一个部分是指二个或多个点彼此连接的顺序。部分间彼此相连或不连。部分间彼此可能相交或不相交。
因为该定义没有禁止有确定坐标的连续点,shape文件的读程序必须掌握这样的情况。在另外,退化(degenerate)和可能导致零长度的结果是不被允许的。
PolyLine
{
Double[4] Box //边界盒
Integer NumParts //部分的数目
Integer NumPoints //点的总数目
Integer[NumParts] Parts //在部分中第一个点的索引
Point[NumPoints] Points //所有部分的点
}
PolyLine的域在以下为更详细的描述:
Box 被存储的PolyLine的边界盒,以Xmin,Ymin,Xmax,Ymax的顺序存储。
NumParts 在PolyLine中部分的数目。
NumPoints 所有部分的点的总数目。
Parts NumParts长度的数列。为每条PolyLine存储它在点数列中的第一个点的索引。数列索引是从0开始的。
Points NumPoints长度的数列。在PolyLine中的每一部分的点被尾到尾存储。部分2的点跟在部分1的点之后,如此下去。部分数列对每一部分保持开始点的数列索引。
在部分间点之间没有界限。
表 6 PolyLine记录内容
位置 域 值 类型 数目 字节顺序
0字节 shape类型 3 整数 1 小
4字节 Box Box 双精度 4 小
36字节 NumParts NumParts 整数 1 小
40字节 NumPoints NumPoints 整数 1 小
44字节 Parts Parts 整数 NumParts 小
X字节 Points Points 点 NumPoints 小
注意:X=44+4 NumParts多边形 一个多边形包含一个或多个环。一个环是四或多个点彼此相连组成的一个闭合的彼此不相交的环。一个多边形可能包括多个外环,一个环的vertices的顺序和方向指示环的哪一边是多边形的内部。在多边形中的洞的环的vertices是逆时针方向的。一个环组成的多边形总是顺时针方向的。一个多边形的环是被做为它的一部分的。因为该定义没有禁止有确定坐标的连续的点,shape文件读程序必须解决这种情况。在另外,退化(degenerate)和可能导致零长度的结果是不被允许的。多边形的结构被定义为PolyLine结构,正如下文:
Polygon
{
Double[4] Box //边界盒
Integer NumParts //部分的数目
Integer NumPoints //点的总数目
Integer[NumParts] Parts //在部分中第一个点的索引
Point[NumPoints] Points //所有部分的点
}
多边形的域在以下为更详细的描述:
Box 被存储的多边形的边界盒,以Xmin,Ymin,Xmax,Ymax的顺序存储。
NumParts 在多边形中环的数目。
NumPoints 所有环的点的总数目。
Parts NumParts长度的数列。为每条环存储它在点数列中的第一个点的索引。数列索引是从0开始的。
Points NumPoints长度的数列。在多边形中的每一个环的点被尾到尾存储。环2的点跟在环1的点之后,如此下去。部分数列对每一环保持开始点的数列索引。在环间点之间没有界限。
图 2中的例子图演示了多边形的表现。该图中的多边形有一个洞,总共是8个vertices。
关于多边形shape有以下重要注意事项:
环是闭合的(第一个和最后一个vetex必须是一样的)在点数列中环的顺序是不重要的。
存储在shape文件中的多边形必须是clean,一个clean的多边形是指这样的一个多边形:
1. 没有自交。这意味着属于一个环的一段可能不与另一个环的一段相交。一个多边形
的环可能在vetices处彼此相交,但不是在沿段处。重合的段被认为是相交的。
2. 在定义多边形的线的正确一边有多边形的内部。一个观察者以vertex顺序沿环走时,右边的邻居是多边形的内部。一个独环的多边形的vertices因此都是顺时针的。在这些多边形中的洞有一个逆时针的方向。当定义在多边形中的洞同样是顺时针时,发生"Dirty"多边形错误。这会导致内部的重叠。
图 2 一个多边形的实例
在此例中,NumParts等于2,NumPoints等于10。注意洞多边形的点的顺序是逆序的。
0 5
部 分 : 0 5
0 1 2 3 4 5 6 7 8 9
点 : v1 v2 v3 v4 v1 v5 v8 v7 v6 v5
表 7 多边形记录内容
位置 域 值 类型 数目 字节顺序
0字节 shape类型 5 整数 1 小
4字节 Box Box 双精度 4 小
36字节 NumParts NumParts 整数 1 小
40字节 NumPoints NumPoints 整数 1 小
44字节 Parts Parts 整数 NumParts 小
X字节 Points Points 点 NumPoints 小
注意:X=44+4 NumParts
typedef struct
{
FILE fpSHP;
FILE fpSHX;
int nShapeType; / SHPT_ /
int nFileSize; / SHP file /
int nRecords;
int nMaxRecords;
int panRecOffset;
int panRecSize;
double adBoundsMin[4];
double adBoundsMax[4];
int bUpdated;
unsigned char pabyRec;
int nBufSize;
} SHPInfo;
typedef struct
{
int nSHPType;
int nShapeId; / -1 is unknown/unassigned /
int nParts;
int panPartStart;
int panPartType;
int nVertices;
double padfX;
double padfY;
double padfZ;
double padfM;
double dfXMin;
double dfYMin;
double dfZMin;
double dfMMin;
double dfXMax;
double dfYMax;
double dfZMax;
double dfMMax;
} SHPObject;
下载 地址:>
在该路径下会生成一个文件夹(CMakeFiles),三个文件(Makefile, CMakeCachetxt, cmake_installcmake)以及一个程序(addition)
此时的文件目录结构为
该项目该依赖于MPI,GDAL和cereal库。MPI和GDAL库自行编译
1配置各种编译的时候,可以使用set设置,更多详情,请自行搜索。
2头文件的包含请使用include_directories。
3搜索源文件请使用aux_source_directory。
4第三方库的查找使用 find_package。例如我们想找GDAL, 那么 find_package(GDAL), 它会在 /usr/share/cmake/Modules 文件中的FindGDALcmake文件中去找GDAL的各种信息。前提是GDAL 是make install的, FindGDALcmake中才会有GDAL的各种信息。否则的话,我们需要set自行制定GDAL的相关信息。
5第三方库的链接用target_link_libraries。
注意,也可以将该项目中的某个文件夹编译成静态库,然后在于其余源文件链接,可以参考: >
是的,kbmmemtable 100%线程。
有几种方法可以从多个线程访问存储表:
1)有一个包含数据库kbmmemtable。然后在每个线程附加到另一个基地kbmmemtable tkbmmemtable。该线程将有他们自己的光标进入基地MemTable中,这意味着他们可以排序和索引,和滤波器等完全相互独立。
2)让每一个线程做山锁之前使用它,和山。这使得 *** 作不会被另一个线程中断。如太追加;mtfields […]:=…;后山是3个步骤。例如如果另一个线程做太取消这3个步骤中,无论是mtfields…或太后将失败,因为该数据集的异常突然不再在编辑模式。
kbmmemtable不会崩溃,因为这(因为其内部_is_线程)但是程序不会像预期的那样。因此,在附加语句和一个附加语句之前先放一个山。
真搞不明白了,你去这有下载 >
用 gdal库。
库参考和下载在这:>
下面这个文件瞎写的,你可以修改下。。需要加装库,头文件和lib
//tifhenum
{
TOPX = 0,
CELLX,
XXXX,
TOPY,
XXXXX,
CELLY,
GeoTfInfoArrCount
};
template<typename type, int nBand =1>
class CTifFileOp
{
public:
CTifFileOp(string FilePath=string(""));
virtual ~CTifFileOp();
double get_nodata_value()
{
return m_pDataset->GetRasterBand(nBand)->GetNoDataValue();
}
int GetGeoTransform(double gt)const;
int ChangeFile(string strPath);
void ReadTiffDataset(type DataGet, int begRow = 0, int begCol = 0, int numRows = 1, int numCols = 1)const;
void WriteTiffDataset(type DataGet, int begRow = 0, int begCol = 0, int numRows = 1, int numCols = 1);
void ReadTiffDataset(vector<type> & DataGet, int begRow = 0, int begCol = 0, int numRows = 1, int numCols = 1)const
{
DataGetclear();
DataGetresize(numColsnumRows);
ReadTiffDataset(&DataGetbegin(), begRow, begCol, numRows, numCols);
}
size_t GetColNum()
{
openDs();
return m_pDataset->GetRasterXSize();
}
size_t GetRowNum()
{
openDs();
return m_pDataset->GetRasterYSize();
}
//获取波段数
int GetRasterCount()
{
openDs();
return m_pDataset->GetRasterCount();
}
//获取坐标系信息
const char GetProjectionRef()
{
openDs();
return m_pDataset->GetProjectionRef();
}
//获取数据类型
GDALDataType GetDataType(int iRaster = nBand)
{
openDs();
return m_pDataset->GetRasterBand(iRaster)->GetRasterDataType();
}
void GetAllData(vector<type> & DataGet)
{
// double geoInfo[GeoTfInfoArrCount] = { 0 };
// GetGeoTransform(geoInfo);
openDs();
ReadTiffDataset(DataGet, 0, 0, GetRowNum(), GetColNum());
}
private:
string m_strFile;
GDALDataset m_pDataset = nullptr;
bool m_bWrite = false;
private:
void openDs(GDALAccess openMode = GA_ReadOnly);
bool CanWrite()const
{
return m_bWrite;
}
};
template<typename type, int nBand>
int CTifFileOp<type, nBand>::GetGeoTransform(double gt) const
{
// openDs();
m_pDataset->GetGeoTransform(gt);
return 0;
}
template<typename type, int nBand>
CTifFileOp<type, nBand>::CTifFileOp(string FilePath)
:m_strFile(FilePath), m_pDataset(nullptr)
{
openDs();
}
template<typename type, int nBand>
CTifFileOp<type, nBand>::~CTifFileOp()
{
if (m_pDataset)
{
GDALClose(m_pDataset);
m_pDataset = nullptr;
//是这样关闭 数据集 么?
}
}
template<typename type, int nBand>
void CTifFileOp<type, nBand>::openDs(GDALAccess openMode)
{
if (m_pDataset)//当不为nullptr,认为是打开的
{
return;
}
GDALAllRegister();
const char pszFormat = "GTiff";
GDALDriver poDriver;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if (poDriver == nullptr){
return;
}
if (!m_strFileempty())
{
m_pDataset = ((GDALDataset )GDALOpen(m_strFilec_str(), openMode));
// if (m_pDataset != NULL)
// {
// int ibandCounts = m_pDataset->GetRasterCount();
// ibandCounts |= (long(1)<<0);
// }
if (GA_Update == openMode)
{
m_bWrite = true;
}
else
m_bWrite = false;
}
// OGRCleanupAll();
}
template<typename type, int nBand>
int CTifFileOp<type, nBand>::ChangeFile(string strPath)
{
m_strFile = strPath;
if (m_pDataset)
{
GDALClose(m_pDataset);
m_pDataset = nullptr;
//是这样关闭 数据集 么?
}
openDs();
return 0;
}
template<typename type, int nBand>
void CTifFileOp<type, nBand>::ReadTiffDataset(type DataGet, int begRow, int begCol, int numRows, int numCols)const
{
if (!DataGet || !m_pDataset)
{
return;
}
if (begRow < 0 || begCol < 0 || numRows <= 0 || numCols <= 0)
{
return;
}
GDALDataType datatype = m_pDataset->GetRasterBand(nBand)->GetRasterDataType();
//不知道下面读数据的这个类型参数有什么意义
m_pDataset->RasterIO(GF_Read,begCol,begRow,numCols,numRows,DataGet,numCols,numRows,datatype,1,0,0,0,0);
}
template<typename type,int nBand>
void CTifFileOp<type, nBand>::WriteTiffDataset(type DataGet, int begRow, int begCol, int numRows, int numCols)
{
if (!DataGet || !m_pDataset)
{
return;
}
if (begRow < 0 || begCol < 0 || numRows <= 0 || numCols <= 0)
{
return;
}
if (!CanWrite())
{
GDALClose(m_pDataset);
m_pDataset = nullptr;
openDs(GA_Update);
}
GDALDataType datatype = m_pDataset->GetRasterBand(nBand)->GetRasterDataType();
//不知道下面读数据的这个类型参数有什么意义
m_pDataset->RasterIO(GF_Write, begCol, begRow, numCols, numRows, DataGet, numCols, numRows, datatype, 1, 0, 0, 0, 0);
}
以上就是关于gdal如何建立不带几何数据的空shape全部的内容,包括:gdal如何建立不带几何数据的空shape、Python下的subprocess.call()使用和注意事项、cmake编译单/多文件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)