shapefile格式说明及读写代码示例
- 格式:doc
- 大小:273.00 KB
- 文档页数:19
ogr2ogr 转换shapefile 编码(原创版)目录1.引言2.ogr2ogr 转换器的概述3.Shapefile 格式的概述4.编码的选择与转换5.示例与实践6.结论正文【引言】地理信息系统 (GIS) 是一种通过将空间数据与属性数据相结合来捕捉、存储、分析和管理地理信息的技术。
GIS 数据格式的标准化对于数据共享和互操作性至关重要。
Shapefile 是一种常见的 GIS 数据格式,而ogr2ogr 是一个开源的 GIS 数据转换器,可以将 Shapefile 转换为其他格式。
本文将介绍如何使用 ogr2ogr 转换器对 Shapefile 进行编码转换。
【ogr2ogr 转换器的概述】ogr2ogr 是一个命令行工具,可以将 GIS 数据从一个格式转换为另一个格式。
它支持许多不同的数据源和目标格式,包括 Shapefile、GeoJSON、KML 等。
ogr2ogr 转换器还可以处理地理坐标系和投影。
它由OGR(Open Geospatial Reference) 项目开发,是一个开源的 GIS 软件库。
【Shapefile 格式的概述】Shapefile 是一种常见的 GIS 数据格式,可以存储点、线和面等空间几何数据。
Shapefile 文件由多个文件组成,包括.shp(几何图形)、.shx(索引) 和.dbf(属性数据) 等文件。
Shapefile 文件通常使用dbf 文件存储属性数据,这些数据可以是任何类型的数据,包括字符串、数字、日期等。
【编码的选择与转换】在将 Shapefile 转换为其他格式时,需要选择目标格式的编码。
常见的编码包括 UTF-8、UTF-16、ISO-8859-1 等。
选择正确的编码可以确保数据在转换过程中不会丢失或损坏。
例如,如果将 Shapefile 转换为GeoJSON,则应该选择 UTF-8 编码,因为 GeoJSON 是一种基于 JSON 的格式,它使用 UTF-8 编码来存储字符串数据。
使用Python Shapefile Library创建和编辑Shapefile文件shapefile是GIS中非常重要的一种数据类型,在ArcGIS中被称为要素类(Feature Classes),主要包括点(point)、线(polyline)和多边形(polygon)。
Python脚本是ArcGIS官方推荐的脚本语言,通过Python脚本能够很方便的调用ArcGIS中的各种工具和函数批量完成所需操作。
本文所介绍的这个库(Python Shapefile Library)是一个Python库,用于在Python脚本中对ArcGIS中的Shapefile 文件(.shp,.shx,.dbf等格式)进行读写操作。
1、Python Shapefile Library的下载与安装:Python Shapefile Library下载地址:https:///p/pyshp/Python Shapefile Library使用时无需安装,只需在Python程序中导入该模块文件即可(import shapefile,具体导入方法参考Python教程中模块的导入部分)2、Shapefile文件的读操作2.1 Python Shapefile Library提供了Reader类,通过创建Reader类的对象(如下面的sf)进行shapefile文件的读操作:sf = shapefile . Reader ('shapefile name')2.2 使用Python Shapefile Library读取shapefile文件的"几何数据"(Geometry)和"属性数据"(Attribute Record)"几何数据"一般有多个几何对象组成,比如一个"点文件",每个点就是一个对象;对于一个多边形文件,每个对象可能包含有多个多边形,每个多边形又称为"块(parts)",每个"块"由多个点组成。
5.5 Shapefile文件编辑 155也可能包含一个名为m的测量值。
该测量测值可能是和上述形状有关的用户自定义信息。
例如一个给定位置的温度信息,这是另外一种形状类型,它允许为每个形状添加一个m值而非z值。
这种形状数据大家一般叫它M型几何图形。
和z值类似,如果存在该类型数据,就会生成m属性,如果没有那么它们就不是上述类型的数据。
你一般不会遇到包含z值的Shapefile文件,碰到需要设置m值的数据的几率就更小了。
但是如果有机会遇到它们,那么也不必大惊小怪。
只需将dbf文件中的看到的字段和记录一视同仁即可。
如果你不喜欢将z和m值分开存放在List对象中,那么可以使用zip()方法通过点集List对它们进行组合。
zip()方法可以接受多个List对象作为参数,只需要用逗号对它们分隔即可。
5.5.4 Shapefile文件修改当你使用PyShp库创建了一个读取器对象后,它是只读的。
你可以在该读取器对象中修改记录的值,但是它们不会对原Shapefile文件中的记录产生影响。
为了创建一个Shapefile 文件,你也需要创建一个写者对象。
你可以在写入和读取对象中随意修改数据记录的值,因为它们都是Python的动态数据类型。
但是与此同时,你必须将需要修改的值从读取器对象拷贝到写入对象中。
PyShp库能自动处理所有头文件信息,例如边框和记录总数。
你唯一需要关注的是几何图形和属性。
你会发现这个方法比在之前OGR示例中使用的方法容易的多。
不过它的缺点是只适用于UTM投影。
为了演示这一概念,将会读取一个使用度做计量单位的点Shapefile文件,然后在写者对象保存它之前将其参照系统转换为UTM投影。
我们将会用到本章前面提到过的PyShp 和UTM库。
本示例中用到的Shapefile文件是之前重投影为WGS84坐标系统的纽约市博物馆Shapefile文件。
你还可以通过如下地址下载该文件的ZIP压缩格式:http://git.io/vLd8Y请看下列代码:>>> import shapefile>>> import utm>>> r = shapefile.Reader("NYC_MUSEUMS_GEO")>>> w = shapefile.Writer(r.shapeType)>>> w.fields = list(r.fields)>>> w.records.extend(r.records())>>> for s in r.iterShapes():... lon,lat = s.points[0]... y,x,zone,band = utm.from_latlon(lat,lon)... w.point(x,y)>>> w.save("NYC_MUSEUMS_UTM")。
结合C++和GDAL实现shapefile(shp)⽂件的创建和写⼊⼯具:vs2012+GDAL 2.0包含头⽂件:#include ""int main(){const char *pszDriverName = "ESRI Shapefile";GDALDriver *poDriver;GDALAllRegister();poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName );if( poDriver == NULL ){printf( "%s driver not available.\n", pszDriverName );return0;}GDALDataset *poDS;poDS = poDriver->Create("d:/newShp.shp", 0, 0, 0, GDT_Unknown, NULL ); //创建shp⽂件if( poDS == NULL ){printf( "Creation of output file failed.\n" );return0;}OGRLayer *poLayer;poLayer = poDS->CreateLayer( "point_out", NULL, wkbPoint, NULL );if( poLayer == NULL ){printf( "Layer creation failed.\n" );return0;}OGRFieldDefn idField("ID",OFTReal);OGRFieldDefn firstField("NAME",OFTInteger);OGRFieldDefn secondField("X",OFTReal);OGRFieldDefn thirdField("Y",OFTReal);idField.SetWidth(32);firstField.SetWidth(32);secondField.SetWidth(32);thirdField.SetWidth(32);poLayer->CreateField(&idField);poLayer->CreateField(&firstField);poLayer->CreateField(&secondField);poLayer->CreateField(&thirdField);int x, y;int a=10,b=100;for(int i=1;i<=10;i++){OGRFeature *poFeature;poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );poFeature->SetField("ID",i);poFeature->SetField("NAME",i);x=(rand() % (b-a))+ a;y=(rand() % (b-a))+ a;poFeature->SetField("X",x);poFeature->SetField("Y",y);OGRPoint pt;pt.setX( x );pt.setY( y );poFeature->SetGeometry( &pt );if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ){printf( "Failed to create feature in shapefile.\n" );return0;}OGRFeature::DestroyFeature( poFeature );}GDALClose( poDS );return1;}这样,就会在d盘根⽬录⽣成⼀个newShp.shp的⽂件,⽤arcgis打开,显⽰如下。
表1.shp文件的头文件结构注:最后4个加星号特别标示的四个数据只有当这个Shapefile文件包含Z方向坐标或者具有Measrue值时才有值,否则为0.0。
所谓Measrue值,是用于存储需要的附加数据,可以用来记录各种数据,例如权值、道路长度等信息。
文件长度是文件的所有长度,用16位字表示(即包括50个16位字长度的文件头)。
编号几何类型0Null Shape(表示这个Shapefile文件不含坐标)1Point(表示Shapefile文件记录的是点状目标,但不是多点)3PolyLine(表示Shapefile文件记录的是线状目标)5Polygon(表示Shapefile文件记录的是面状目标)8MultiPoint(表示Shapefile文件记录的是多点,即点集合)11PointZ(表示Shapefile文件记录的是三维点状目标)13PolyLineZ(表示Shapefile文件记录的是三维线状目标)15PolygonZ(表示Shapefile文件记录的是三维面状目标)18MultiPointZ(表示Shapefile文件记录的是三维点集合目标)21PointM(表示含有Measrue值的点状目标)23PolyLineM(表示含有Measrue值的线状目标)25PolygonM(表示含有Measrue值的面状目标)28MultiPointM(表示含有Measrue值的多点目标)31MultiPatch(表示复合目标)(5)Polygon -X,Y空间的面状目标:一个面状目标包含一个或多个环。
环是一个首尾连接的由4个或4个以上的点组成的一个封闭的,非自交的环路。
一个面状目标可能包含多重外环路。
一个环的顶点顺序或方向显示了环是否位于面状目标的内部。
内部环是逆时针的,而简单的环状面状目标通常是顺时针的。
和线类似,面状目标也包括边界框、部分数、点表14 PolygonZ的记录内容一个MultiPatch 包括许多表面部分(parts)。
Python使⽤pyshp库读取shapefile信息的⽅法通过pyshp库,可以读写Shapefile⽂件,查询相关信息,github地址为import shapefile # 使⽤pyshp库file = shapefile.Reader("data\\市界.shp")shapes = file.shapes()# <editor-fold desc="读取元数据">print(file.shapeType) # 输出shp类型'''NULL = 0POINT = 1POLYLINE = 3POLYGON = 5MULTIPOINT = 8POINTZ = 11POLYLINEZ = 13POLYGONZ = 15MULTIPOINTZ = 18POINTM = 21POLYLINEM = 23POLYGONM = 25MULTIPOINTM = 28MULTIPATCH = 31'''print(file.bbox) # 输出shp的范围# </editor-fold># print(shapes[1].parts)# print(len(shapes)) # 输出要素数量# print(file.numRecords) # 输出要素数量# print(file.records()) # 输出所有属性表# <editor-fold desc="输出字段名称和字段类型">'''字段类型:此列索引处的数据类型。
类型可以是:“C”:字符,⽂字。
“N”:数字,带或不带⼩数。
“F”:浮动(与“N”相同)。
“L”:逻辑,表⽰布尔值True / False值。
“D”:⽇期。
“M”:备忘录,在GIS中没有意义,⽽是xbase规范的⼀部分。
'''# fields = file.fields# print(fields)# </editor-fold># <editor-fold desc="输出⼏何信息">for index in range(len(shapes)):geometry = shapes[index]# print(geometry.shapeType)# print(geometry.points)# </editor-fold>以上这篇Python使⽤pyshp库读取shapefile信息的⽅法就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
ESRI shapefile 技术手册本技术手册规定了shapefile空间数据格式,阐述了为什么是一种比较重要的数据格式。
同时本技术手册还列出了直接创建shapefile数据的ESRI工具和从其它数据格式向shapefile 格式转换的软件。
对一些希望通过自己开发程序来完成数据转换或者创建shapefile格式的数据的组织来说,这份技术说明同样提供了所需的所有技术支持。
什么是shapefile?Shapefile把空间对象的非拓扑地理数据和属性信息存储在一个数据集里面。
由于其不包含拓扑结构数据结构,因此相比于其它的数据格式,具有更易于图形输出与编辑的能力。
Shapefile更易于处理单要素图形,此外shapefile还具有需要较少的磁盘储存空间与易于读写的优点。
Shapefile支持点、线、面状要素;面状要素以闭合的多线,即多边形的边界存储。
属性要素以dBASE格式记录。
且每一个属性值与相关的形记录有一对一的关系。
如何创建shapefile?可以通过以下方式创建shapefile:导入---使用ARC/INFO、PC ARC/INFO,、Spatial Database Engine(SDE)、Arc View GIS,或者是Business MAP等软件,由已有的数据源创建。
数字化---由ArcView的地理信息要素创建工具直接数字化得到。
编程---使用Avenue™ (ArcView GIS), MapObjects™, ARC Macro Language (AML™)(ARC/INFO),或者简单的宏命令,自行创建shapefile.直接生成----通过特定的程序直接生成shapefile文件。
SDE、ARC/INFO、PC ARC/INFO、Data Automation Kit (DAK), 和Arc CAD这些软件可以把shapefile格式的文件转化为coverage的文件格式,ARC/INFO还可以把coverage格式转化为shapefile 文件格式,在这份文件中详细地说明了shapefile数据与其他形式数据的转化过程。
matlab中shaperead函数Matlab中的shaperead函数是一个非常有用的工具,它可以帮助我们读取和处理地理信息系统(GIS)中的矢量数据。
这些数据通常以shapefile格式存储,包含了地图上的各种要素,如道路、河流、建筑物等等。
在本文中,我们将详细介绍shaperead函数的用法和功能。
首先,让我们看一下shaperead函数的基本语法:```matlabS = shaperead(filename)```其中,filename是shapefile文件的名称,S是一个结构体数组,包含了shapefile中的所有要素。
每个结构体都包含了该要素的几何形状和属性信息。
例如,我们可以使用以下代码读取一个名为“myshapefile.shp”的shapefile文件:```matlabS = shaperead('myshapefile.shp');```读取完成后,我们可以使用S(1)、S(2)等方式访问结构体数组中的每个要素。
每个结构体包含的字段可能会有所不同,但通常包括以下几个:- Geometry:要素的几何形状,可以是点、线或面。
- BoundingBox:要素的边界框,即最小外接矩形。
- X、Y:要素的中心点坐标。
- Attributes:要素的属性信息,可以是任意类型的数据,如字符串、数值等等。
下面是一个简单的示例,演示如何读取shapefile文件并显示其中的要素:```matlabS = shaperead('myshapefile.shp');for i = 1:length(S)plot(S(i).X, S(i).Y);hold on;end```这段代码将读取“myshapefile.shp”文件中的所有要素,并将它们显示在一个图形窗口中。
我们可以使用plot函数绘制要素的几何形状,使用hold on命令保持图形窗口的状态,以便在同一张图中显示多个要素。
C#读取shapefile文件C#读取shapefile文件using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Data.Odbc; //add by hand,which is needed when load the layer attribute informationusing System.Data.OleDb;using System.Collections;using System.Data;using System.Xml;namespace CGCL.CGFiles{public class CGShapeFileParser{public class ESRI_ShxHeader{int FileCode; //9994int[] Unused2 = new int[5];int FileLength;int Version; //1000int ShapeType; // 0- Null shape// 1- Point// 3-Arc// 5-Polygon// 8-MultiPointdouble XMin;double YMin;double XMax;double YMax;int[] Unused3 = new int[8];}class ESRI_ShapeFile{int FileCode; //9994int[] Unused = new int[5];int FileLength;int Version; //1000int ShapeType; // 0- Null shape // 1- Point// 3-Arc// 5-Polygon// 8-MultiPointdouble XMin;double YMin;double XMax;double YMax;int[] Unused1 = new int[8];}class ESRI_RecordHeader {int RecNumber;int ContentLength;}class ESRI_PointContent {int ShapeType;double X;double Y;}class ESRI_IndexRec//索引文件{int Offset;int ContentLen;}class ESRI_ArcContent{int ShapeType;double xmin;double ymin;double xmax;double ymax;int NumParts;int NumPoints;}class ESRI_PolygonContent{int ShapeType;double xmin;double ymin;double xmax;double ymax;int NumParts;int NumPoints;}public bool LoadShapeFile(CGDataAdapter.CGLocalGeoDataAdapter adapter) {string connectionString;OdbcConnection connection;OdbcDataAdapter OdbcAdapter;CGMap.CGGeoLayer geolayer = adapter.getMasterGeoLayer();string shpfilepath = adapter.getPath();string shpfilename = adapter.getFileName();string shxfilepath = shpfilepath.Substring(0, stIndexOf("\\") + 1) + adapter.getFileName() + ".shx";//read out the layer attribute infomationconnectionString = "Dsn=Visual FoxProDatabase;sourcedb=" + shpfilepath + ";sourcetype=DBF;exclusive=No;backgroundfetch=Yes;collate= Machine";connection = new OdbcConnection(connectionString);connection.Open();OdbcAdapter = new OdbcDataAdapter("select * from " + shpfilename, connectionString);// Create new DataTable and DataSource objects.DataSet ds = new DataSet();OdbcAdapter.Fill(ds);connection.Close();if (geolayer == null) return false;try{//先读取.shx文件,得到文件的总字节长度FileStream fs = new FileStream(shxfilepath, FileMode.Open, FileAccess.Read); //文件流形式BinaryReader BinaryFile = new BinaryReader(fs); //二进制读取文件的对象long BytesSum = fs.Length; //得到文件的字节总长int shapecount = (int)(BytesSum - 100) / 8; //得以总记录数目BinaryFile.Close();fs.Close();//打开shp文件if (shxfilepath == ""){// MessageBox.Show("索引文件打开出错");return false;}//打开.shp文件,读取x,y坐标的信息fs = new FileStream(shpfilepath, FileMode.Open, FileAccess.Read); //文件流形式BinaryFile = new BinaryReader(fs); //打开二进制文件BinaryFile.ReadBytes(32); //先读出36个字节,紧接着是Box边界合int shapetype = BinaryFile.ReadInt32();geolayer.envlope.left = BinaryFile.ReadDouble(); //读出整个shp图层的边界合geolayer.envlope.bottom = BinaryFile.ReadDouble();geolayer.envlope.right = BinaryFile.ReadDouble();geolayer.envlope.top = BinaryFile.ReadDouble();BinaryFile.ReadBytes(32); // shp中尚未使用的边界盒//Get Shape Data From Here Onint stype;double x, y;double left, right, top, bottom;int partcount;int pointcount;switch (shapetype){case 1://single pointgeolayer.shapeType = CGConstants.CGShapeType.SHAPE_POINT;for (int i = 0; i < shapecount; i++){CGGeoShape.CGGeoPoint gps = new CGGeoShape.CGGeoPoint();BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype/* stype = BinaryFile.ReadInt32();if (stype != shapetype)continue;*/x = BinaryFile.ReadDouble();y = BinaryFile.ReadDouble();gps.objectID = i;gps.objectUID = i;gps.x = x;gps.y = y;gps.z = 0;gps.envlope.left = gps.x;gps.envlope.right = gps.x;gps.envlope.top = gps.y;gps.envlope.bottom = gps.y;geolayer.getDataContainer().Add(gps);}break;case 8://multi points layerbreak;case 3://Polyline layergeolayer.shapeType = CGConstants.CGShapeType.SHAPE_LINE;for (int i = 0; i < shapecount; i++){geolayer.getAttributeContainer().Add(ds.Tables[0].Rows[i][0] ); //read out the attribute step by stepBinaryFile.ReadBytes(12);// int pos = indexRecs[i].Offset+8;// bb0.position(pos);// stype = bb0.getInt();// if (stype!=nshapetype){// continue;// }left = BinaryFile.ReadDouble();bottom = BinaryFile.ReadDouble();right = BinaryFile.ReadDouble();top = BinaryFile.ReadDouble();partcount = BinaryFile.ReadInt32(); pointcount = BinaryFile.ReadInt32();int[] parts = new int[partcount];int[] partspos = new int[partcount];double[] xpoints = new double[pointcount]; double[] ypoints = new double[pointcount]; double[] zpoints = new double[pointcount];//firstly read out parts begin pos in filefor (int j = 0; j < partcount; j++){parts[j] = BinaryFile.ReadInt32();}//shift them to be points count included in parts if (partcount > 0)partspos[0] = 0;int newpos = 0;for (int j = 0; j <= partcount - 2; j++){parts[j] = parts[j + 1] - parts[j];newpos += parts[j];partspos[j + 1] = newpos;}parts[partcount - 1] = pointcount - parts[partcount - 1];//read out coordinatesfor (int j = 0; j < pointcount; j++){x = BinaryFile.ReadDouble();y = BinaryFile.ReadDouble();xpoints[j] = x;ypoints[j] = y;zpoints[j] = 0;}if (pointcount > 1){CGGeoShape.CGGeoLine gl = new CGGeoShape.CGGeoLine(xpoints, ypoints, zpoints, parts, partspos, pointcount, partcount);gl.envlope.left = left;gl.envlope.right = right;gl.envlope.top = top;gl.envlope.bottom = bottom;gl.objectID = i;gl.objectUID = i;geolayer.getDataContainer().Add(gl);}}break;。
shapefile格式说明及读写代码示例 Shape files数据说明 Shape files是ESRI提供的一种矢量数据格式,它没有拓扑信息,一个Shape files由一组文件组成,其中必要的基本文件包括坐标文件(.shp)、索引文件(.shx)和属性文件(.dbf)三个文件。 坐标文件的结构说明 坐标文件(.shp)用于记录空间坐标信息。它由头文件和实体信息两部分构成(如图2.1所示)。 坐标文件的文件头 坐标文件的文件头是一个长度固定(100 bytes)的记录段,一共有9个int型和7个double型数据,主要记录内容见表2.2。
文件头 记录头 记录内容 记录头 记录内容 记录头 记录内容 记录头 记录内容 „„
记录头 记录内容 图2.1 坐标文件的结构
起始位置 名称 数值 类型 位序 0 File Code 9994 Integer big 4 Unused 0 Integer big 8 Unused 0 Integer big 12 Unused 0 Integer big 16 Unused 0 Integer big 20 Unused 0 Integer big 24 文件长度 文件的实际长度 Integer big 28 版本号 1000 Integer Little 32 几何类型 表示这个Shapefile文件所记录的空间数据的几何类型 Integer Little
36 Xmin 空间数据所占空间范围的X方向最小值 Double Little 44 Ymin 空间数据所占空间范围的Y方向最小值 Double Little 52 Xmax 空间数据所占空间范围的X方向最大值 Double Little 60 Ymax 空间数据所占空间范围的Y方向最大值 Double Little 68* Zmin 空间数据所占空间范围的Z方向最小值 Double Little 76* Zmax 空间数据所占空间范围的Z方向最大值 Double Little 84* Mmin 最小Measure值 Double Little 92* Mmax 最大Measure值 Double Little 表2.2shapefiles 头文件表 注:最后4个加星号特别标示的四个数据只有当这个Shapefile文件包含Z方向坐标或者具有Measure值时才有值,否则为0.0。所谓Measure值,是用于存储需要的附加数据,可以用来记录各种数据,例如权值、道路长度等信息。 位序 细心的读者会注意到表2.2中的数值的位序有Little和big的区别,对于位序是big的数据我们在读取时要小心。通常,数据的位序都是Little,但在有些情况下可能会是big,二者的区别在于它们位序的顺序相反。一个位序为big的数据,如果我们想得到它的真实数值,需要将它的位序转换成Little即可。转换原理非常简单,就是交换字节顺序,下面是作者实现的在两者间进行转换的程序,代码如下: //位序转换程序 unsigned long OnChangeByteOrder (int indata) { char ss[8]; char ee[8]; unsigned long val = unsigned long(indata); _ultoa( val, ss, 16 );//将十六进制的数(val)转到一个字符串(ss)中 int i; int length=strlen(ss); if(length!=8) { for(i=0;i<8-length;i++) ee[i]='0'; for(i=0;i ee[i+8-length]=ss[i]; for(i=0;i<8;i++) ss[i]=ee[i]; } ////******进行倒序 int t; t =ss[0]; ss[0] =ss[6]; ss[6] =t; t =ss[1]; ss[1] =ss[7]; ss[7] =t; t =ss[2]; ss[2] =ss[4]; ss[4] =t; t =ss[3]; ss[3] =ss[5]; ss[5] =t; ////****** //******将存有十六进制数(val)的字符串(ss)中的十六进制数转成十进制数 int value=0; for(i=0;i<8;i++) { int k; CString mass; mass=ss[i]; if(ss[i]=='a' || ss[i]=='b' || ss[i]=='c' || ss[i]=='d' || ss[i]=='e' || ss[i]=='f') k=10+ss[i]-'a'; else sscanf(mass,"%d",&k); value=value+int(k*pow(16,7-i)); } return (value); } Shapefile文件支持的几何类型(ShapeType) Shapefile文件所支持的几何类型如表2.3所示:
编号 几何类型 0 Null Shape(表示这个Shapefile文件不含坐标) 1 Point(表示Shapefile文件记录的是点状目标,但不是多点) 3 PolyLine(表示Shapefile文件记录的是线状目标) 5 Polygon(表示Shapefile文件记录的是面状目标) 8 MultiPoint(表示Shapefile文件记录的是多点,即点集合) 11 PointZ(表示Shapefile文件记录的是三维点状目标) 13 PolyLineZ(表示Shapefile文件记录的是三维线状目标) 15 PolygonZ(表示Shapefile文件记录的是三维面状目标) 18 MultiPointZ(表示Shapefile文件记录的是三维点集合目标) 21 PointM(表示含有Measure值的点状目标) 23 PolyLineM(表示含有Measure值的线状目标) 25 PolygonM(表示含有Measure值的面状目标) 28 MultiPointM(表示含有Measure值的多点目标) 31 MultiPatch(表示复合目标) 表2.3shapefiles文件支持的几何类型 对于一个不是记录Null Shape类型的Shapefile文件,它所记录的空间目标的几何类型必须一致,不能在一个Shapefile文件中同时记录两种不同类型的几何目标。 读取坐标文件(.shp)的文件头的代码如下: void OnReadShp(CString ShpFileName) { FILE* m_ShpFile_fp; //****Shp文件指针 //打开坐标文件 if((m_ShpFile_fp=fopen(ShpFileName,"rb"))==NULL) { return; } //读取坐标文件头的内容开始 int FileCode; int Unused; int FileLength; int Version; int ShapeType; double Xmin; double Ymin; double Xmax; double Ymax; double Zmin; double Zmax; double Mmin; double Mmax; fread(&FileCode, sizeof(int), 1,m_ShpFile_fp); FileCode = OnChangeByteOrder(FileCode); for(i=0;i<5;i++) fread(&Unused,sizeof(int), 1,m_ShpFile_fp); fread(&FileLength, sizeof(int), 1,m_ShpFile_fp); FileLength = OnChangeByteOrder(FileLength); fread(&Version, sizeof(int), 1,m_ShpFile_fp); fread(&ShapeType, sizeof(int), 1,m_ShpFile_fp); fread(&Xmin, sizeof(double),1,m_ShpFile_fp); fread(&Ymin, sizeof(double),1,m_ShpFile_fp); fread(&Xmax, sizeof(double),1,m_ShpFile_fp); fread(&Ymax, sizeof(double),1,m_ShpFile_fp); fread(&Zmin, sizeof(double),1,m_ShpFile_fp); fread(&Zmax, sizeof(double),1,m_ShpFile_fp); fread(&Mmin, sizeof(double),1,m_ShpFile_fp); fread(&Mmax, sizeof(double),1,m_ShpFile_fp); //读取坐标文件头的内容结束 //根据几何类型读取实体信息 „„ } 实体信息的内容 实体信息负责记录坐标信息,它以记录段为基本单位,每一个记录段记录一个地理实体目标的坐标信息,每个记录段分为记录头和记录内容两部分。 记录头的内容包括记录号(Record Number)和坐标记录长度(Content Length) 两个记录项。它们的位序都是big。记录号(Record Number)和坐标记录长度(Content Length) 两个记录项都是int型,并且shapefile文件中的记录号都是从1开始的。 记录内容包括目标的几何类型(ShapeType)和具体的坐标记录(X、Y) ,记录内容因要素几何类型的不同其具体的内容及格式都有所不同。下面分别介绍点状目标(Point)、线状目标(PolyLine)和面状目标(Polygon)三种几何类型的.shp文件的记录内容: 点状目标 shapefile中的点状目标由一对X、Y坐标构成,坐标值为双精度型(double)。点状目标的记录内容如表2.4:
记录项 数值 数据类型 长度 个数 位序 几何类型(ShapeType) 1(表示点状目标) int型 4 1 Little X方向坐标 X方向坐标值 double型 8 1 Little Y方向坐标 Y方向坐标值 double型 8 1 Little 表2.4点状目标的记录内容 下面是读取点状目标的记录内容的代码: OnReadPointShp(CString ShpFileName) { //打开坐标文件 „„ //读取坐标文件头的内容开始 „„ //读取点状目标的实体信息 int RecordNumber; int ContentLength; int num =0; while((fread(&RecordNumber, sizeof(int), 1,ShpFile_fp)!=0)) { num++; fread(&ContentLength,sizeof(int), 1,ShpFile_fp); RecordNumber = OnChangeByteOrder(RecordNumber);