Пример #1
0
        /// <summary>
        /// Reads the header of a Shapefile
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <returns>The shapefile header</returns>
        private void ReadFileHeader(BinaryReader reader, out ShapefileShapeType shapeType, out BoundingBox bounds)
        {
            // Read File Code.
            int FileCode = NumberReader.ReadIntBE(reader);

            //Verify that the file has the correct file code (9994)
            if (FileCode != 9994)
            {
                throw new FormatException("Invalid FileCode encountered. Expecting a file code of 9994.");
            }

            //Skip unused section
            reader.BaseStream.Seek(20, SeekOrigin.Current);

            // Read the File Length.
            long fileLength = NumberReader.ReadIntBE(reader);

            // Skip the Version number of the shapefile.
            reader.BaseStream.Seek(4, SeekOrigin.Current);

            // Get the shape type of the shapefile. Note that shapefiles can only contain one type of shape per file
            shapeType = (ShapefileShapeType)NumberReader.ReadIntLE(reader);

            // Get the bounding box of the Bounding Box.
            bounds = ReadBoundingBox(reader);
        }
Пример #2
0
        /// <summary>
        /// Reads LineString shapefile
        /// </summary>
        /// <param name="reader">The shapefile stream</param>
        /// <returns>A list of Geometry objects</returns>
        private async Task <List <Geometry> > ReadLineStringData(BinaryReader reader)
        {
            var items = new List <Geometry>();
            int numParts, numPoints;

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                Geometry item;

                // Read Record Header.
                int id          = ReadRecordHeader(reader);
                var boundingBox = ReadBoundingBox(reader);

                // Read the number of Parts and Points in the shape.
                numParts  = NumberReader.ReadIntLE(reader);
                numPoints = NumberReader.ReadIntLE(reader);

                int[] parts = ReadParts(reader, numParts, numPoints);

                //First read all the rings
                var rings = new List <CoordinateCollection>();

                var multiline = new MultiLineString();
                for (int ringID = 0; ringID < numParts; ringID++)
                {
                    var line = new LineString();

                    for (int i = parts[ringID]; i < parts[ringID + 1]; i++)
                    {
                        line.Vertices.Add(ReadCoordinate(reader));
                    }

                    if (optimize)
                    {
                        line.Vertices = await SpatialTools.VertexReductionAsync(line.Vertices, tolerance);
                    }

                    multiline.Geometries.Add(line);
                }

                if (numParts == 1)
                {
                    item = (Geometry)multiline.Geometries[0];
                }
                else
                {
                    item = multiline;
                }

                item.Metadata.ID = id.ToString();
                item.Metadata.Properties.Add("BoundingBox", boundingBox);

                items.Add(item);
            }

            return(items);
        }
Пример #3
0
        /// <summary>
        /// Read the Parts index array for a record
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <param name="numParts">The number of parts in the array</param>
        /// <param name="numPoints">The number of points in total</param>
        /// <returns>An array of part indexes</returns>
        private int[] ReadParts(BinaryReader reader, int numParts, int numPoints)
        {
            int[] parts = new int[numParts + 1];

            for (int i = 0; i < numParts; i++)
            {
                parts[i] = NumberReader.ReadIntLE(reader);
            }

            parts[numParts] = numPoints;

            return(parts);
        }
Пример #4
0
        /// <summary>
        /// Reads MultiPoint shapefile
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <returns>A list of Geometry objects</returns>
        private List <Geometry> ReadMultiPointData(BinaryReader reader)
        {
            var items = new List <Geometry>();
            int numPoints;

            // For each header
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                Geometry item;

                // Read Record Header.
                int id          = ReadRecordHeader(reader);
                var boundingBox = ReadBoundingBox(reader);

                // Num Points.
                numPoints = NumberReader.ReadIntLE(reader);

                if (numPoints == 1) //if there is only one point then create a point geography
                {
                    item = new Point(ReadCoordinate(reader));
                }
                else
                {
                    MultiPoint mp = new MultiPoint(numPoints);

                    // Read in all the Points.
                    for (int i = 0; i < numPoints; i++)
                    {
                        mp.Geometries.Add(new Point(ReadCoordinate(reader)));
                    }

                    item = mp;
                }

                item.Metadata.ID = id.ToString();
                item.Metadata.Properties.Add("Bounding Box", boundingBox);

                items.Add(item);
            }

            return(items);
        }
Пример #5
0
        /// <summary>
        /// Read a shapefile Polygon record.
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <returns>A list of Geometry objects</returns>
        private List <Geometry> ReadPolygonData(BinaryReader reader)
        {
            var items = new List <Geometry>();
            int numParts, numPoints;

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                Geometry item;

                // Read Record Header.
                int id          = ReadRecordHeader(reader);
                var boundingBox = ReadBoundingBox(reader);

                // Read the number of Parts and Points in the shape.
                numParts  = NumberReader.ReadIntLE(reader);
                numPoints = NumberReader.ReadIntLE(reader);

                int[] parts = ReadParts(reader, numParts, numPoints);

                //First read all the rings
                var rings = new List <CoordinateCollection>();

                for (int ringID = 0; ringID < numParts; ringID++)
                {
                    var ring = new CoordinateCollection();

                    for (int i = parts[ringID]; i < parts[ringID + 1]; i++)
                    {
                        ring.Add(ReadCoordinate(reader));
                    }

                    if (optimize)
                    {
                        ring = SpatialTools.VertexReduction(ring, tolerance);
                    }

                    rings.Add(ring);
                }

                // Vertices for a single, ringed polygon are always in clockwise order.
                // Rings defining holes in these polygons have a counterclockwise orientation.

                bool[] IsCounterClockWise = new bool[rings.Count];

                int PolygonCount = 0;

                //determine the orientation of each ring.
                for (int i = 0; i < rings.Count; i++)
                {
                    IsCounterClockWise[i] = rings[i].IsCCW();

                    if (!IsCounterClockWise[i])
                    {
                        PolygonCount++;     //count the number of polygons
                    }
                }

                //if the polygon count is 1 then there is only one polygon to create.
                if (PolygonCount == 1)
                {
                    Polygon polygon = new Polygon();
                    polygon.ExteriorRing = rings[0];
                    if (rings.Count > 1)
                    {
                        for (int i = 1; i < rings.Count; i++)
                        {
                            polygon.InteriorRings.Add(rings[i]);
                        }
                    }

                    item = polygon;
                }
                else
                {
                    MultiPolygon multPolygon = new MultiPolygon();
                    Polygon      poly        = new Polygon();
                    poly.ExteriorRing = rings[0];

                    for (int i = 1; i < rings.Count; i++)
                    {
                        if (!IsCounterClockWise[i])
                        {
                            multPolygon.Geometries.Add(poly);
                            poly = new Polygon(rings[i]);
                        }
                        else
                        {
                            poly.InteriorRings.Add(rings[i]);
                        }
                    }

                    multPolygon.Geometries.Add(poly);

                    item = multPolygon;
                }

                item.Metadata.ID = id.ToString();
                item.Metadata.Properties.Add("Bounding Box", boundingBox);

                items.Add(item);
            }

            return(items);
        }