• C#读取二进制格式的shapefile


    1.定义基本图形类

    namespace Mercator.Shapefile.IO
    {
        /// <summary>
        /// 一个点包括一对以X,Y顺序排列的双精度的坐标
        /// </summary>
        public class Point
        {
            /// <summary>
            /// X坐标
            /// </summary>
            public double X;
    
            /// <summary>
            /// Y坐标
            /// </summary>
            public double Y;
        }
    
        /// <summary>
        /// 一条PolyLine是指一条包含一个或多个部分的有序的顶点集合。
        /// </summary>
        public class Polyline
        {
            /// <summary>
            /// 边界盒,以Xmin,Ymin,Xmax,Ymax的顺序存储。
            /// </summary>
            public double[] Box { get; set; } = new double[4];
    
            /// <summary>
            /// Part的数目
            /// </summary>
            public int NumParts;
    
            /// <summary>
            /// 所有Part的点的总数
            /// </summary>
            public int NumPoints;
    
            /// <summary>
            /// NumParts长度的数组。
            /// 为每条PolyLine存储它在点数组中的第一个点的索引。
            /// 数组索引是从0开始的。
            /// </summary>
            public ArrayList Parts { get; set; } = new ArrayList();
    
            /// <summary>
            /// NumPoints长度的数组。
            /// 在PolyLine中的每一Part的点被首尾相连得存储。
            /// Part2的点跟在Part1的点之后,如此下去。
            /// Part数组对每一Part保持开始点的数组索引。 
            /// 在不同Part间的点之间没有分隔符。
            /// </summary>
            public ArrayList Points { get; set; } = new ArrayList(); //所有Part的点
        }
    
        /// <summary>
        /// 一个多边形包含一个或多个环
        /// </summary>
        public class Polygon : Polyline
        { 
        }
    }

    2.读取二进制文件

            public void ReadSHP(string shapefilename)
            {
                var polygons = new ArrayList();//面集合
                var polylines = new ArrayList();//线集合
                var points = new ArrayList();//点集合
    
                var stream = new FileStream(shapefilename, FileMode.Open, FileAccess.Read);
                var reader = new BinaryReader(stream);
    
                #region 主文件头包含17个字段,共100个字节,其中包含九个4字节(32位有符号整数,int32)整数字段,紧接着是八个8字节(双精度浮点数)有符号浮点数字段。
                // 字节0–3,文件编号 (永远是十六进制数0x0000270a)
                var file_no = reader.ReadInt32();
    
                // 字节4–23,五个没有被使用的32位整数
                for (int i = 0; i < 5; i++)
                {
                    reader.ReadInt32();
                }
    
                // 字节24–27,文件长度,包括文件头。(用16位整数表示)
                var file_length = reader.ReadInt32();
    
                // 字节28–31,版本
                var file_version = reader.ReadInt32();
    
                // 字节32–35,图形类型
                var file_shape_type = reader.ReadInt32();
    
                // 字节36–67,最小外接矩形 (MBR),也就是一个包含shapefile之中所有图形的矩形。以四个浮点数表示,分别是X坐标最小值,Y坐标最小值,X坐标最大值,Y坐标最大值。
                var x_min = reader.ReadDouble();
                var y_max = reader.ReadDouble();
                var x_max = reader.ReadDouble();
                var y_min = reader.ReadDouble();
    
                // 字节68–83,Z坐标值的范围。以两个浮点数表示,分别是Z坐标的最小值与Z坐标的最大值。
                var z_min = reader.ReadDouble();
                var z_max = reader.ReadDouble();
    
                // 字节84–99,M坐标值的范围。以两个浮点数表示,分别是M坐标的最小值与M坐标的最大值。
                var m_min = reader.ReadDouble();
                var m_max = reader.ReadDouble();
                #endregion
    
                switch (file_shape_type)
                {
                    case 1: // Point(点)
                        while (reader.PeekChar() != -1)
                        {
                            var point = new Point();
    
                            #region 记录头,每个数据记录以一个8字节记录头开始
                            //字节0–3,记录编号 (从1开始)
                            var record_no = reader.ReadUInt32();
    
                            //字节4–7,记录长度(以16位整数表示)
                            int record_length = reader.ReadInt32();
                            #endregion
    
                            //读取第i个记录
                            reader.ReadInt32();
                            point.X = reader.ReadDouble();
                            point.Y = -1 * reader.ReadDouble();
                            points.Add(point);
                        }
                        break;
                    case 3: // Polyline(折线)
                        while (reader.PeekChar() != -1)
                        {
                            var polyline = new Polyline();
    
                            #region 记录头,每个数据记录以一个8字节记录头开始
                            //字节0–3,记录编号 (从1开始)
                            var record_no = reader.ReadUInt32();
    
                            //字节4–7,记录长度(以16位整数表示)
                            int record_length = reader.ReadInt32();
                            #endregion
    
                            // 字节0–3,图形类型
                            var shape_type = reader.ReadInt32();
                            // 字节4-,图形内容,变长记录的内容由图形的类型决定。
                            for (int i = 0; i < 4; i++)
                            {
                                polyline.Box[i] = reader.ReadDouble();
                            }
                            // 多边形中环的数目
                            polyline.NumParts = reader.ReadInt32();
                            // 所有环的点的总数目
                            polyline.NumPoints = reader.ReadInt32();
                            for (int i = 0; i < polyline.NumParts; i++)
                            {
                                var parts = reader.ReadInt32();
                                polyline.Parts.Add(parts);
                            }
                            for (int i = 0; i < polyline.NumPoints; i++)
                            {
                                var point = new Point();
                                point.X = reader.ReadDouble();
                                point.Y = -1 * reader.ReadDouble();
                                polyline.Points.Add(point);
                            }
                            polylines.Add(polyline);
                        }
                        break;
                    case 5: // Polygon(多边形)
                        #region 记录
                        while (reader.PeekChar() != -1)
                        {
                            var polygon = new Polygon();
    
                            #region 记录头,每个数据记录以一个8字节记录头开始
                            //字节0–3,记录编号 (从1开始)
                            var record_no = reader.ReadUInt32();
    
                            //字节4–7,记录长度(以16位整数表示)
                            int record_length = reader.ReadInt32();
                            #endregion
    
                            #region 实际记录
                            // 字节0–3,图形类型
                            var shape_type = reader.ReadInt32();
                            // 字节4-,图形内容,变长记录的内容由图形的类型决定。
                            for (int i = 0; i < 4; i++)
                            {
                                polygon.Box[i] = reader.ReadDouble();
                            }
                            // 多边形中环的数目
                            polygon.NumParts = reader.ReadInt32();
                            // 所有环的点的总数目
                            polygon.NumPoints = reader.ReadInt32();
                            for (int i = 0; i < polygon.NumParts; i++)
                            {
                                var parts = reader.ReadInt32();
                                polygon.Parts.Add(parts);
                            }
                            for (int i = 0; i < polygon.NumPoints; i++)
                            {
                                var point = new Point();
                                point.X = reader.ReadDouble();
                                point.Y = -1 * reader.ReadDouble();
                                polygon.Points.Add(point);
                            }
                            polygons.Add(polygon);
                            #endregion
                        }
                        #endregion
                        break;
                }
            }
  • 相关阅读:
    各大云服务器的对比
    程式上传的功能修改
    如何免费拥有一个聊天机器人
    自学网站大全(值得收藏)
    三菱PLC串口通信的IO控制
    免费下载知网、万方等数据库文档教程
    QT--Android之全配置教程
    QT--Android之Android环境配置
    QT--Android之Java环境配置
    安装纯净的Windows或者Ubuntu系统教程
  • 原文地址:https://www.cnblogs.com/mercator/p/12631494.html
Copyright © 2020-2023  润新知