Exemple #1
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);
        }
Exemple #2
0
        /// <summary>
        /// Reads the BoundingBox property of a record
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <returns>A bounding box of a record</returns>
        private BoundingBox ReadBoundingBox(BinaryReader reader)
        {
            //Read the standard bounding latitude and longitude values of the bounding box
            var minX = NumberReader.ReadDoubleLE(reader);
            var minY = NumberReader.ReadDoubleLE(reader);
            var maxX = NumberReader.ReadDoubleLE(reader);
            var maxY = NumberReader.ReadDoubleLE(reader);

            var width  = Math.Abs(maxX - minX);
            var height = Math.Abs(maxY - minY);
            var center = new Coordinate(maxY - height / 2, maxX - width / 2);

            return(new BoundingBox(center, width, height));
        }
Exemple #3
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);
        }
        private async Task <Polygon> ReadPolygon(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the Number of rings in this Polygon.
            int numRings = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            var c = await ReadLinearRing(reader, wkbByteOrder, type, includeAltitude, includeM);

            Polygon shell = new Polygon(c);

            // Create a new array of linearrings for the interior rings.
            for (int i = 0; i < (numRings - 1); i++)
            {
                c = await ReadLinearRing(reader, wkbByteOrder, type, includeAltitude, includeM);

                shell.InteriorRings.Add(c);
            }

            // Create and return the Poylgon.
            return(shell);
        }
        private MultiPoint ReadMultiPoint(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the number of points in this multPoint.
            int numPoints = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array for the points.
            MultiPoint points = new MultiPoint();

            // Loop on the number of points.
            for (int i = 0; i < numPoints; i++)
            {
                // Read point header
                reader.ReadByte();
                NumberReader.ReadUInt32(reader, wkbByteOrder);

                // Create the next point and add it to the point array.
                points.Geometries.Add(ReadPoint(reader, wkbByteOrder, type, includeAltitude, includeM));
            }

            return(points);
        }
        private async Task <CoordinateCollection> ReadCoordinates(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the number of points in this linestring.
            int numPoints = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array of coordinates.
            var coords = new CoordinateCollection();

            // Loop on the number of points in the ring.
            for (int i = 0; i < numPoints; i++)
            {
                coords.Add(ReadCoordinate(reader, wkbByteOrder, type, includeAltitude, includeM));
            }

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

            return(coords);
        }
        private async Task <GeometryCollection> ReadGeometryCollection(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // The next byte in the array tells the number of geometries in this collection.
            int numGeometries = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array for the geometries.
            var geographies = new GeometryCollection(numGeometries);

            Geometry g;

            // Loop on the number of geometries.
            for (int i = 0; i < numGeometries; i++)
            {
                g = await ReadGeometry(reader, wkbByteOrder, type, includeAltitude, includeM);

                // Call the main create function with the next geometry.
                geographies.Geometries.Add(g);
            }

            // Create and return the next geometry.
            return(geographies);
        }
Exemple #8
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);
        }