1. 程式人生 > >C#不用ArcEngine,生成Shp檔案(五)---------讀取.shx檔案和生成.shx檔案

C#不用ArcEngine,生成Shp檔案(五)---------讀取.shx檔案和生成.shx檔案

這一篇來寫一下.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文字。