C#不用ArcEngine,生成Shp文件(二)---------读取.shp文件格式

上一篇介绍了Shape files文件结构,在这一篇,以面文件为例,写一下如何读取.shp文件,以面文件为例。

首先在ArcMap里面新建一个名为  三角形面   的 shp文件,用做测试数据。如下

测试数据下载地址为:http://download.csdn.net/detail/gis0911178/9650967

在Arcmap中显示如下

测试数据准备好之后,就可以在C#里面写代码来读取这个shp文件;代码如下

private void button1_Click(object sender, EventArgs e)
        {
            string shpfilepath = "";
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "shapefile(*.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();
                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);


                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 = 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 = 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, 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();
                            //Console.Write("文件记录号为:"+RecordNum);
                            Console.WriteLine("文件记录号为:" + ChangeByteOrder((int)RecordNum));
                            int DataLength = br.ReadInt32();
                            //Console.Write("坐标长度为:"+DataLength);
                            Console.WriteLine("坐标长度为:" + ChangeByteOrder(DataLength));


                            //读取第i个记录
                            int m = br.ReadInt32();
                            Console.WriteLine("几何类型:"+m);
                            for (int i = 0; i < 4;i++ )
                            {
                                polygon.Box[i] = br.ReadDouble();
                                Console.WriteLine("Box[" + i + "]:" + polygon.Box[i]);
                            }


                            polygon.NumParts = br.ReadInt32();
                            Console.WriteLine("子面个数:"+polygon.NumParts);
                            polygon.NumPoints = br.ReadInt32();
                            Console.WriteLine("坐标点个数:" + polygon.NumPoints);


                            Console.WriteLine("每个子环在坐标点内的起始位置:");
                            for (int j = 0; j < polygon.NumParts;j++ )
                            {
                                int parts = new int();
                                parts = br.ReadInt32();
                                polygon.Parts.Add(parts);
                                Console.WriteLine("parts[" + j + "]:" + parts);
                            }


                            Console.WriteLine("Points数组:");
                            for (int j = 0; j < polygon.NumPoints;j++ )
                            {
                                Point pointtemp = new Point();
                                pointtemp.X = br.ReadDouble();
                                pointtemp.Y = br.ReadDouble();
                                polygon.Points.Add(pointtemp);
                                Console.WriteLine("Points["+j+"]:"+pointtemp.X+" "+pointtemp.Y);
                            }
                            polygons.Add(polygon);
                            Console.WriteLine("--------------------------");


                        }
                        break;
                }
            }
        }

读取文件可以了解.shp文件的构成,这样才知道怎么去生成.shp文件。

为了清晰的看到结果,在这里我将每次读取到的东西都打印了出来,结果如下

--------------------------------------------------------------------------------

文件长度:110
Xmin:120.062485706624
Ymin:27.752624080108
Xmax:120.102341678472
Ymax:27.7716597681547
文件记录号为:1
坐标长度为:56
几何类型:5
Box[0]:120.062485706624
Box[1]:27.752624080108
Box[2]:120.102341678472
Box[3]:27.7716597681547
子面个数:1
坐标点个数:4
每个子环在坐标点内的起始位置:
parts[0]:0
Points数组:
Points[0]:120.062485706624 27.7618444915056
Points[1]:120.102341678472 27.7716597681547
Points[2]:120.081521394671 27.752624080108
Points[3]:120.062485706624 27.7618444915056

------------------------------------------------------------------------------------------------------

要注意.shp文件里面,文件长度、文件记录号、坐标长度 均为位序为big,读取跟写入的时候都要转换为little。位序转换函数如下:

private int ChangeByteOrder(int indata)
        {
            byte[] src = new byte[4];
            src[0] = (byte)((indata >> 24) & 0xFF);
            src[1] = (byte)((indata >> 16) & 0xFF);
            src[2] = (byte)((indata >> 8) & 0xFF);
            src[3] = (byte)(indata  & 0xFF);


            int value ;
            value = (int)((src[0] & 0xFF) | ((src[1] & 0xFF) << 8) | ((src[2] & 0xFF) << 16) | ((src[3] & 0xFF) << 24));
            return value;
        }

代码里使用到的polygon.cs如下

class Polygon
    {
        public double[] Box=new double[4];
        public int NumParts;
        public int NumPoints;
        public ArrayList Parts;
        public ArrayList Points;
    }

猜你喜欢

转载自blog.csdn.net/gis0911178/article/details/52162251