zoukankan      html  css  js  c++  java
  • 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;
                }
            }
  • 相关阅读:
    e621. Activating a Keystroke When Any Child Component Has Focus
    e587. Filling Basic Shapes
    e591. Drawing Simple Text
    e595. Drawing an Image
    e586. Drawing Simple Shapes
    e636. Listening to All Key Events Before Delivery to Focused Component
    在 PL/SQL 块的哪部分可以对初始变量赋予新值? (选择1项)
    Oracle数据库中,在SQL语句中连接字符串的方法是哪个?(选择1项)
    你判断下面语句,有什么作用?(单选)
    Oracle数据库表空间与数据文件的关系描述正确的是( )
  • 原文地址:https://www.cnblogs.com/mercator/p/12631494.html
Copyright © 2011-2022 走看看