none
用C#读shapefile(shp文件)http://www.cnblogs.com/China3S/archive/2013/07/09/3180950.html RRS feed

  • 问题

  • 小弟愚昧。用C#读shp文件需要构造一个输出点线面的工程。此为网上找了好久的范例。但是苦于没有成功。请有C#基础的朋友,可以参考范例修改一下。(shp文件可以随意找,这边我没找到上传附件,请谅解。回请回复参考的修改之后的代码。)

    2013年11月11日 2:20

全部回复

  • 题目上面的网址是我找的范例,热心的大大可以参考下。只需要稍作修改= =小弟c#初学者,表示各种看不懂。现在正在认真学习C#书籍。如有人能把代码详细注释下,感激不尽!
    2013年11月11日 2:21
  • using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using Microsoft.VisualBasic ;
    
    namespace MyCprogram
    {
    
    
        public partial class Form1 : Form
        {
            ArrayList polygons = new ArrayList(); //面集合
            ArrayList polylines = new ArrayList();//线集合
            ArrayList points = new ArrayList();//点集合
            Pen pen = new Pen(Color.Blue, 2);//定义画笔
            int ShapeType;//文件类型
            int count;//计数
            double xmin, ymin, xmax, ymax;
            double n1, n2;//x,y轴放大倍数
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("请读取后缀为.Shp的文件,否则将导致未知的程序错误","按钮声明",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                DialogResult dr = this.openFileDialog1.ShowDialog( "shapefiles(*.shp)|*.shp|All files(*.*)|*.*");
                if (dr == DialogResult.OK)
                {
                    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.pictureBox1.Width * 0.9 / width);//x轴放大倍数
                    n2 = (float)(this.pictureBox1.Height * 0.9 / height);//y轴放大倍数
                    br.ReadBytes(32);
    
                    switch (ShapeType)
                    {
                        case 1:
                            points.Clear();
                            while (br.PeekChar() != -1)
                            {
                                Point_shape point = new Point_shape();
    
                                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_shape p in points)
                            {
                                sw.WriteLine("{0},{1},{2} ", p.X, -1 * p.Y, 0);
                            }
                            this.pictureBox1.Refresh();
                            sw.Close();
                            break;
                        case 3:
                            polylines.Clear();
                            while (br.PeekChar() != -1)
                            {
                                PolyLine_shape polyline = new PolyLine_shape();
                                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_shape pointtemp = new Point_shape();
                                    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_shape 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_shape ps = (Point_shape)p.Points[j];
                                        sw2.WriteLine("    {0},{1},{2} ", ps.X, -1 * ps.Y, 0);
                                    }
                                    count++;
                                }
                                  }
                            this.pictureBox1.Refresh();
                            sw2.Close();
                            break;
                        case 5:
                            polygons.Clear();
                            while (br.PeekChar() != -1)
                            {
                                Polygon_shape polygon = new Polygon_shape();
                                polygon.Parts = new ArrayList();
                                polygon.Points = new ArrayList();
    
                                uint RecordNum = br.ReadUInt32();
                                int DataLength = br.ReadInt32();
    
                                //读取第i个记录
                                int m = br.ReadInt32();
                                polygon.Box1 = br.ReadDouble();
                                polygon.Box2 = br.ReadDouble();
                                polygon.Box3 = br.ReadDouble();
                                polygon.Box4 = 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_shape pointtemp = new Point_shape();
                                    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_shape 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_shape ps = (Point_shape)p.Points[j];
                                        sw1.WriteLine("    {0},{1},{2} ", ps.X, -1 * ps.Y, 0);
                                    }
                                    count++;
                                }
                            }
                            this.pictureBox1.Refresh();
                            sw1.Close();
                            break;
                    }
                    br.Close();
                }
                double Width = xmax - xmin;
                double Height = ymax - ymin;
                n1 = (float)(this.pictureBox1.Width * 0.9 / Width);//x轴放大倍数
                n2 = (float)(this.pictureBox1.Height * 0.9 / Height);//y轴放大倍数
                this.pictureBox1.Refresh();
            }
    
            private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                PointF[] point;
    
                switch (ShapeType)
                {
                    case 1:
                        foreach (Point_shape 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_shape 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_shape ps = (Point_shape)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_shape 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_shape ps = (Point_shape)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;
                }
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                DialogResult dr = this.colorDialog1.ShowDialog();
                if (dr == DialogResult.OK)
                {
                    pen.Color = this.colorDialog1.Color;
                    this.button2.BackColor = pen.Color;
                }
                this.pictureBox1.Refresh();
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                MessageBox.Show("请选择要读取属性的Shapefile文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                string shpfilepath = "";
    
                int FileCode = 0;   //文件代码
                int Unused = 0;     //未使用
                int FileLength = 0; //文件长度
                int Version = 0;    //版本
                int ShapeType = 0;  //Shape类型
    
                double Xmin = 0;    //边界盒
                double Ymin = 0;
                double Xmax = 0;
                double Ymax = 0;
                double Zmin = 0;
                double Zmax = 0;
                double Mmin = 0;
                double Mmax = 0;
    
                int RecorderNumber = 0; //Shp文件的记录数
    
                openFileDialog1.Filter = "shapefiles(*.shp)|*.shp|All files(*.*)|*.*";
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                    shpfilepath = openFileDialog1.FileName;
    
                //先读取.shx文件,得到文件的总字节长度,以便求取.shp文件的记录数
    
                string shxpath = shpfilepath.Remove(shpfilepath.Length - 1, 1) + "x";
                FileStream fo = new FileStream(shxpath, FileMode.Open, FileAccess.Read);   //文件流形式
                BinaryReader bi = new BinaryReader(fo);     //打开二进制文件
    
                FileCode = bi.ReadInt32();
                FileCode = Convert.ToInt32(big2little(FileCode));
                for (int i = 0; i < 5; i++)
                {
                    Unused = bi.ReadInt32();
                }
    
                FileLength = bi.ReadInt32();           //FileLength以字为单位,一字等于2字节,等于16位
    
                FileLength = Convert.ToInt32(big2little(FileLength));
    
                //   RecorderNumber = (int)fo.Length;         //fo.Length以字节为单位
    
                /*   Version = bi.ReadInt32();
                   ShapeType = bi.ReadInt32();
                   Xmin = bi.ReadDouble();
                   Ymin = bi.ReadDouble();
                   Xmax = bi.ReadDouble();
                   Ymax = bi.ReadDouble();
                   Zmin = bi.ReadDouble();
                   Zmax = bi.ReadDouble();
                   Mmin = bi.ReadDouble();
                   Mmax = bi.ReadDouble();
                   for (int i = 0; i < 4; i++)
                   {
                       int a = bi.ReadInt32();
                       int b = bi.ReadInt32();
                       a = Convert.ToInt32(big2little(a ));
                       b = Convert.ToInt32(big2little(b ));
                   }*/
    
                fo.Close();
    
                RecorderNumber = (int)(FileLength - 50) / 4;  //求取.shp文件的记录数
    
                // 读取shp文件头的内容开始
                FileStream fs = new FileStream(shpfilepath, FileMode.Open, FileAccess.Read);   //文件流形式
                BinaryReader br = new BinaryReader(fs);     //打开二进制文件
                FileCode = br.ReadInt32();
    
                FileCode = Convert.ToInt32(big2little(FileCode));
                for (int i = 0; i < 5; i++)
                {
                    Unused = br.ReadInt32();
                }
    
                FileLength = br.ReadInt32();
                FileLength = Convert.ToInt32(big2little(FileLength));
                //int a = (int)fs.Length;
                Version = br.ReadInt32();
                ShapeType = br.ReadInt32();
                Xmin = br.ReadDouble();
                Ymin = br.ReadDouble();
                Xmax = br.ReadDouble();
                Ymax = br.ReadDouble();
                Zmin = br.ReadDouble();
                Zmax = br.ReadDouble();
                Mmin = br.ReadDouble();
                Mmax = br.ReadDouble();
                // 读取坐标文件头的内容结束
    
                //根据几何类型读取信息
                int RecorderNum = 0;
                int ContentLength = 0;
                int Num = 0;
                switch (ShapeType)
                {
                    case 1:   //Single Point 点
    
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            RecorderNum = br.ReadInt32();     //记录号
                            Num++;
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));       // ContentLength以字为单位,一字等于2字节,等于16位
                            int shapetype1 = 0;
                            double x = 0;
                            double y = 0;
                            shapetype1 = br.ReadInt32();
                            x = br.ReadDouble();
                            y = br.ReadDouble();
                            textBox_show.Text += RecorderNum.ToString() + "   " + ContentLength.ToString() + "   " + shapetype1.ToString() + "   " + x.ToString() + "  " + y.ToString() + " \r\n";
    
                        }
    
                        break;
                    case 3:   //Polyline  线
    
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            RecorderNum = br.ReadInt32();        //记录号
                            Num++;
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位,一字等于2字节,等于16位
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();
                            int Numparts;     //子线段个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
    
                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                            }
    
                            textBox_show.Text += RecorderNum.ToString() + "   " + ContentLength.ToString() + "   " + shapetype1.ToString() + "   "; //+ x.ToString() + "   " + y.ToString() + "***************";
                            for (int i = 0; i < Numpoints; i++)
                            {
                                textBox_show.Text += "x=" + pointsx[i] + "  ";
                                textBox_show.Text += "y=" + pointsy[i] + "  ";
                            }
                            textBox_show.Text += " \r\n";
    
                        }
                        break;
                    case 5:   //Polygon   面
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            RecorderNum = br.ReadInt32();        //记录号
                            Num++;
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位,一字等于2字节,等于16位
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();
                            int Numparts;     //子环个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
    
                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                            }
    
                            textBox_show.Text += RecorderNum.ToString() + "   " + ContentLength.ToString() + "   " + shapetype1.ToString() + "   "; //+ x.ToString() + "   " + y.ToString() + "***************";
                            for (int i = 0; i < Numpoints; i++)
                            {
                                textBox_show.Text += "x=" + pointsx[i] + "  ";
                                textBox_show.Text += "y=" + pointsy[i] + "  ";
                            }
                            textBox_show.Text += " \r\n";
    
                        }
    
                        break;
                    case 8:   //Multipoint
                        /*
                         * 
                         
                         .....
    
                         
                         * 
                         */
    
                        break;
                }
    
                fs.Close();
    
                //读取dbf文件
    
                string dbfpath = shpfilepath.Remove(shpfilepath.Length - 3, 3) + "dbf";
                FileStream fd = new FileStream(dbfpath, FileMode.Open, FileAccess.Read);   //文件流形式
                BinaryReader bd = new BinaryReader(fd);     //打开二进制文件
    
                int m = Convert.ToInt32(fd.Length);
    
                //读取文件头
                byte dbf_version;             //版本信息
                dbf_version = bd.ReadByte();
    
                byte[] date = new byte[3];    //更新日期
                for (int i = 0; i < 3; i++)
                {
                    date[i] = bd.ReadByte();
                }
    
                int recordnumb;               //文件中的记录数
                recordnumb = bd.ReadInt32();
    
                short HeaderByteNum;          //文件头中的字节数
                HeaderByteNum = bd.ReadInt16();
    
                short RecordByteNum;          //一条记录中的字节数
                RecordByteNum = bd.ReadInt16();
    
                short Reservd1;               //保留字节
                Reservd1 = bd.ReadInt16();
    
                byte Flag4s;                  //表示未完成的操作
                Flag4s = bd.ReadByte();
    
                byte EncrypteFlag;            //编密码标记
                EncrypteFlag = bd.ReadByte();
    
                for (int i = 0; i < 3; i++)   //保留字节,用于多用户处理时使用
                {
                    Unused = bd.ReadInt32();
                }
    
                byte MDXFlag;          //DBF文件的MDX标志
                MDXFlag = bd.ReadByte();
    
                byte LDriID;           //Language driver ID
                LDriID = bd.ReadByte();
    
                short Reserved2;       //保留字节
                Reserved2 = bd.ReadInt16();
    
    
                int fieldscount;       //记录项个数
                fieldscount = (HeaderByteNum - 32) / 32;
    
                for (int j = 0; j < fieldscount; j++)
                {
                    byte[] name = new byte[11];       //记录项名称,是ASCII码值
                    for (int i = 0; i < 11; i++)
                    {
                        name[i] = bd.ReadByte();
                    }
    
                    byte fieldType;                   //记录项数据类型,是ASCII码值。(B二进制、C字符型、D日期型、G各种字符、L逻辑型、M各种字、N数值型)
                    fieldType = bd.ReadByte();
    
                    int reserved3;                    //保留字节
                    reserved3 = bd.ReadInt32();
    
                    byte fieldLength;                 //记录项长度,二进制型
                    fieldLength = bd.ReadByte();
    
                    byte decimalCount;                //记录项精度,二进制型
                    decimalCount = bd.ReadByte();
    
                    short reserved4;                  //保留字节
                    reserved4 = bd.ReadInt16();
    
                    byte workID;                      //工作区ID
                    workID = bd.ReadByte();
    
                    short[] Reserved5 = new short[5];   //保留字节
                    for (int i = 0; i < 5; i++)
                        {
                        Reserved5[i] = bd.ReadInt16();
                    }
    
                    byte mDXFlag1;                     //MDX标识
                    mDXFlag1 = bd.ReadByte();
                }
                byte terminator; //记录项终止标志      
                terminator = bd.ReadByte();
    
                //读取文件头结束
    
    
                //读取文件实体信息
                /*   byte[] sd = new byte[40];
                     for (int i = 0; i < 36; i++)
                     {
                         sd[i]=bd.ReadByte();
                     }
                      char[] sd = new char[40];
                     for (int i = 0; i < 36; i++)
                     {
                         sd[i] = bd.ReadChar ();
                     }*/
    
                /*    int ID;
                    int ff = 0;
                    ff = bd.ReadInt32();
    
                    for (int i = 0; i < RecorderNumber; i++)
                    {
                       // string s= "";
                        byte deleteFlag;
                        deleteFlag = bd.ReadByte();
                       byte [] media = new byte [6];
                       for (int j = 0; j < 6; j++)
                        {
                           media[j] = bd.ReadByte  ();
                      
                        }
    
                        //ID = Convert.ToInt32(media );//
    
                    
                    }  */
                fd.Close();
    
    
    
                //读取dbf文件结束
            }
    
            ulong big2little(int code)      //将big位序转换为little位序
            {
                ulong value;
                value = ((((ulong)(code) & (ulong)0x000000ffUL) << 24) | (((ulong)(code) & (ulong)0x0000ff00UL) << 8) | (((ulong)(code) & (ulong)0x00ff0000UL) >> 8) | (((ulong)(code) & (ulong)0xff000000UL) >> 24));
                return value;
            }
    
            private void button4_Click(object sender, EventArgs e)
            {
                MessageBox.Show("请选择要写入的Shapefile文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                string shpfilepath = "";
    
                int FileCode = 0;   //文件代码
                int Unused = 0;     //未使用
                int FileLength = 0; //文件长度
                int Version = 0;    //版本
                int ShapeType = 0;  //Shape类型
    
                double Xmin = 0;    //边界盒
                double Ymin = 0;
                double Xmax = 0;
                double Ymax = 0;
                double Zmin = 0;
                double Zmax = 0;
                double Mmin = 0;
                double Mmax = 0;
    
    
    
                //原始数据
    
                //将折线点坐标存入数组中,下列数据仅起示例作用
    
                double[][] pointx = new double[][]
                     {  new double []{0,100,150,160,200},
                        new double []{10,40},
                       
                     
                     };
                double[][] pointy = new double[][]
                
                    {   new double []{0,50,100,150,200},
                        new double []{10,90},
                        
                     
                       };
    
    
    
    
                int RecorderNumber = 0; //Shp文件的记录数  
                RecorderNumber = (int)pointx.GetLength(0); //Shp文件的记录数,即有数据数组中存储的连续折线数目
    
    
    
                //保存Shpe文件
                saveFileDialog1.Filter = "shapefiles(*.shp)|*.shp|All files(*.*)|*.*";
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                    shpfilepath = saveFileDialog1.FileName;
    
                FileStream fw = new FileStream(shpfilepath, FileMode.OpenOrCreate, FileAccess.Write);   //文件流形式
                BinaryWriter bw = new BinaryWriter(fw);//打开二进制文件
                bw.Flush();
    
                //保存shx文件
                string shxpath = shpfilepath.Remove(shpfilepath.Length - 1, 1) + "x";
    
                FileStream fu = new FileStream(shxpath, FileMode.OpenOrCreate, FileAccess.Write);   //文件流形式
                BinaryWriter bu = new BinaryWriter(fu);//打开二进制文件
                bu.Flush();
    
    
                //确定文件头信息
                FileCode = 9994;   //文件代码
                Unused = 0;     //未使用
                //边界盒,通过计算所有坐标中的最大、最小值确定,以下开始计算
                Xmin = pointx[0][0];
                Ymin = pointy[0][0];
                Xmax = pointx[0][0];
                Ymax = pointy[0][0];
                int Arraynum = 0;   //数据数组中总的元素数目
                foreach (double[] pont in pointx)
                    foreach (double pot in pont)
                    {
                        Arraynum++;
                        if (pot > Xmax)
                        {
                            Xmax = pot;
                        }
                        else if (pot < Xmin)
                        {
                            Xmin = pot;
                        }
    
                    }
                foreach (double[] pont in pointy)
                    foreach (double pot in pont)
                    {
                        if (pot > Ymax)
                        {
                            Ymax = pot;
                        }
                        else if (pot < Ymin)
                        {
                            Ymin = pot;
                        }
    
                    }
                //边界盒计算完毕
                Zmin = 0.0;
                Zmax = 0.0;
                Mmin = 0.0;
                Mmax = 0.0;
                FileLength = 50 + 28 * RecorderNumber + 8 * Arraynum; //文件长度  FileLength以字为单位,一字等于2字节,等于16位 FileLength=50+ (4+22) * RecorderNumber+所有的Parts和Points数组的大小   66
                Version = 1000;    //版本
                ShapeType = 3;    //Shape类型,表示线状目标
    
    
    
    
                ////写文件头, shx文件的文件头与shp文件基本一致,只是 FileLength不同
                //File Code
                //将little位序转换为big位序
                byte[] lbt = BitConverter.GetBytes(FileCode);  //将int转变为byte
                byte[] bbt = new byte[4];             //用于存放big byte,维数为4
                bbt[0] = lbt[3];                       //0
                bbt[1] = lbt[2];                       //0
                bbt[2] = lbt[1];                       //39
                bbt[3] = lbt[0];                       //10
                for (int i = 0; i < 4; i++)
                {
                    bw.Write(bbt[i]);
                    bu.Write(bbt[i]);
                }
    
                for (int i = 0; i < 5; i++)
                {
                    bw.Write(Unused);
                    bu.Write(Unused);
                }
    
    
                //File Length
                byte[] lbt1 = BitConverter.GetBytes(FileLength);  //将int转变为byte
                bbt[0] = lbt1[3];
                bbt[1] = lbt1[2];
                bbt[2] = lbt1[1];
                bbt[3] = lbt1[0];
                for (int i = 0; i < 4; i++)
                {
                    bw.Write(bbt[i]);
                }
    
                FileLength = 50 + 4 * RecorderNumber; // shx文件长度,以字为单位,等于 50 + 4*记录数
    
                //File Length
                lbt1 = BitConverter.GetBytes(FileLength);  //将int转变为byte
                bbt[0] = lbt1[3];
                bbt[1] = lbt1[2];
                bbt[2] = lbt1[1];
                bbt[3] = lbt1[0];
                for (int i = 0; i < 4; i++)
                {
                    bu.Write(bbt[i]);
                }
    
                bw.Write(Version);  //版本
                bu.Write(Version);
    
                bw.Write(ShapeType);  //Shape类型
                bu.Write(ShapeType);
    
                bw.Write(Xmin);    //shp边界盒
                bw.Write(Ymin);
                bw.Write(Xmax);
                bw.Write(Ymax);
                bw.Write(Zmin);
                bw.Write(Zmax);
                bw.Write(Mmin);
                bw.Write(Mmax);
    
                bu.Write(Xmin);   //shx边界盒
                bu.Write(Ymin);
                bu.Write(Xmax);
                bu.Write(Ymax);
                bu.Write(Zmin);
                bu.Write(Zmax);
                bu.Write(Mmin);
                bu.Write(Mmax);
    
                //文件头结束
    
                //写文件主要信息
    
    
                int RecorderNum = 0;    //记录号
                int ContentLength = 0;  //记录长度
                int Offset = 50;       //Shp文件对应记录的起始位置相对于shap文件起始位置的位移量
                // int Num = 0;
    
    
                RecorderNum = 1;
                for (int i = 0; i < RecorderNumber; i++, RecorderNum++)
                {
    
                    ContentLength = ((int)pointx[i].GetLength(0) * 8 + 24);
    
                    // Write RecorderNum
                    byte[] lbt2 = BitConverter.GetBytes(RecorderNum);  //将int转变为byte
                    byte[] bbt2 = new byte[4];             //用于存放big byte,维数为4
                    bbt2[0] = lbt2[3];
                    bbt2[1] = lbt2[2];
                    bbt2[2] = lbt2[1];
                    bbt2[3] = lbt2[0];
                    for (int j = 0; j < 4; j++)
                    {
                        bw.Write(bbt2[j]);
                    }
    
                    // Write  offset of shx
                    lbt2 = BitConverter.GetBytes(Offset);  //将int转变为byte
                    bbt2[0] = lbt2[3];
                    bbt2[1] = lbt2[2];
                    bbt2[2] = lbt2[1];
                    bbt2[3] = lbt2[0];
                    for (int j = 0; j < 4; j++)
                    {
                        bu.Write(bbt2[j]);
                    }
    
                    // Write  ContentLength 
                    lbt2 = BitConverter.GetBytes(ContentLength);  //将int转变为byte
                    bbt2[0] = lbt2[3];
                    bbt2[1] = lbt2[2];
                    bbt2[2] = lbt2[1];
                    bbt2[3] = lbt2[0];
                    for (int j = 0; j < 4; j++)
                    {
                        bw.Write(bbt2[j]);
                        bu.Write(bbt2[j]);
                    }
    
                    Offset = Offset + ContentLength + 4;   //位移量增加
    
                    bw.Write(ShapeType);
                    double Xmin1 = pointx[i][0];    //边界盒
                    double Ymin1 = pointy[i][0];
                    double Xmax1 = pointx[i][0];
                    double Ymax1 = pointy[i][0];
    
                    for (int j = 1; j < (int)pointx[i].GetLength(0); j++)    //计算边界
                    {
                        if (Xmin1 > pointx[i][j])
                        {
                            Xmin1 = pointx[i][j];
                        }
                        if (Xmax1 < pointx[i][j])
                        {
                            Xmin1 = pointx[i][j];
                        }
                        if (Ymin1 > pointy[i][j])
                        {
                            Ymin1 = pointy[i][j];
                        }
                        if (Ymax1 < pointy[i][j])
                        {
                            Ymax1 = pointy[i][j];
                        }
    
                    }
    
                    bw.Write(Xmin1);
                    bw.Write(Ymin1);
                    bw.Write(Xmax1);
                    bw.Write(Ymax1);
    
                    int Numparts = 1;  //当前线目标所包含的子线段的个数为1
                    int Numpoints = (int)pointx[i].GetLength(0); //当前线目标所包含的顶点个数
    
                    bw.Write(Numparts);
                    bw.Write(Numpoints);
    
                    /* 
                      
                     int[] Parts = new int[Numparts];
                     Parts[0] = 0;   //由于只有一个子线段,故为0
                     for (int j = 0; j  < Numparts; j ++)
                     {
                         bw.Write(Parts [j]);
                     }
                      
                     */
                    int parts = 0;
                    bw.Write(parts);
                    for (int j = 0; j < Numpoints; j++)
                    {
                        bw.Write(pointx[i][j]);
                        bw.Write(pointy[i][j]);
                    }
    
    
    
                }
                fw.Close();
                fu.Close();
    
    
                //保存dbf文件
                string dbfpath = shpfilepath.Remove(shpfilepath.Length - 3, 3) + "dbf";
    
                FileStream fd = new FileStream(dbfpath, FileMode.OpenOrCreate, FileAccess.Write);   //文件流形式
                BinaryWriter bd = new BinaryWriter(fd);//打开二进制文件
                bd.Flush();
    
                byte dbf_version = 3;             //版本信息
                bd.Write(dbf_version);
    
                System.DateTime today = System.DateTime.Now;
                byte[] date = new byte[3];    //更新日期
                date[0] = Convert.ToByte(today.Year - 1900);
                date[1] = Convert.ToByte(today.Month);
                date[2] = Convert.ToByte(today.Day);
    
                for (int i = 0; i < 3; i++)
                {
                    bd.Write(date[i]);
                }
    
                int recordnumb = RecorderNumber;               //文件中的记录数
                bd.Write(recordnumb);
    
                short HeaderByteNum;          //文件头中的字节数
                HeaderByteNum = 33 + 32 * 1;   //记录项个数,默认为1
                bd.Write(HeaderByteNum);
    
                short RecordByteNum = 7;          //一条记录中的字节数
                bd.Write(RecordByteNum);
    
                short Reservd1 = 0;               //保留字节
                bd.Write(Reservd1);
    
                byte Flag4s = 0;                  //表示未完成的操作
                bd.Write(Flag4s);
    
                byte EncrypteFlag = 0;            //编密码标记
                bd.Write(EncrypteFlag);
    
                int Unused1 = 0;
                for (int i = 0; i < 3; i++)   //保留字节,用于多用户处理时使用
                {
                    bd.Write(Unused1);
                }
    
                byte MDXFlag = 0;          //DBF文件的MDX标志
                bd.Write(MDXFlag);
    
                byte LDriID = 77;           //Language driver ID
                bd.Write(LDriID);
    
                short Reserved2 = 0;       //保留字节
                bd.Write(Reserved2);
    
    
                //int fieldscount = 1;       //记录项个数,默认情况下只有一个ID字段,即fieldscount = 1
    
    
    
                byte[] name = new byte[11];       //记录项名称,是ASCII码值
                name[0] = 73;    // 'I'
                name[1] = 100;   // 'd'
    
                for (int i = 2; i < 11; i++)
                {
                    name[i] = 0;
                }
                for (int i = 0; i < 11; i++)
                {
                    bd.Write(name[i]);
                }
    
                byte fieldType = 78;      //'N'                 //记录项数据类型,是ASCII码值。(B二进制、C字符型、D日期型、G各种字符、L逻辑型、M各种字、N)
                bd.Write(fieldType);
    
                int reserved3 = 0;                    //保留字节
                bd.Write(reserved3);
    
                byte fieldLength = 6;                 //记录项长度,二进制型
                bd.Write(fieldLength);
    
                byte decimalCount = 0;                //记录项精度,二进制型
                bd.Write(decimalCount);
    
                short reserved4 = 0;                  //保留字节
                bd.Write(reserved4);
    
                byte workID = 0;                      //工作区ID
                bd.Write(workID);
    
                short[] Reserved5 = new short[5];   //保留字节
                for (int i = 0; i < 5; i++)
                {
                    Reserved5[i] = 0;
                    bd.Write(Reserved5[i]);
    
                }
    
    
                byte mDXFlag1 = 0;                     //MDX标识
                bd.Write(mDXFlag1);
    
                byte terminator = 13; //记录项终止标志      
                bd.Write(terminator);
    
    
                //文件内容
                /*  byte[] f1 = new byte[] { 0,0,0,0,13};
                  for (int k = 0; k < 5;k++ )
                  {
                      bd.Write(f1[k]);
                  }*/
    
    
                for (int i = 0; i < RecorderNumber; i++)
                {
                    //byte []media = new byte []{32,32,32,32,32,32,48};
    
                    char[] sd = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', '0' };
                    for (int j = 0; j < 7; j++)
                    {
                        bd.Write(sd[j]);
                    }
                }
                byte f3 = 26;
                bd.Write(f3);
                fd.Close();
    
    
    
    
    
                //文件写完
    
    
                MessageBox.Show("已写完!");
            }
    
    
        }
        struct Polygon_shape
        {
            public double Box1; //边界盒
            public double Box2; //边界盒
            public double Box3; //边界盒
            public double Box4; //边界盒
            public int NumParts; //部分的数目
            public int NumPoints; //点的总数目
            public ArrayList Parts; //在部分中第一个点的索引
            public ArrayList Points; //所有部分的点
        }
        struct Point_shape
        {
            public double X;
            public double Y;
        }
        struct PolyLine_shape
        {
            public double[] Box; //边界盒
            public int NumParts; //部分的数目
            public int NumPoints; //点的总数目
            public ArrayList Parts; //在部分中第一个点的索引
            public ArrayList Points; //所有部分的点
        }
    }

    2013年11月11日 8:57
  • 上面是找到的范例。但是运行之后还是有点错误。请会的同学帮忙改下。

    2013年11月11日 8:59
  • Hi 刚参加工作没多久希望能和大家多多学习,

      欢迎你来到MSDN中文论坛。我能理解你找到范例能够解决你的问题的喜悦,但是这个例子是个人写的,建议你最好在他的博客园里评价里问下写这个博客的作者相关问题,其二,你没有贴出任何有关的问题关于这段代码的,我们不可能在没有开发环境的前提下,还有没有在错误代码以及错误所在的行的情况下精确描述出或者揣测出你的症结所在,希望你能够理解。

     


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年11月12日 2:50
    版主