C语言写的SHAPEFILE
纯C#读取SHAPEFILE
综合性实验报告一、实验名称:Shapefile文件的读写二、实验目的:能够熟悉基本的原理,掌握基本技能,并能综合运用课程所学的基本知识和技能解决实践中的问题。
根据此目标,特设计本综合性实验,作为该课程的完整组成部分。
为后续课程有的放矢地开展与安排提供参考。
三、实验准备(数据与软件):开发环境安装:开发环境采用Visual studio ,开发语言为C#相关文档阅读:教材《C#程序设计》教程,孙践知等编著,清华大学出版社;实验指导书自编;ESRI公开的Shapefile白皮书《ESRI Shapefile Technical Description》;IBM公开的DBF文件格式。
四、实验原理(方法):一个.shp文件由文件头和记录组成。
文件头大小为100个字节,其布局如下表:* Unused, with value 0.0, if not Measured or Z typeBig表示大尾(big endian)型字节顺序,即是高低位字节是反序的,主要适用于Sun® or Motorola®平台,而Little表示小尾(little endian)型字节顺序,高低位字节顺序不变,主要使用在PC or Intel®平台。
在读取的字节为Big时,需要进行字节顺序交换,才能得出正确的值。
一个把Big顺序转换为Little顺序的函数可以如下:int Big2LittleEndian(int num){int reverse; //返回结果char bit0, bit1, bit2, bit3;bit0 = (num & 0x000000ff);bit1 = (num & 0x0000ff00) >> 8;bit2 = (num & 0x00ff0000) >> 16;bit3 = (num & 0xff000000) >> 24;reverse = (bit0 << 24) | (bit1 << 16) | (bit2 << 8) | (bit3);return reverse;}文件头中第32-35位字节为一个整型,其值反映了shapefile的图形对象类型,具体值对应含义如下:第36-67个字节包含了图幅的范围大小。
shapefile包的用法
shapefile包的用法Shapefile是一种常用的地理信息系统(GIS)数据格式,用于存储地理空间数据。
它由三个主要文件组成,包括.shp、.shx和.dbf文件,这些文件分别存储空间几何信息、索引信息和属性数据。
Shapefile包是一个用于读取和处理Shapefile文件的Python库。
它提供了一系列函数和类,可用于加载、浏览和操作Shapefile数据。
以下是Shapefile包的常见用法:1.安装Shapefile包:可以使用命令`pip install pyshp`来安装Shapefile包。
2.导入Shapefile包:在Python脚本中,使用`importshapefile`语句来导入Shapefile包。
3.打开Shapefile文件:使用`shapefile.Reader()`函数打开Shapefile文件,例如:`sf = shapefile.Reader("file.shp")`。
4.访问Shapefile的空间几何信息:使用`.shapes()`方法获取Shapefile的几何信息,例如:`shapes = sf.shapes()`。
5.访问Shapefile的属性数据:使用`.records()`方法获取Shapefile的属性数据,例如:`records = sf.records()`。
6.遍历Shapefile的空间几何信息和属性数据:可以使用循环来遍历Shapefile的空间几何信息和属性数据,例如:```pythonfor shape in shapes:#处理空间几何信息# ...for record in records:#处理属性数据# ...```7.获取Shapefile的字段信息:使用`.fields`属性获取Shapefile的字段信息,例如:`fields = sf.fields`。
8.获取Shapefile的坐标系:使用`.crs`属性获取Shapefile的坐标系信息,例如:`crs = sf.crs`。
资料: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数据与其他形式数据的转化过程。
C#读取shapefile文件
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;。
C语言shape文件读取
读取数据
//读取之前分配了存储空间的Parts和points数据
将结构体中 用不到的变 量级指针置 空
心得体会
• 这次试验的关键点之一是要读出存储的文件数。因此我们选用 了指针跳动的方式来完成。 • 在试验过程中通过探索、试验,我们找到了用feof(file)不能判 断文件尾的原因,以及解决方法。
读 取 文 件 头
这部分数据 在文件中采 取大端存储, 从文件中读 出后要进行 位序转换才 能得到正确 数值
实验目的
判断数据类型及记录数并分配内存空间
判断记录数 循环每做一 次记录数加 一
读取数据
判断文件 尾
这里不能使用feof(file)即【 while(feof(file)==0)】 的方式来判断文件尾!因为即使已经到达了文 件尾,但file->flag仍然没有被置为_IOEOF,因 而feof()仍然没有探测到文件结尾
Shapefile文件的读取
Hale Waihona Puke 实验目的• 读取包含常规点、线、面矢量数据的.shp 文件,掌握 .shp文件的基本存储结构,并 以此为基础深入理解shapefile的矢量数据 结构。
Shapefile文件格式
每条记录长度:(8+记录长度*2字节)
文件头
信息记录
基本识 别信息
空间信 息概况
几何体空间坐标记录
100字节
记录头 shapeType 共8字节 4字节
实验方案
1 2 3 4
读文件头
判断有多少条记录 分配内存空间
读取数据
文件头说明: FileCode(文件代码=9994) 5个unused FileLength 整个文件的长度(包括文件头,以16字节为单位) FileVersion 文件版本=10
shapefile格式说明及读写代码示例
shapefile格式说明及读写代码示例Shape files数据说明Shape files是ESRI提供的一种矢量数据格式,它没有拓扑信息,一个Shape files由一组文件组成,其中必要的基本文件包括坐标文件(.shp)、索引文件(.shx)和属性文件(.dbf)三个文件。
坐标文件的结构说明坐标文件(.shp)用于记录空间坐标信息。
它由头文件和实体信息两部分构成(如图2.1所示)。
坐标文件的文件头坐标文件的文件头是一个长度固定(100 bytes)的记录段,一共有9个int型和7个double型数据,主要记录内容见表2.2。
表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<length;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';elsesscanf(mass,"%d",&k);value=value+int(k*pow(16,7-i));}return (value);}Shapefile文件支持的几何类型(ShapeType)Shapefile文件所支持的几何类型如表2.3所示:表2.3shapefiles文件支持的几何类型对于一个不是记录Null Shape类型的Shapefile文件,它所记录的空间目标的几何类型必须一致,不能在一个Shapefile文件中同时记录两种不同类型的几何目标。
shapefile包的用法 -回复
shapefile包的用法-回复Shapefile是一种经常被使用的地理信息系统(GIS)文件格式,它可以用来存储和传输地理位置、空间对象和属性信息。
它由几个文件组成,包括.shp、.shx、.dbf和.prj文件。
这篇文章将一步一步地介绍如何使用shapefile包来读取、创建和编辑shapefile文件。
第一步:安装shapefile包首先,在Python环境中安装shapefile包。
可以使用以下命令在终端或命令提示符中安装:pip install pyshp安装完成后,你就可以在Python程序中使用shapefile包了。
第二步:导入shapefile包在Python程序的开头,导入shapefile包:pythonimport shapefile第三步:读取shapefile文件使用以下代码来读取一个shapefile文件:pythonsf = shapefile.Reader("path/to/shapefile.shp")这将创建一个`ShapefileReader`对象,用于读取shapefile文件的几何形状、属性以及其他相关信息。
第四步:访问shapefile的几何对象和属性可以使用以下代码来访问shapefile中的几何对象和属性:pythonshapes = sf.shapes() # 获取所有几何形状records = sf.records() # 获取所有属性记录通过迭代遍历这些几何形状和属性记录,可以获取每个几何形状的坐标和每个属性记录的值:pythonfor shape in shapes:points = shape.points # 获取几何形状的坐标列表# 处理坐标数据...for record in records:attributes = record.attributes # 获取属性记录的值# 处理属性数据...第五步:创建shapefile文件shapefile包还允许创建新的shapefile文件并添加几何对象和属性。
C#读取shapefile文件
C#读取shapefile文件(不用AE)1.创建工程文件,选窗体应用程序,命名为:EsriShpReader2.添加SplitContainer控件到窗体3.在SplitContainer.panel1中添加两个按钮Button,text属性分别改为“打开”,“刷新”4. 在SplitContainer.panel2中添加panel容器,用来显示图像Dock设置为Fill,背景颜色设置为白色5.界面图如下:6.在过程文件中添加类文件,命名为ShpClass编写点、线、面、三个类class Point//点类{public double X;public double Y;}class Polyline//线类{public double[] Box=new double[4];public int NumParts;public int NumPoints;public ArrayList Parts; //在部分中第一个点的索引public ArrayList Points; //所有部分的点}class Polygon : Polyline//面类{ }7.在Form1中添加ArrayList polygons = new ArrayList();//面集合ArrayList polylines = new ArrayList();//线集合ArrayList points = new ArrayList();//点集合Pen pen = new Pen(Color.Black, 1);//定义画笔int ShapeType;//shp文件类型int count;//计数double xmin, ymin, xmax, ymax;double n1, n2;//x,y轴放大倍数8.添加button1的Click事件,添加代码string shpfilepath = "";openFileDialog1.Filter = "shapefiles(*.shp)|*.shp|All files(*.*)|*.*";//打开文件路径if (openFileDialog1.ShowDialog() == DialogResult.OK){shpfilepath = openFileDialog1.FileName;BinaryReader br = new BinaryReader(openFileDialog1.OpenFile());//读取文件过程br.ReadBytes(24);int FileLength = br.ReadInt32();//<0代表数据长度未知int FileBanben = br.ReadInt32();ShapeType = br.ReadInt32();xmin = br.ReadDouble();ymax = -1 * br.ReadDouble();xmax = br.ReadDouble();ymin = -1 * br.ReadDouble();double width = xmax - xmin;double height = ymax - ymin;n1 = (float)(this.panel1.Width * 0.9 / width);//x轴放大倍数n2 = (float)(this.panel1.Height * 0.9 / height);//y轴放大倍数br.ReadBytes(32);switch (ShapeType){case 1:points.Clear();while (br.PeekChar() != -1){Point point = new Point();uint RecordNum = br.ReadUInt32();int DataLength = br.ReadInt32();//读取第i个记录br.ReadInt32();point.X = br.ReadDouble();point.Y = -1 * br.ReadDouble();points.Add(point);}StreamWriter sw = new StreamWriter("point.txt");foreach (Point p in points){sw.WriteLine("{0},{1},{2} ", p.X, -1 * p.Y, 0);}sw.Close();break;case 3:polylines.Clear();while (br.PeekChar() != -1){Polyline polyline = new Polyline();polyline.Box = new double[4];polyline.Parts = new ArrayList();polyline.Points = new ArrayList();uint RecordNum = br.ReadUInt32();int DataLength = br.ReadInt32();//读取第i个记录br.ReadInt32();polyline.Box[0] = br.ReadDouble();polyline.Box[1] = br.ReadDouble();polyline.Box[2] = br.ReadDouble();polyline.Box[3] = br.ReadDouble();polyline.NumParts = br.ReadInt32();polyline.NumPoints = br.ReadInt32();for (int i = 0; i < polyline.NumParts; i++) {int parts = new int();parts = br.ReadInt32();polyline.Parts.Add(parts);}for (int j = 0; j < polyline.NumPoints; j++){Point pointtemp = new Point();pointtemp.X = br.ReadDouble();pointtemp.Y = -1 * br.ReadDouble();polyline.Points.Add(pointtemp);}polylines.Add(polyline);}StreamWriter sw2 = new StreamWriter("line.txt");count = 1;foreach (Polyline p in polylines){for (int i = 0; i < p.NumParts; i++){int startpoint;int endpoint;if (i == p.NumParts - 1){startpoint = (int)p.Parts[i];endpoint = p.NumPoints;}else{startpoint = (int)p.Parts[i];endpoint = (int)p.Parts[i + 1];}sw2.WriteLine("线" + count.ToString() + ":");for (int k = 0, j = startpoint; j < endpoint; j++, k++){Point ps = (Point)p.Points[j];sw2.WriteLine(" {0},{1},{2} ", ps.X, -1 * ps.Y, 0);}count++;}}sw2.Close();break;case 5:polygons.Clear();while (br.PeekChar() != -1){Polygon polygon = new Polygon();polygon.Parts = new ArrayList();polygon.Points = new ArrayList();uint RecordNum = br.ReadUInt32();int DataLength = br.ReadInt32();//读取第i个记录int m = br.ReadInt32();for (int i = 0; i < 4; i++){polygon.Box[i] = br.ReadDouble();}polygon.NumParts = br.ReadInt32();polygon.NumPoints = br.ReadInt32();for (int j = 0; j < polygon.NumParts; j++){int parts = new int();parts = br.ReadInt32();polygon.Parts.Add(parts);}for (int j = 0; j < polygon.NumPoints; j++){Point pointtemp = new Point();pointtemp.X = br.ReadDouble();pointtemp.Y = -1 * br.ReadDouble();polygon.Points.Add(pointtemp);}polygons.Add(polygon);}StreamWriter sw1 = new StreamWriter("polygon.txt");count = 1;foreach (Polygon p in polygons){for (int i = 0; i < p.NumParts; i++){int startpoint;int endpoint;if (i == p.NumParts - 1){startpoint = (int)p.Parts[i];endpoint = p.NumPoints;}else{startpoint = (int)p.Parts[i];endpoint= (int)p.Parts[i + 1];}sw1.WriteLine("多边形" + count.ToString() + ":");for (int k = 0, j = startpoint; j < endpoint; j++, k++){Point ps = (Point)p.Points[j];sw1.WriteLine(" {0},{1},{2} ", ps.X, -1 * ps.Y, 0);}count++;}}sw1.Close();break;}}9. 添加button2的Click事件,添加代码double width = xmax - xmin;//图像宽double height = ymax - ymin;//图像高n1 = (float)(this.panel1.Width * 0.9 / width);//x轴放大倍数n2 = (float)(this.panel1.Height * 0.9 / height);//y轴放大倍数this.panel1.Refresh();10.添加panel1的paint事件private void panel1_Paint(object sender, PaintEventArgs e){PointF[] point;switch (ShapeType){case 1://点类型foreach (Point p in points){PointF pp = new PointF();pp.X = (float)(10 + (p.X - xmin) * n1);pp.Y = (float)(10 + (p.Y - ymin) * n2);e.Graphics.DrawEllipse(pen, pp.X, pp.Y, 1.5f, 1.5f);break;case 3://线类型foreach (Polyline p in polylines){for (int i = 0; i < p.NumParts; i++){int startpoint;int endpoint;point = null;if (i == p.NumParts - 1){startpoint = (int)p.Parts[i];endpoint = p.NumPoints;}else{startpoint = (int)p.Parts[i];endpoint = (int)p.Parts[i + 1];}point = new PointF[endpoint - startpoint];for (int k = 0, j = startpoint; j < endpoint; j++, k++){Point ps = (Point)p.Points[j];point[k].X = (float)(10 + (ps.X - xmin) * n1);point[k].Y = (float)(10 + (ps.Y - ymin) * n2);}e.Graphics.DrawLines(pen, point);}break;case 5://面类型foreach (Polygon p in polygons){for (int i = 0; i < p.NumParts; i++){int startpoint;int endpoint;point = null;if (i == p.NumParts - 1){startpoint = (int)p.Parts[i];endpoint = p.NumPoints;}else{startpoint = (int)p.Parts[i];endpoint = (int)p.Parts[i + 1];}point = new PointF[endpoint - startpoint];for (int k = 0, j = startpoint; j < endpoint; j++, k++) {Point ps = (Point)p.Points[j];point[k].X = (float)(10 + (ps.X - xmin) * n1);point[k].Y = (float)(10 + (ps.Y - ymin) * n2);}e.Graphics.DrawPolygon(pen, point);}}break;}}11.编译运行。
Shapefile
一、什么是shapefile?Shapefile是一种用于存储地理要素的几何位置和属性信息的非拓扑简单格式。
shapefile 中的地理要素可通过点、线或面(区域)来表示。
包含shapefile的工作空间还可以包含dBASE 表,它们用于存储可连接到shapefile的要素的附加属性。
(一)下面是shapefile如何在ArcCatalog中显示的示例。
还能看到dBASE文件(它可能与shapefile相关联)。
默认情况下,具有文件扩展名.txt、.asc、.csv或.tab 的所有文件将以文本文件的形式显示在ArcCatalog中。
但在选项对话框中,您可以选择其中哪些文件类型应显示为文本文件以及哪些不能显示在目录树中。
当文本文件包含逗号分隔和制表符分隔的值时,您能够在ArcCatalog表视图中看到它们的内容并可将其连接到地理要素。
在ArcCatalog中,可将文本文件删除,但其内容为只读。
可以在图层“属性”对话框的连接和关联选项卡中,将dBASE表或文本文件中存储的属性连接到shapefile中的要素。
如果表包含描述空间位置的信息(例如,x,y,z坐标或街道地址),则可以使用ArcCatalog中提供的工具创建用以表示这些位置的shapefile。
(二)编辑shapefile可以在具有任意许可等级的ArcGIS for Desktop(ArcGIS for Desktop Basic、ArcGIS for Desktop Standard或ArcGIS for Desktop Advanced)中编辑shapefile。
但要想利用高级编辑功能(例如,拓扑),则需要将shapefile作为要素类导入到地理数据库中。
(三)将shapefile和dBASE表导入到地理数据库要素类和表shapefile中的所有要素类型都会在地理数据库中转换为几何类型。
与coverage 不同的是,shapefile要素类型与地理数据库中存储的几何类型相类似,因此转换要更为简单。
Shapefile格式说明
Shapefile格式说明及读写代码示例Shape files 数据说明Shape files 是ESRI 提供的一种矢量数据格式,它没有拓扑信息,一个Shape files 由一组文件组成,其中必要的基本文件包括坐标文件( .shp )、索引文件( .shx )和属性文件( .dbf )三个文件。
坐标文件的结构说明坐标文件(.shp) 用于记录空间坐标信息。
它由头文件和实体信息两部分构成(如图 2.1 所示)。
坐标文件的文件头坐标文件的文件头是一个长度固定(100 bytes) 的记录段,一共有9 个int 型和7 个double 型数据,主要记录内容见表2.2 。
图2.1 坐标文件的结构表2.2shapefiles 头文件表注:最后4 个加星号特别标示的四个数据只有当这个Shapefile 文件包含Z 方向坐标或者具有Measure 值时才有值,否则为0.0各种数据,例如权值、道路长度等信息。
位序细心的读者会注意到表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<length;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';elsesscanf(mass,"%d",&k);value=value+int(k*pow(16,7-i));}return (value);}Shapefile 文件支持的几何类型(ShapeType )Shapefile 文件所支持的几何类型如表2.3 所示:表2.3shapefiles 文件支持的几何类型对于一个不是记录Null Shape 类型的Shapefile 文件,它所记录的空间目标的几何类型必须一致,不能在一个Shapefile 文件中同时记录两种不同类型的几何目标。
结合C++和GDAL实现shapefile(shp)文件的创建和写入
结合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打开,显⽰如下。
shapefile文件
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文件中的属性记录必须和主文件中的记录是相同顺序的。
命名习惯所有文件名都符合8.3命名习惯。
主文件,索引文件和dBASE文件有相同的前缀。
前缀必须是由字符或数字(a-Z,0-9)开始,后跟0到7个字符(a-Z,0-9,_,)主文件的后缀是.shp,索引文件的后缀是.shx,dBASE表的后缀是.dbf。
文件名中的所有字母在对文件名敏感的操作系统中都是小写的。
例子主文件:counties.shp 索引文件:counties.shx dBASE表:ounties.dbf数字类型一个shape文件存储整数和双精度数,本文档的余数指以下类型:整数:有符号32位整数(4字节)双精度:有符号64位IEEE双精度浮点数(8字节)浮点数必须是数字的值。
负无穷,正无穷和非数字(NaN)值在shape文件不被允许。
然而shape文件支持'没有数据'的值这样的概念,但是只用于衡量。
数据的天空?如何用IDL处理Shapefile数据
数据的天空?如何用IDL处理Shapefile数据Bloged in IDL编程作者: wulizong 星期四 07月 16, 2009遥感和GIS不分家,IDL擅长处理遥感数据,但偶尔也需要用来处理一些GIS数据,不过还好IDL能处理Shapefile数据。
使用IDL处理shapefile格式,需要了解IDLffShape对象,IDL帮助中有一些说明和代码,但过于简单,不熟悉的人很难上手,现对几个关键点进行说明:一、读取shapefile文件1.首先要打开文件我们用Arcview带的数据做例子吧,就用那个国界数据吧。
创建和销毁idlffshape分别使用的是IDL处理对象的通用命令OBJ_new和Obj_Destroy,每建立一个对象都要记着要销毁,否则会出现内存不足问题。
pro readshapefileshapefile='C:\ESRI\ESRIDATA\WORLD\country.shp' ;定义shape文件位置oshp=Obj_New('IDLffShape',filename)print oshp;中间处理代码Obj_destroy,oshp ;销毁一个shape对象end如果读取错误,oshp会返回-1,否则得话返回的就是一个结构体。
2.获取整体描述信息读完shape对象后,就需要读几何数据和属性表数据了。
Shapefile数据由几何体(或实体Entity)和属性表两部分组成,而几何体一般又包括点(point)、线(polyline)和多边形(polygon)(当然也有其它类型,但不常用)。
属性表包括属性表结构、字段个数和记录个数,属性表记录数与实地必须一一对应,属性表的结构又包含字段名,字段类型,字段长度和精确度。
在IDL读取数据前,需要了解一些全局属性,知道有多少个几何体和记录,属性表中有多少个字段,就需要用GetProperty方法,它查询shape文件的属性,包括实体类型,实体个数,属性表结构,属性表字段个数,记录数等,代码如下:pro readshapefileshapefile='C:\ESRI\ESRIDATA\WORLD\country.shp' ;定义shape文件位置oshp=Obj_New('IDLffShape',filename)oshp->getproperty,n_entities=n_ent,Attribute_info=attr_inf o,n_attributes=n_attr,Entity_type=ent_typeprint,'实体个数:'n_entprint,'属性表字段数:',n_attrprint,'实体类型代码:',ent_typeObj_destroy,oshp ;销毁一个shape对象end3.再了解几个概念•bouns存储的是每个实体的范围,是一个有8个元素的数组([x0,x1,x2,x3,x4,x5,x6,x7]),其中x0 —最小x值,x1 —最小y值,x2最小z值(高度),x3 —最小M值(测量值,一般不用)x4-x7就是最大值了。
shapefile
ESRI Shapefile Technical Description An ESRI White Paper—July 1998Copyright © 1997, 1998 Environmental Systems Research Institute, Inc.All rights reserved.Printed in the United States of America.The information contained in this document is the exclusive property of Environmental Systems Research Institute, Inc. This work is protected under United States copyright law and other international copyright treaties and conventions. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, or by any information storage or retrieval system, except as expressly permitted in writing by Environmental Systems Research Institute, Inc. All requests should be sent to Attention: Contracts Manager, Environmental Systems Research Institute, Inc., 380 New York Street, Redlands, CA 92373-8100 USA.The information contained in this document is subject to change without notice.U.S. GOVERNMENT RESTRICTED/LIMITED RIGHTSAny software, documentation, and/or data delivered hereunder is subject to the terms of the License Agreement. In no event shall the Government acquire greater than RESTRICTED/LIMITED RIGHTS. At a minimum, use, duplication, or disclosure by the Government is subject to restrictions as set forth in FAR §52.227-14 Alternates I, II, and III (JUN 1987); FAR §52.227-19 (JUN 1987) and/or FAR §12.211/12.212 (Commercial Technical Data/Computer Software); and DFARS §252.227-7015 (NOV 1995) (Technical Data) and/or DFARS §227.7202 (Computer Software), as applicable. Contractor/Manufacturer is Environmental Systems Research Institute, Inc., 380 New York Street, Redlands, CA 92373-8100 USA.In the United States and in some countries, ARC/INFO, ArcCAD, ArcView, ESRI, and PC ARC/INFO are registered trademarks; 3D Analyst, ADF, AML, ARC COGO, ARC GRID, ARC NETWORK, ARC News, ARC TIN, ARC/INFO, ARC/INFO LIBRARIAN, ARC/INFO—Professional GIS, ARC/INFO—The World's GIS, ArcAtlas, ArcBrowser, ArcCAD, ArcCensus, ArcCity, ArcDoc, ARCEDIT, ArcExplorer, ArcExpress, ARCPLOT, ArcPress, ArcScan, ArcScene, ArcSchool, ArcSdl, ARCSHELL, ArcStorm, ArcTools, ArcUSA, ArcUser, ArcView, ArcWorld, Atlas GIS, AtlasWare, Avenue, Business MAP, DAK, DATABASE INTEGRATOR, DBI Kit, ESRI, ESRI—Team GIS, ESRI—The GIS People, FormEdit, Geographic Design System, GIS by ESRI, GIS for Everyone, GISData Server, IMAGE INTEGRATOR, Insite MAP, MapCafé, MapObjects, NetEngine, PC ARC/INFO, PC ARCEDIT, PC ARCPLOT, PC ARCSHELL, PC DATA CONVERSION, PC NETWORK, PC OVERLAY, PC STARTER KIT, PC TABLES, SDE, SML, Spatial Database Engine, StreetMap, TABLES, the ARC COGO logo, the ARC GRID logo, the ARC NETWORK logo, the ARC TIN logo, the ARC/INFO logo, the ArcCAD logo, the ArcCAD WorkBench logo, the ArcData emblem, the ArcData logo, the ArcData Online logo, the ARCEDIT logo, the ArcExplorer logo, the ArcExpress logo, the ARCPLOT logo, the ArcPress logo, the ArcPress for ArcView logo, the ArcScan logo, the ArcStorm logo, the ArcTools logo, the ArcView 3D Analyst logo, the ArcView Data Publisher logo, the ArcView GIS logo, the ArcView Internet Map Server logo, the ArcView Network Analyst logo, the ArcView Spatial Analyst logo, the ArcView StreetMap logo, the Atlas GIS logo, the Avenue logo, the Business MAP logo, the Business MAP PRO logo, the Common Design Mark, the DAK logo, the ESRI corporate logo, the ESRI globe logo, the MapCafé logo, the MapObjects logo, the MapObjects Internet Map Server logo, the NetEngine logo, the PC ARC/INFO logo, the SDE logo, the SDE CAD Client logo, The World's Leading Desktop GIS, ViewMaker, Water Writes, and Your Personal Geographic Information System are trademarks; and ArcData, ARCMAIL, ArcOpen, ArcQuest, ArcWatch, ArcWeb, Rent-a-Tech, , and @ are service marks of Environmental Systems Research Institute, Inc.The names of other companies and products herein are trademarks or registered trademarks of their respective trademark owners.J-7855ESRI Shapefile TechnicalDescriptionAn ESRI White PaperContents PageWhy Shapefiles?1Shapefile Technical Description2Organization of the Main File 2Main File Record Contents5Organization of the Index File 23Organization of the dBASE File 25Glossary26ESRI White Paper iJ-7855ESRI White PaperESRI Shapefile Technical Description This document defines the shapefile (.shp) spatial data format and describes why shapefiles are important. It lists the tools available in Environmental Systems Research Institute, Inc. (ESRI), software for creating shapefiles directly or converting data into shapefiles from other formats. This document also provides all the technical information necessary for writing a computer program to create shapefiles without the use of ESRI ® software for organizations that want to write their own data translators.Why Shapefiles?A shapefile stores nontopological geometry and attribute information for the spatial features in a data set. The geometry for a feature is stored as a shape comprising a set of vector coordinates.Because shapefiles do not have the processing overhead of a topological data structure,they have advantages over other data sources such as faster drawing speed and edit ability. Shapefiles handle single features that overlap or that are noncontiguous. They also typically require less disk space and are easier to read and write.Shapefiles can support point, line, and area features. Area features are represented as closed loop, double-digitized polygons. Attributes are held in a dBASE ® format file.Each attribute record has a one-to-one relationship with the associated shape record.How Shapefiles Can Be Created Shapefiles can be created with the following four general methods:Export Shapefiles can be created by exporting any data source to a shapefile using ARC/INFO ®, PC ARC/INFO ®, Spatial Database Engine ™ (SDE ™), ArcView ® GIS,or Business MAP ™ software.Digitize Shapefiles can be created directly by digitizing shapes using ArcView GIS feature creation tools.Programming Using Avenue ™ (ArcView GIS), MapObjects ™, ARC Macro Language (AML ™) (ARC/INFO), or Simple Macro Language (SML ™)(PC ARC/INFO) software, you can create shapefiles within your programs.Write directly to the shapefile specifications by creating a program.ESRI Shapefile Technical Description J-7855March 19982SDE, ARC/INFO, PC ARC/INFO, Data Automation Kit (DAK ™), and ArcCAD ®software provide shape-to-coverage data translators, and ARC/INFO also provides a coverage-to-shape translator. For exchange with other data formats, the shapefile specifications are published in this paper. Other data streams, such as those from global positioning system (GPS) receivers, can also be stored as shapefiles or X,Y event tables.Shapefile Technical DescriptionComputer programs can be created to read or write shapefiles using the technical specification in this section.An ESRI shapefile consists of a main file, an index file, and a dBASE table. The main file is a direct access, variable-record-length file in which each record describes a shape with a list of its vertices. In the index file, each record contains the offset of the corresponding main file record from the beginning of the main file. The dBASE table contains feature attributes with one record per feature. The one-to-one relationship between geometry and attributes is based on record number. Attribute records in the dBASE file must be in the same order as records in the main file.Naming ConventionsAll file names adhere to the 8.3 naming convention. The main file, the index file, and the dBASE file have the same prefix. The prefix must start with an alphanumeric character (a –Z, 0–9), followed by zero or up to seven characters (a –Z, 0–9, _, -). The suffix for the main file is .shp. The suffix for the index file is .shx. The suffix for the dBASE table is .dbf. All letters in a file name are in lower case on operating systems with case sensitive file names.ExamplesMain file:counties.shp Index file:counties.shx dBASE table:counties.dbf Numeric TypesA shapefile stores integer and double-precision numbers. The remainder of this document will refer to the following types:Integer:Signed 32-bit integer (4 bytes)Double:Signed 64-bit IEEE double-precision floating point number (8 bytes)Floating point numbers must be numeric values. Positive infinity, negative infinity, and Not-a-Number (NaN) values are not allowed in shapefiles. Nevertheless, shapefiles support the concept of "no data" values, but they are currently used only for measures.Any floating point number smaller than –1038 is considered by a shapefile reader to represent a "no data" value.The first section below describes the general structure and organization of the shapefile.The second section describes the record contents for each type of shape supported in the anization of the Main File The main file (.shp) contains a fixed-length file header followed by variable-lengthrecords. Each variable-length record is made up of a fixed-length record header followed by variable-length record contents. Figure 1 illustrates the main file organization.ESRI Shapefile Technical Description J-7855Figure 1Organization of the Main FileFile HeaderRecord Header Record ContentsRecord Header Record ContentsRecord Header Record ContentsRecord Header Record Contents. . .. . .Record Header Record ContentsByte Order All the contents in a shapefile can be divided into two categories:Data related•Main file record contents•Main file header’s data description fields (Shape Type, Bounding Box, etc.)File management related•File and record lengths•Record offsets, and so onThe integers and double-precision integers that make up the data description fields in thefile header (identified below) and record contents in the main file are in little endian (PCor Intel®) byte order. The integers and double-precision floating point numbers that makeup the rest of the file and file management are in big endian (Sun® or Motorola®) byteorder.The Main File Header The main file header is 100 bytes long. Table 1 shows the fields in the file header withtheir byte position, value, type, and byte order. In the table, position is with respect to thestart of the file.ESRI White Paper3ESRI Shapefile Technical DescriptionJ-7855Table 1Description of the Main File HeaderBytePosition Field Value Type OrderByte 0File Code9994Integer BigByte 4Unused0Integer BigByte 8Unused0Integer BigByte 12Unused0Integer BigByte 16Unused0Integer BigByte 20Unused0Integer BigByte 24File Length File Length Integer BigByte 28Version1000Integer LittleByte 32Shape Type Shape Type Integer LittleByte 36Bounding Box Xmin Double LittleByte 44Bounding Box Ymin Double LittleByte 52Bounding Box Xmax Double LittleByte 60Bounding Box Ymax Double LittleByte 68*Bounding Box Zmin Double LittleByte 76*Bounding Box Zmax Double LittleByte 84*Bounding Box Mmin Double LittleByte 92*Bounding Box Mmax Double Little*Unused, with value 0.0, if not Measured or Z typeThe value for file length is the total length of the file in 16-bit words (including the fifty16-bit words that make up the header).All the non-Null shapes in a shapefile are required to be of the same shape type. Thevalues for shape type are as follows:Value Shape Type0Null Shape1Point3PolyLine5Polygon8MultiPoint11PointZ13PolyLineZ15PolygonZ18MultiPointZ21PointM23PolyLineM25PolygonM28MultiPointM31MultiPatchMarch 19984ESRI Shapefile Technical Description J-7855ESRI White Paper 5Shape types not specified above (2, 4, 6, etc., and up to 33) are reserved for future use.Currently, shapefiles are restricted to contain the same type of shape as specified above.In the future, shapefiles may be allowed to contain more than one shape type. If mixed shape types are implemented, the shape type field in the header will flag the file as such.The Bounding Box in the main file header stores the actual extent of the shapes in the file:the minimum bounding rectangle orthogonal to the X and Y (and potentially the M and Z)axes that contains all shapes. If the shapefile is empty (that is, has no records), the values for Xmin, Ymin, Xmax, and Ymax are unspecified. Mmin and Mmax can contain "no data" values (see Numeric Types on page 2) for shapefiles of measured shape types that contain no measures.Record HeadersThe header for each record stores the record number and content length for the record.Record headers have a fixed length of 8 bytes. Table 2 shows the fields in the file header with their byte position, value, type, and byte order. In the table, position is with respect to the start of the record.Table 2Description of Main File Record Headers Byte Position Field Value Type Order Byte 0Record Number Record Number Integer Big Byte 4Content Length Content Length Integer Big Record numbers begin at 1.The content length for a record is the length of the record contents section measured in 16-bit words. Each record, therefore, contributes (4 + content length) 16-bit words toward the total length of the file, as stored at Byte 24 in the file header.Main FileRecord Contents Shapefile record contents consist of a shape type followed by the geometric data for the shape. The length of the record contents depends on the number of parts and vertices in a shape. For each shape type, we first describe the shape and then its mapping to record contents on disk. In Tables 3 through 16, position is with respect to the start of the record contents.Null Shapes A shape type of 0 indicates a null shape, with no geometric data for the shape. Eachfeature type (point, line, polygon, etc.) supports nulls it is valid to have points and null points in the same shapefile. Often null shapes are place holders; they are used during shapefile creation and are populated with geometric data soon after they are created.ESRI Shapefile Technical Description J-7855March 19986Table 3Null Shape Record Contents Byte Position Field Value Type Number Order Byte 0Shape Type 0Integer 1Little Shape Types in X,Y SpacePointA point consists of a pair of double-precision coordinates in the order X,Y.Point {Double X // X coordinate Double Y // Y coordinate }Table 4Point Record Contents Byte Position Field Value Type Number Order Byte 0Shape Type 1Integer 1Little Byte 4X X Double 1Little Byte 12Y Y Double 1Little MultiPoint A MultiPoint represents a set of points, as follows:MultiPoint{Double[4]Box // Bounding Box Integer NumPoints // Number of Points Point[NumPoints]Points // The Points in the Set }The Bounding Box is stored in the order Xmin, Ymin, Xmax, Ymax.J-7855Table 5MultiPoint Record ContentsBytePosition Field Value Type Number OrderByte 0Shape Type8Integer1LittleByte 4Box Box Double4LittleByte 36NumPoints NumPoints Integer1LittleByte 40Points Points Point NumPoints Little PolyLine A PolyLine is an ordered set of vertices that consists of one or more parts. A part is aconnected sequence of two or more points. Parts may or may not be connected to oneanother. Parts may or may not intersect one another.Because this specification does not forbid consecutive points with identical coordinates,shapefile readers must handle such cases. On the other hand, the degenerate, zero lengthparts that might result are not allowed.PolyLine{Double[4]Box// Bounding BoxInteger NumParts// Number of PartsInteger NumPoints// Total Number of PointsInteger[NumParts]Parts// Index to First Point in PartPoint[NumPoints]Points// Points for All Parts}The fields for a PolyLine are described in detail below:Box The Bounding Box for the PolyLine stored in the order Xmin, Ymin, Xmax,Ymax.NumParts The number of parts in the PolyLine.NumPoints The total number of points for all parts.Parts An array of length NumParts. Stores, for each PolyLine, the index of itsfirst point in the points array. Array indexes are with respect to 0.Points An array of length NumPoints. The points for each part in the PolyLine arestored end to end. The points for Part 2 follow the points for Part 1, and soon. The parts array holds the array index of the starting point for each part.There is no delimiter in the points array between parts.J-7855Table 6PolyLine Record ContentsByte Position Field Value Type Number OrderByte 0Shape Type3Integer1LittleByte 4Box Box Double4LittleByte 36NumParts NumParts Integer1LittleByte 40NumPoints NumPoints Integer1LittleByte 44Parts Parts Integer NumParts LittleByte X Points Points Point NumPoints LittleNote:X = 44 + 4 * NumPartsPolygon A polygon consists of one or more rings. A ring is a connected sequence of four or more points that form a closed, non-self-intersecting loop. A polygon may contain multipleouter rings. The order of vertices or orientation for a ring indicates which side of the ringis the interior of the polygon. The neighborhood to the right of an observer walking alongthe ring in vertex order is the neighborhood inside the polygon. Vertices of rings definingholes in polygons are in a counterclockwise direction. Vertices for a single, ringedpolygon are, therefore, always in clockwise order. The rings of a polygon are referred toas its parts.Because this specification does not forbid consecutive points with identical coordinates,shapefile readers must handle such cases. On the other hand, the degenerate, zero lengthor zero area parts that might result are not allowed.The Polygon structure is identical to the PolyLine structure, as follows:Polygon{Double[4]Box// Bounding BoxInteger NumParts// Number of PartsInteger NumPoints// Total Number of PointsInteger[NumParts]Parts// Index to First Point in PartPoint[NumPoints]Points// Points for All Parts}The fields for a polygon are described in detail below:Box The Bounding Box for the polygon stored in the order Xmin, Ymin, Xmax,Ymax.NumParts The number of rings in the polygon.NumPoints The total number of points for all rings.J-7855Parts An array of length NumParts. Stores, for each ring, the index of its firstpoint in the points array. Array indexes are with respect to 0.PointsAn array of length NumPoints. The points for each ring in the polygon arestored end to end. The points for Ring 2 follow the points for Ring 1, and soon. The parts array holds the array index of the starting point for each ring.There is no delimiter in the points array between rings.The instance diagram in Figure 2 illustrates the representation of polygons. This figure shows a polygon with one hole and a total of eight vertices.The following are important notes about Polygon shapes.The rings are closed (the first and last vertex of a ring MUST be the same).The order of rings in the points array is not significant.Polygons stored in a shapefile must be clean. A clean polygon is one that1.Has no self-intersections. This means that a segment belonging to one ring maynot intersect a segment belonging to another ring. The rings of a polygon cantouch each other at vertices but not along segments. Colinear segments areconsidered intersecting.2. Has the inside of the polygon on the "correct" side of the line that defines it. Theneighborhood to the right of an observer walking along the ring in vertex order is the inside of the polygon. Vertices for a single, ringed polygon are, therefore,always in clockwise order. Rings defining holes in these polygons have acounterclockwise orientation. "Dirty" polygons occur when the rings that define holes in the polygon also go clockwise, which causes overlapping interiors.Figure 2An Example Polygon Instancev1v2v3v4J-7855For this example, NumParts equals 2 and NumPoints equals 10. Note that the order of thepoints for the donut (hole) polygon are reversed below.050123456789Parts:Points:Table 7Polygon Record Contents Byte Position Field Value Type Number Order Byte 0Shape Type 5Integer 1Little Byte 4Box Box Double 4Little Byte 36NumParts NumParts Integer 1Little Byte 40NumPoints NumPoints Integer 1Little Byte 44Parts Parts Integer NumParts Little Byte X Points Points Point NumPoints Little Note:X = 44 + 4 * NumParts MeasuredShape Types in X,Y SpaceShapes of this type have an additional coordinate M. Note that "no data" value can be specified as a value for M (see Numeric Types on page 2).PointM A PointM consists of a pair of double-precision coordinates in the order X, Y, plus ameasure M.PointM{Double X // X coordinateDouble Y // Y coordinateDouble M // Measure}J-7855Table 8PointM Record ContentsBytePosition Field Value Type Number OrderByte 0Shape Type21Integer1LittleByte 4X X Double1LittleByte 12Y Y Double1LittleByte 20M M Double1Little MultiPointM A MultiPointM represents a set of PointMs, as followsMultiPointM{Double[4]Box// Bounding BoxInteger NumPoints// Number of PointsPoint[NumPoints]Points// The Points in the SetDouble[2]M Range// Bounding Measure RangeDouble[NumPoints]M Array// Measures}The fields for a MultiPointM areBox The Bounding Box for the MultiPointM stored in the order Xmin, Ymin,Xmax, YmaxNumPoints The number of PointsPoints An array of Points of length NumPointsM Range The minimum and maximum measures for the MultiPointM stored in theorder Mmin, MmaxM Array An array of measures of length NumPointsJ-7855Table 9MultiPointM Record ContentsByte Position Field Value Type Number OrderByte 0Shape Type28Integer1LittleByte 4Box Box Double4LittleByte 36NumPoints NumPoints Integer1LittleByte 40Points Points Point NumPoints LittleByte X*Mmin Mmin Double1LittleByte X+8*Mmax Mmax Double1LittleByte X+16*Marray Marray Double NumPoints LittleNote:X = 40 + (16 * NumPoints)*optionalPolyLineM A shapefile PolyLineM consists of one or more parts. A part is a connected sequence of two or more points. Parts may or may not be connected to one another. Parts may or maynot intersect one another.PolyLineM{Double[4]Box// Bounding BoxInteger NumParts// Number of PartsInteger NumPoints// Total Number of PointsInteger[NumParts]Parts// Index to First Point in PartPoint[NumPoints]Points// Points for All PartsDouble[2]M Range// Bounding Measure RangeDouble[NumPoints]M Array// Measures for All Points}The fields for a PolyLineM areBox The Bounding Box for the PolyLineM stored in the order Xmin, Ymin,Xmax, Ymax.NumParts The number of parts in the PolyLineM.NumPoints The total number of points for all parts.Parts An array of length NumParts. Stores, for each part, the index of its firstpoint in the points array. Array indexes are with respect to 0.Points An array of length NumPoints. The points for each part in the PolyLineMare stored end to end. The points for Part 2 follow the points for Part 1, andso on. The parts array holds the array index of the starting point for eachpart. There is no delimiter in the points array between parts.J-7855M Range The minimum and maximum measures for the PolyLineM stored in theorder Mmin, Mmax.M Array An array of length NumPoints. The measures for each part in thePolyLineM are stored end to end. The measures for Part 2 follow themeasures for Part 1, and so on. The parts array holds the array index of thestarting point for each part. There is no delimiter in the measure arraybetween parts.Table 10PolyLineM Record ContentsBytePosition Field Value Type Number OrderByte 0Shape Type23Integer1LittleByte 4Box Box Double4LittleByte 36NumParts NumParts Integer1LittleByte 40NumPoints NumPoints Integer1LittleByte 44Parts Parts Integer NumParts LittleByte X Points Points Point NumPoints LittleByte Y*Mmin Mmin Double1LittleByte Y + 8*Mmax Mmax Double1LittleByte Y + 16*Marray Marray Double NumPoints LittleNote:X = 44 + (4 * NumParts), Y = X + (16 * NumPoints)*optionalPolygonM A PolygonM consists of a number of rings. A ring is a closed, non-self-intersecting loop.Note that intersections are calculated in X,Y space, not in X,Y,M space. A PolygonMmay contain multiple outer rings. The rings of a PolygonM are referred to as its parts.The PolygonM structure is identical to the PolyLineM structure, as follows:PolygonM{Double[4]Box// Bounding BoxInteger NumParts// Number of PartsInteger NumPoints// Total Number of PointsInteger[NumParts]Parts// Index to First Point in PartPoint[NumPoints]Points// Points for All PartsDouble[2]M Range// Bounding Measure RangeDouble[NumPoints]M Array// Measures for All Points}J-7855 The fields for a PolygonM areBox The Bounding Box for the PolygonM stored in the order Xmin, Ymin, Xmax, Ymax.NumParts The number of rings in the PolygonM.NumPoints The total number of points for all rings.Parts An array of length NumParts. Stores, for each ring, the index of its first point in the points array. Array indexes are with respect to 0.Points An array of length NumPoints. The points for each ring in the PolygonM are stored end to end. The points for Ring 2 follow the points for Ring 1,and so on. The parts array holds the array index of the starting point foreach ring. There is no delimiter in the points array between rings.M Range The minimum and maximum measures for the PolygonM stored in the order Mmin, Mmax.M Array An array of length NumPoints. The measures for each ring in the PolygonM are stored end to end. The measures for Ring 2 follow the measures forRing 1, and so on. The parts array holds the array index of the startingmeasure for each ring. There is no delimiter in the measure array betweenrings.The following are important notes about PolygonM shapes.The rings are closed (the first and last vertex of a ring MUST be the same).The order of rings in the points array is not significant.J-7855Table 11PolygonM Record ContentsBytePosition Field Value Type Number OrderByte 0Shape Type25Integer1LittleByte 4Box Box Double4LittleByte 36NumParts NumParts Integer1LittleByte 40NumPoints NumPoints Integer1LittleByte 44Parts Parts Integer NumParts LittleByte X Points Points Point NumPoints LittleByte Y*Mmin Mmin Double1LittleByte Y + 8*Mmax Mmax Double1LittleByte Y + 16*Marray Marray Double NumPoints LittleNote:X = 44 + (4 * NumParts), Y = X + (16 * NumPoints)*optionalShape Types in X,Y,Z Space Shapes of this type have an optional coordinate M. Note that "no data" value can be specified as a value for M (see Numeric Types on page 2).PointZ A PointZ consists of a triplet of double-precision coordinates in the order X, Y, Z plus a measure.PointZ{Double X// X coordinateDouble Y// Y coordinateDouble Z// Z coordinateDouble M// Measure}Table 12PointZ Record ContentsByte Position Field Value Type Number OrderByte 0Shape Type11Integer1LittleByte 4X X Double1LittleByte 12Y Y Double1LittleByte 20Z Z Double1LittleByte 28Measure M Double1Little。
Shapefile格式
Shapefile格式shapefile数据文件组成前言呵呵,看到数据文件里面有.dbf的竟然不认识,丢人喽丢人喽,补补,摘自:/wiki/Shapefile内容Shapefile属于一种矢量图形格式,它能够保存几何图形的位置及相关属性。
但这种格式没法存储地理数据的拓扑信息。
Shapefile在九十年代初的ArcView GIS的第二个版本被首次应用。
目前,许多自由的程序或商业的程序都可以读取Shapefile。
Shapefile是一种比较原始的矢量数据存储方式,它仅仅能够存储几何体的位置数据,而无法在一个文件之中同时存储这些几何体的属性数据。
因此,Shapefile还必须附带一个二维表用于存储Shapefile 中每个几何体的属性信息。
Shapefile中许多几何体能够代表复杂的地理事物,并为他们提供强大而精确的计算能力。
Shapefile文件指的是一种文件存储的方法,实际上该种文件格式是由多个文件组成的。
其中,要组成一个Shapefile,有三个文件是必不可少的,它们分别是".shp", ".shx"与 ".dbf" 文件。
表示同一数据的一组文件其文件名前缀应该相同。
例如,存储一个关于湖的几何与属性数据,就必须有lake.shp,lake.shx与lake.dbf三个文件。
而其中“真正”的Shapefile的后缀为shp,然而仅有这个文件数据是不完整的,必须要把其他两个附带上才能构成一组完整的地理数据。
除了这三个必须的文件以外,还有八个可选的文件,使用它们可以增强空间数据的表达能力。
所有的文件名都必须遵循MS DOS的8.3文件名标准(文件前缀名8个字符,后缀名3个字符,如shapefil.shp),以方便与一些老的应用程序保持兼容性,尽管现在许多新的程序都能够支持长文件名。
此外,所有的文件都必须位于同一个目录之中。
必须的文件:•.shp —图形格式,用于保存元素的几何实体。
shapefile的使用和地理信息的获得
shapefile的使⽤和地理信息的获得Shapefile⽂件是美国ESRI公司发布的⽂件格式,因其ArcGIS软件的推⼴⽽得到了普遍的使⽤,是现在GIS领域使⽤最为⼴泛的⽮量数据格式。
官⽅称Shapefile是⼀种⽤于存储地理要素的⼏何位置和属性信息的⾮拓扑简单格式。
⼀般地,Shapefile⽂件是多个⽂件的集合,⾄少包括⼀个shp,shx以及dbf⽂件。
shp主⽂件使⽤变长记录存储空间⼏何数据,⽀持点,线,⾯等多种⼏何类型。
shx索引⽂件⽤于存储⼏何数据的索引信息,包含对主⽂件中每个记录长度的描述(注意不是空间索引)dbf表⽂件是使⽤dBase数据库表⽂件进⾏空间属性数据存储的⽂件所以,我们如果要⾃⼰完全从底层写代码解析Shapefile⽂件的话,需要根据shx⽂件中的信息读取shp中的⼆进制数据并转化为⼏何对象,然后再读取dbf表格,将属性添加到⼏何对象上就完成了对⼀个Shapefile⽂件的解析.其实现在,如果给定⼀个地点的经度和维度,现在让你想判断⼀下,这个地点是算什么区域,正常做法是,我们调⽤百度地图或者⾕歌地图的API⾥⾯的接⼝就可以了。
但是其实,如果当这些接⼝不能调⽤的时候,我们该怎么办呢。
这⾥我们可以考虑下⽤shapefile来完成这个任务。
1. ⾸先在shapefile⾥⾯,⽂件数据提供了信息,这个信息可以帮助我们绘制⼀个地区区域的多边形。
2. 接着我们需要把我们的⽬标点绘制成⼀个点3. 剩下的任务就是,我们来判断,⽬标区域的点是不是在地形绘制的多边形⾥⾯。
判断任务3的时候,我们可以⽤⼀个景点的 point in ploygon 理论,⼤概是这个样⼦判断的算法我就直接引⽤了:1) Draw a horizontal line to the right of each point and extend it to infinity1) Count the number of times the line intersects with polygon edges.2) A point is inside the polygon if either count of intersections is odd orpoint lies on an edge of polygon. If none of the conditions is true, thenpoint lies outside.那这样,我们有我们⽬标点的坐标,我们⼜有我们区域的⼤概的形状,那这样我们就可以确定,我们的⽬标点的所在区域了下⾯是代码,⽤python实现的# Library# 这个是⽤来判断点在不在多边形⾥⾯的库,同时绘制点和多边形from shapely.geometry import Pointfrom shapely.geometry.polygon import Polygon# 这⾥是⽤这个来读取shapefile⽂件import shapefile接着我们读⼊数据1# Load the shapefile information2 sf = shapefile.Reader("./vic_suburb_boundary/VIC_LOCALITY_POLYGON_shp") # note, no suffix, all3 files are used3 recs = sf.records()4 shapes = sf.shapes()这时候我们先看下,shapefile⾥⾯有哪些信息recs[0]这⾥我们发现,基本上可能是与这个区域有关的⼀些⽂字信息,我们看到第7个元素是我们这次需要的,是这个区域的名字,接着我们看下shapes⾥⾯的内容shapes[0].points这⾥我们发现是⼀系列坐标点,这些坐标点可以帮助我们来绘制这个区域的的多边形# Build a list to hold the name of the suburbsubsurb_name = []for item in recs:# Extract the 7th element:subsurb namesubsurb_name.append(item[6])# Check the extraction resultprint(subsurb_name[:5])# Build a list to hold the ploygon represent the subsurbsub_plon = []for item in shapes:# Using the points information to draw the ploygonpolygon = Polygon(item.points)sub_plon.append(polygon)# Drow one of the subsurbsub_plon[0]在上⾯两步,我们把shape中的区域名字信息以及区域性质信息都提取了出来,接着,我们就可以⽤这个信息,来判断,我们的⽬标点,相应都在哪⾥了# Combine name and ploygon list togethersub_info = list(zip(subsurb_name,sub_plon))# lat information for all the latslat_list = list(df_t)# lng informationlng_list = list(df_house.lng)# Zip them in the list of tuplesposition_list = zip(lng_list, lat_list)# A list for holding the subsurb information for each house propertysub_for_house = []# Loop through all the housefor item in position_list:# Build a point to represent the house propertypoint = Point(item[0],item[1])# Check where the point is locatedfor sub in sub_info:# Return true if the point is in the ploygonif sub[1].contains(point):# Collect the resultsub_for_house.append(sub[0])# Check the resultsub_for_house[:5]根据我们之前的算法,我们把每个我们的⽬标地址都便利了⼀遍,并且计算出相应的位置点。
shapelib库编译
VS2017编译ShapeLib库的步骤及注意事项
ShapeLib是一个用于读写Shapefile格式数据的轻量级C语言库。
它主要包括Shape API(用于读写.shp文件的空间几何信息)和DBF API(用于读写.dbf文件的属性信息)。
以下是使用VS2017编译ShapeLib库的步骤:
1.下载ShapeLib源码,解压后进入路径。
2.使用VS2017本机命令执行工具。
解压源码后,进入路径,使用nmake -f
makefile.vc进行编译。
3.编译完成后,会在shapelib文件夹下生成静态库“shapelib.lib”,和动态
库shapelib_i.lib和shapelib.dll。
4.将头文件“shapefil.h”和lib及dll复制到自己需要的地方使用即可。
以上步骤仅供参考,建议查阅ShapeLib官方文档或咨询专业技术人员,获取更准确的信息。
读取Shapefile文件
运行结果
fclose(file); return records;
最后关闭文件,输出数据,得到运行结果如下
bjsa.shp
tgr39035lkA_Project.shp
点击图片放大
Thank you
程序设计思路
——读取文件头
由于shapefile文件只能存储单一类型的几何体,所以我们只需要判断文件头中的 ShapeType,就可以知道该文件存储的是点、线还是 面
if(fHeader.ShapeType==1) if(fHeader.ShapeType==3) if(fHeader.ShapeType==5)
点 线 面
程序设计思路
——读取点数据 首先我们读取最后一条记录的记录号,它在数值上等于点的数量 (一条点记录的长度是28字节) fseek(file,-28L,2); fread(&numPoints,sizeof(int),1,file); numPoints=ExchangeOrder(numPoints);
程序设计思路
——读取文件头 文件头中有9个int数据和8个double数据 所以我们考虑用两个数组来读取数据, 然后分配给fHeader中的变量。 int double *fileHeaderPart1; *fileHeaderPart2;
fileHeaderPart1=(int *)malloc(sizeof(int)*9); fileHeaderPart2=(double *)malloc(sizeof(double)*8); fread(fileHeaderPart1,sizeof(int),9,file); fread(fileHeaderPart2,sizeof(double),8,file);
CShape代码规范
农行:62284 8012 02154 66919田金沅1. 引言本文是一套面向C# programmer 和C# developer 进行开发所应遵循的开发规范。
按照此规范来开发C#程序可带来以下益处:∙代码的编写保持一致性,∙提高代码的可读性和可维护性,∙在团队开发一个项目的情况下,程序员之间可代码共享∙易于代码的回顾,本规范是初版,只适用于一般情况的通用规范,并不能覆盖所有的情况。
2. 文件组织2.1 C# 源文件类名或文件名要简短,不要超过2000LOC,将代码分割开,使结构清晰。
将每个类放在一个单独的文件中,使用类名来命名文件名(当然扩展名是.cs)。
这种约定会使大家工作更简单。
2.2 目录设计为每一个命名空间创建一个目录。
(用MyProject/TestSuite/TestTier作为MyProject.TestSuite.TestTier的路径,而不用带点的命名空间名做路径)这样可以更容易地将命名空间映射到目录层次划分。
3. 缩进3.1 换行当一个表达式超过一行时,根据这些通用原则进行处理:∙在逗号后换行。
∙在操作符后换行。
∙在高层换行而不要在低层处换行。
∙折行后对齐上一行语句同一层的表达式起始位置。
方法调用换行示例:longM ethodCall(expr1, expr2,expr3, expr4, expr5);算术表达式换行示例:推荐:var = a * b / (c - g + f) +4 * z;不好的格式——应避免:var = a * b / (c - g +f) + 4 * z;推荐使用第一种方法,因为是在括号表达式之外折行(高层次折行原则)。
注意要用制表符到缩进的位置,然后用用空格到折行的位置。
在我们的例子中是:> var = a * b / (c - g + f) +> ......4 * z;'>'表示是制表符,'.'表示是空格符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
shapefile格式说明及读写代码示例08-04-08 11:50:49不详核心提示:Shape files 数据说明Shape files 是ESRI 提供的一种矢量数据格式,它没有拓扑信息,一个Shape files 由一组文件组成,其中必要的基记录内容包括目标的几何类型(ShapeType )和具体的坐标记录(X 、Y) ,记录内容因要素几何类型的不同其具体的内容及格式都有所不同。
下面分别介绍点状目标(Point )、线状目标(PolyLine )和面状目标(Polygon )三种几何类型的.shp 文件的记录内容:点状目标shapefile 中的点状目标由一对X 、Y 坐标构成,坐标值为双精度型(double )。
点状目标的记录内容如表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);ContentLength = OnChangeByteOrder(ContentLength);int shapeType;double x;double y;fread(&shapeType, sizeof(int), 1,ShpFile_fp);fread(&x, sizeof(double), 1,ShpFile_fp);fread(&y, sizeof(double), 1,ShpFile_fp);}}线状目标shapefile 中的线状目标是由一系列点坐标串构成,一个线目标可能包括多个子线段,子线段之间可以是相离的,同时子线段之间也可以相交。
Shapefile 允许出现多个坐标完全相同的连续点,当读取文件时一定要注意这种情况,但是不允许出现某个退化的、长度为0 的子线段出现。
线状目标的记录内容如表2.5 :具体的数据结构如下:PolyLine{Double[4] Box // 当前线状目标的坐标范围Integer NumParts // 当前线目标所包含的子线段的个数Integer NumPoints // 当前线目标所包含的顶点个数Integer[NumParts] Parts // 每个子线段的第一个坐标点在Points 的位置Point[NumPoints] Points // 记录所有坐标点的数组}这些记录项的具体含义如下:Box 记录了当前的线目标的坐标范围,它是一个double 型的数组,按照Xmin 、Ymin 、Xmax 、Ymax 的顺序记录了坐标范围;NumParts 记录了当前线目标所包含的子线段的个数;NumPoints 记录了当前线目标的坐标点总数;Parts 记录了每个子线段的第一个坐标点在坐标数组points 中的位置,以便读取数据;Points 是用于存放当前线目标的X 、Y 坐标的数组。
下面是读取线状目标的记录内容的代码:OnReadLineShp(CString ShpFileName){// 打开坐标文件……// 读取坐标文件头的内容开始……// 读取线状目标的实体信息int RecordNumber;int ContentLength;int num =0;while((fread(&RecordNumber, sizeof(int), 1,ShpFile_fp)!=0)){fread(&ContentLength,sizeof(int), 1,ShpFile_fp);RecordNumber = OnChangeByteOrder (RecordNumber);ContentLength = OnChangeByteOrder (ContentLength);int shapeType;double Box[4];int NumParts;int NumPoints;int *Parts;fread(&shapeType, sizeof(int), 1,ShpFile_fp); // 读Boxfor(i=0;i<4;i++)fread(Box+i, sizeof(double),1,ShpFile_fp); // 读NumParts 和NumPointsfread(&NumParts, sizeof(int), 1,ShpFile_fp);fread(&NumPoints, sizeof(int), 1,ShpFile_fp); // 读Parts 和PointsParts = new int[NumParts];for(i=0;i<NumParts;i++)fread(Parts+i, sizeof(int), 1,ShpFile_fp);int pointNum;for(i=0;i<NumParts;i++){if(i!=NumParts-1)pointNum =Parts[i+1]-Parts[i];elsepointNum =NumPoints-Parts[i];double *PointsX;double *PointsY;PointsX =new double[pointNum];PointsY =new double[pointNum];for(j=0;j<pointNum;j++){fread(PointsX+j, sizeof(double),1,ShpFile_fp);fread(PointsY+j, sizeof(double),1,ShpFile_fp);}delete[] PointsX;delete[] PointsY;}delete[] Parts;}}面状目标shapefile 中的面状目标是由多个子环构成,每个子环是由至少四个顶点构成的封闭的、无自相交现象的环。
对于含有岛的多边形,构成它的环有内外环之分,每个环的顶点的排列顺序或者方向说明了这个环到底是内环还是外环。
一个内环的顶点是按照逆时针顺序排列的;而对于外环,它的顶点排列顺序是顺时针方向。
如果一个多边形只由一个环构成,那么它的顶点排列顺序肯定是顺时针方向。
每条多边形记录的数据结构与线目标的数据结构完全相同,Polygon{Double[4] Box // 当前面状目标的坐标范围Integer NumParts // 当前面目标所包含的子环的个数Integer NumPoints // 构成当前面状目标的所有顶点的个数Integer[NumParts] Parts // 每个子环的第一个坐标点在Points 的位置Point[NumPoints] Points // 记录所有坐标点的数组}对于一个shapefile 中的多边形,它必须满足下面三个条件:构成多边形的每个子环都必须是闭合的,即每个子环的第一个顶点跟最后一个顶点是同一个点;每个子环在Points 数组中的排列顺序并不重要,但每个子环的顶点必须按照一定的顺序连续排列;存储在shapefile 中的多边形必须是干净的。
所谓一个干净的多边形,它必须满足两点:没有自相交现象。
这就要求任何一个子环不能跟其它的子环相交,共线的现象也将被当作相交。
但是允许两个子环的顶点重合;对于一个不含岛的多边形或者是含岛的多边形的外环,它们的顶点排列顺序必须是顺时针方向;而对于内环,它的排列顺序必须是逆时针方向。
所谓的“脏多边形”就是指顶点排列顺序为顺时针的内环。
图2.2 中的多边形是一个典型的例子。
这个多边形包括一个岛,所有顶点的个数为8 。
NumParts 等于2 ,NumPoints 等于10 。
请注意内环(岛)的顶点的排列顺序是逆时针的(如图2.3 所示)下面是读取面状目标的记录内容的代码:void OnReadAreaShp(CString ShpFileName){// 打开坐标文件……// 读取坐标文件头的内容开始……// 读取面状目标的实体信息int RecordNumber;int ContentLength;while((fread(&RecordNumber, sizeof(int), 1,m_ShpFile_fp)!=0)){fread(&ContentLength,sizeof(int), 1,m_ShpFile_fp);RecordNumber = OnChangeByteOrder (RecordNumber);ContentLength = OnChangeByteOrder (ContentLength);int shapeType;double Box[4];int NumParts;int NumPoints;int *Parts;fread(&shapeType, sizeof(int), 1,m_ShpFile_fp);// 读Boxfor(i=0;i<4;i++)fread(Box+i, sizeof(double),1,m_ShpFile_fp);// 读NumParts 和NumPointsfread(&NumParts, sizeof(int), 1,m_ShpFile_fp);fread(&NumPoints, sizeof(int), 1,m_ShpFile_fp);// 读Parts 和PointsParts =new int[NumParts];for(i=0;i<NumParts;i++)fread(Parts+i, sizeof(int), 1,m_ShpFile_fp);int pointNum;int xx;int yy;for(i=0;i<NumParts;i++){if(i!=NumParts-1)pointNum =Parts[i+1]-Parts[i];elsepointNum =NumPoints-Parts[i];double *PointsX;double *PointsY;PointsX =new double[pointNum];PointsY =new double[pointNum];for(j=0;j<pointNum;j++){fread(PointsX+j, sizeof(double),1,m_ShpFile_fp);fread(PointsY+j, sizeof(double),1,m_ShpFile_fp);}delete[] PointsX;delete[] PointsY;}delete[] Parts;}}属性文件的文件头其中文件头部分的长度是不定长的,它主要对DBF 文件作了一些总体说明(见表2.7 ),其中最主要的是对这个DBF 文件的记录项的信息进行了详细地描述,比如对每个记录项的名称、数据类型、长度等信息都有具体的说明。