这一篇来写一下.shx文件的读取跟生成。测试数据下载地址为:http://download.csdn.net/detail/gis0911178/9650967
在第一篇时候有介绍.
索引文件(.shx)主要包含坐标文件的索引信息,文件中每个记录包含对应的坐标文件记录距离坐标文件的文件头的偏移量。通过索引文件可以很方便地在坐标文件中定位到指定目标的坐标信息。
索引文件也是由头文件和实体信息两部分构成(如图2.5),其中文件头部分是一个长度固定(100 bytes)的记录段,其内容与坐标文件的文件头基本一致。它的实体信息以记录为基本单位,每一条记录包括偏移量(offset)和记录段长度(Content Length)两个记录项,它们的位序都是big,两个记录项都是int型.本次实例使用的数据仍然为 (二) 里面的 三角形面 shp文件。读取shx文件的代码如下
private void button3_Click(object sender, EventArgs e)
{
string shpfilepath = "";
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "shxfile(*.shx)|*.shx|All files(*.*)|*.*"; //打开文件路径
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
shpfilepath = openFileDialog1.FileName;
BinaryReader br = new BinaryReader(openFileDialog1.OpenFile());
//读取文件过程
br.ReadBytes(24);
int FileLength = br.ReadInt32();
Console.WriteLine("文件长度:" + ChangeByteOrder(FileLength));
int FileBanben = br.ReadInt32();
ShapeType = br.ReadInt32();
xmin = br.ReadDouble();
ymin = br.ReadDouble();
xmax = br.ReadDouble();
ymax = br.ReadDouble();
Console.WriteLine("Xmin:" + xmin);
Console.WriteLine("Ymin:" + ymin);
Console.WriteLine("Xmax:" + xmax);
Console.WriteLine("Ymax:" + ymax);
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);
int i = 1;
while (br.PeekChar() != -1)
{
Console.WriteLine("记录" + i + "的位移量:" + ChangeByteOrder(br.ReadInt32()));
Console.WriteLine("记录" + i + "的记录长度:" + ChangeByteOrder(br.ReadInt32()));
i += 1;
}
}
}
控制台打印结果如下:
文件长度:54
Xmin:120.062485706624
Ymin:27.752624080108
Xmax:120.102341678472
Ymax:27.7716597681547
记录1的位移量:50
记录1的记录长度:56
生成.shx文件跟前面生成.shp文件类似,代码如下:
//生成shx文件
string shxPath = @shxFullNameDir;
using (FileStream fs = new FileStream(shxPath, FileMode.Create, FileAccess.Write))
{
//写入FileCode
int fileCode = ChangeByteOrder(9994);
byte[] fc = System.BitConverter.GetBytes(fileCode);
fs.Seek(0, SeekOrigin.Begin);
fs.Write(fc, 0, fc.Length);
//写入文件长度
int fileLength = ChangeByteOrder(54);
byte[] fl = System.BitConverter.GetBytes(fileLength);
fs.Seek(24, SeekOrigin.Begin);
fs.Write(fl, 0, fl.Length);
//写入版本号
int versionNumber = 1000;
byte[] vn = System.BitConverter.GetBytes(versionNumber);
fs.Seek(28, SeekOrigin.Begin);
fs.Write(vn, 0, vn.Length);
//写入文件类型
int fileType = 5;
byte[] ft = System.BitConverter.GetBytes(fileType); ;
fs.Seek(32, SeekOrigin.Begin);
fs.Write(ft, 0, ft.Length);
//写入Extent范围
double xMin = 120.062485706624;
byte[] xin = System.BitConverter.GetBytes(xMin);
fs.Seek(36, SeekOrigin.Begin);
fs.Write(xin, 0, xin.Length);
double yMin = 27.752624080108;
byte[] yin = System.BitConverter.GetBytes(yMin);
fs.Seek(44, SeekOrigin.Begin);
fs.Write(yin, 0, yin.Length);
double xMax = 120.102341678472;
byte[] xax = System.BitConverter.GetBytes(xMax);
fs.Seek(52, SeekOrigin.Begin);
fs.Write(xax, 0, xax.Length);
double yMax = 27.7716597681547;
byte[] yax = System.BitConverter.GetBytes(yMax);
fs.Seek(60, SeekOrigin.Begin);
fs.Write(yax, 0, yax.Length);
int currentByte = 100;//从101位开始写入实体内容
//记录1的位移量
fs.Seek(currentByte, SeekOrigin.Begin);
byte[] fn1 = System.BitConverter.GetBytes(ChangeByteOrder(50));
fs.Write(fn1, 0, fn1.Length);
currentByte += 4;
//记录长度
fs.Seek(currentByte, SeekOrigin.Begin);
byte[] fn1_length = System.BitConverter.GetBytes(ChangeByteOrder(56));
fs.Write(fn1_length, 0, fn1_length.Length);
//清空缓冲区、关闭流
fs.Flush();
fs.Close();
}
至此,shapefile文件的.shp .dbf .shx已经全部生成,可以在ArcMap里面编辑,修改和保存。其中.prj文件也是代码生成的,类似于生成txt文本。