解析shp文件

</pre><pre name="code" class="csharp">在网上找的代码,经过自己的修改~为了避免自己忘记,在这里mark一下~



 public void openshp()
        {
             string filename = null;
            //Geomtry = new List<ESRI_POINT>();
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.Filter = "shape files (*.shp)|*.shp|All files (*.*)|*.*";
            openDialog.FilterIndex = 1;
            openDialog.RestoreDirectory = true;
            if (openDialog.ShowDialog() == DialogResult.OK)
                filename = openDialog.FileName;
            string pathnode = Path.GetDirectoryName(filename);
            filename = Path.GetFileNameWithoutExtension(filename);

            string shpfilepath = pathnode + "\\" + filename + ".shp";
            string shxfilepath = pathnode + "\\" + filename + ".shx";
            try
            {
                //先读取.shx文件,得到文件的总字节长度    @"E:\素材\墨西哥Shp数据(ArcGIS)\" +
                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;
                }
                //打开.shp文件,读取x,y坐标的信息
                fs = new FileStream(shpfilepath, FileMode.Open, FileAccess.Read);   //文件流形式
                BinaryFile = new BinaryReader(fs);     //打开二进制文件   

                BinaryFile.ReadBytes(32);  //先读出36个字节,紧接着是Box边界合
                int shapetype = BinaryFile.ReadInt32();

                double Left = BinaryFile.ReadDouble(); //读出整个shp图层的边界合   
                double Bottom = BinaryFile.ReadDouble();
                double Right = BinaryFile.ReadDouble();
                double Top = BinaryFile.ReadDouble();


                BinaryFile.ReadBytes(32);  //   shp中尚未使用的边界盒    


                //Get Shape Data From Here On
                int stype;
                double x, y;
                double left, right, top, bottom;

                int partcount;
                int pointcount;
                switch (shapetype)
                {
                    case 1://single point

                        // geolayer.shapeType = CGConstants.CGShapeType.SHAPE_POINT;
                        for (int i = 0; i < shapecount; i++)
                        {
                            // CGGeoShape.CGGeoPoint gps = new CGGeoShape.CGGeoPoint();
                            ESRI_POINT shapPoint = new ESRI_POINT();

                            BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype

                            /* stype = BinaryFile.ReadInt32();
                                  
                             if (stype != shapetype)
                                 continue;

                             */
                            x = BinaryFile.ReadDouble();
                            y = BinaryFile.ReadDouble();

                            shapPoint.objectID = i;
                            shapPoint.objectUID = i;

                            shapPoint.x = x;
                            shapPoint.y = y;
                            shapPoint.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);
                            Geomtry_Point.Add(shapPoint);
                        }
                        StreamWriter sw = new StreamWriter("point.txt");



                        foreach (ESRI_POINT p in Geomtry_Point)
                        {

                            sw.WriteLine("{0},{1},{2} ", p.x, -1 * p.y, 0);

                        }

                        sw.Close();
                        break;

                    case 8://multi points layer
                        break;

                    case 3://Polyline layer
                        //  geolayer.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 step
                            ESRI_POLYLINE shapePolyline = new ESRI_POLYLINE();
                            BinaryFile.ReadBytes(12);//记录头8个字节和一个int(4个字节)的shapetype

                            //	 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 file
                            //节点开始位置
                            for (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 coordinates
                            //读坐标
                            for (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);
                                shapePolyline.OID = i;
                                shapePolyline.XPOINTS = xpoints;
                                shapePolyline.YPOINTS = ypoints;
                            }
                            Geomtry_Line.Add(shapePolyline);
                        }
                        StreamWriter sw2 = new StreamWriter("line.txt");
                        count = 1;
                        foreach (ESRI_POLYLINE p in Geomtry_Line)
                        {

                            sw2.WriteLine("{0} ", p.OID);
                            int number = p.XPOINTS.Length;
                            for (int i = 0; i < number; i++)
                            {
                                sw2.WriteLine("{0}  ,{1}", p.XPOINTS[i], -1 * p.YPOINTS[i]);
                            }
                        }
                        sw2.Close();
                        break;
                    case 5://Polygon layer 

                        for (int i = 0; i < shapecount; i++)
                        {
                            ESRI_POLYGON shapePolygon = new ESRI_POLYGON();
                            BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
                            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 file 
                            for (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];
                            //读坐标
                            for (int j = 0; j < pointcount; j++)
                            {
                                x = BinaryFile.ReadDouble();
                                y = BinaryFile.ReadDouble();
                                xpoints[j] = x;
                                ypoints[j] = y;
                                zpoints[j] = 0;
                            }
                            if (pointcount > 1)
                            {
                                shapePolygon.OID = i;
                                shapePolygon.XPOINTS = xpoints;
                                shapePolygon.YPOINTS = ypoints;
                            }
                        }
                        break;
                    default:
                        return;
                }
            }
            catch (FileNotFoundException ee)
            {
                ee.ToString();

            }

            return;
        }


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值