コード例 #1
0
        /// <summary>
        /// Reads a geometry from an BinaryReader containing of Well Known Binary.
        /// </summary>
        /// <param name="data">A BinaryReader containing Well Known Binary</param>
        /// <returns>A geometry object.</returns>
        public async Task <Geometry> Read(BinaryReader reader)
        {
            // Get the first Byte in the array. This specifies if the WKB is in
            // XDR (big-endian) format of NDR (little-endian) format.
            ByteOrder wkbByteOrder = (ByteOrder)reader.ReadByte();

            // Get the type of this geometry.
            WKBShapeType type = (WKBShapeType)NumberReader.ReadUInt32(reader, wkbByteOrder);

            bool includeAltitude = false, includeM = false;

            //check to see if the coordinates should include the Z coordinate
            if (((type > ((WKBShapeType)0x3e8)) && (type < ((WKBShapeType)0x7d0))) || (type > ((WKBShapeType)0xbb8)))
            {
                includeAltitude = true;
            }

            //check to see if the coordinates should include a Measure
            if (type > ((WKBShapeType)0x7d0))
            {
                includeM = true;
            }

            return(await ReadGeometry(reader, wkbByteOrder, type, includeAltitude, includeM));
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        private async Task <MultiPolygon> ReadMultiPolygon(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the number of Polygons.
            int numPolygons = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array for the Polygons.
            MultiPolygon polygons = new MultiPolygon(numPolygons);

            Polygon p;

            // Loop on the number of polygons.
            for (int i = 0; i < numPolygons; i++)
            {
                // read polygon header
                reader.ReadByte();
                NumberReader.ReadUInt32(reader, wkbByteOrder);

                p = await ReadPolygon(reader, wkbByteOrder, type, includeAltitude, includeM);

                // Create the next polygon and add it to the array.
                polygons.Geometries.Add(p);
            }

            //Create and return the MultiPolygon.
            return(polygons);
        }
コード例 #4
0
        private async Task <MultiLineString> ReadMultiLineString(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the number of linestrings in this multLineString.
            int numLineStrings = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array for the linestrings .
            MultiLineString mline = new MultiLineString(numLineStrings);

            LineString line;

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

                line = await ReadLineString(reader, wkbByteOrder, type, includeAltitude, includeM);

                // Create the next linestring and add it to the array.
                mline.Geometries.Add(line);
            }

            // Create and return the MultiLineString.
            return(mline);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        private async Task <LineString> ReadLineString(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            var c = await ReadCoordinates(reader, wkbByteOrder, type, includeAltitude, includeM);

            return(new LineString(c));
        }
コード例 #8
0
 private Point ReadPoint(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
 {
     return(new Point(ReadCoordinate(reader, wkbByteOrder, type, includeAltitude, includeM)));
 }
コード例 #9
0
        private async Task <Geometry> ReadGeometry(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            switch (type)
            {
            case WKBShapeType.WkbPoint:
            case WKBShapeType.WkbPointZ:
            case WKBShapeType.WkbPointM:
            case WKBShapeType.WkbPointZM:
                return(ReadPoint(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbLineString:
            case WKBShapeType.WkbLineStringZ:
            case WKBShapeType.WkbLineStringM:
            case WKBShapeType.WkbLineStringZM:
                return(await ReadLineString(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbPolygon:
            case WKBShapeType.WkbPolygonZ:
            case WKBShapeType.WkbPolygonM:
            case WKBShapeType.WkbPolygonZM:
                return(await ReadPolygon(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbMultiPoint:
            case WKBShapeType.WkbMultiPointZ:
            case WKBShapeType.WkbMultiPointM:
            case WKBShapeType.WkbMultiPointZM:
                return(ReadMultiPoint(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbMultiLineString:
            case WKBShapeType.WkbMultiLineStringZ:
            case WKBShapeType.WkbMultiLineStringM:
            case WKBShapeType.WkbMultiLineStringZM:
                return(await ReadMultiLineString(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbMultiPolygon:
            case WKBShapeType.WkbMultiPolygonZ:
            case WKBShapeType.WkbMultiPolygonM:
            case WKBShapeType.WkbMultiPolygonZM:
                return(await ReadMultiPolygon(reader, wkbByteOrder, type, includeAltitude, includeM));

            case WKBShapeType.WkbGeometryCollection:
            case WKBShapeType.WkbGeometryCollectionZ:
            case WKBShapeType.WkbGeometryCollectionM:
            case WKBShapeType.WkbGeometryCollectionZM:
                return(await ReadGeometryCollection(reader, wkbByteOrder, type, includeAltitude, includeM));

            default:
                if (!Enum.IsDefined(typeof(WKBShapeType), type))
                {
                    throw new ArgumentException("Geometry type not recognized");
                }
                else
                {
                    throw new NotSupportedException("Geometry type '" + type + "' not supported");
                }
            }
        }
コード例 #10
0
        private async Task <CoordinateCollection> ReadLinearRing(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            var ring = await ReadCoordinates(reader, wkbByteOrder, type, includeAltitude, includeM);

            int count = ring.Count;

            //Check to see if ring is closed. If not add the first point to the end.
            if (count > 0 && ring[0] != ring[count - 1])
            {
                ring.Add(ring[0]);
            }

            return(ring);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        private Coordinate ReadCoordinate(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            double lon = NumberReader.ReadDouble(reader, wkbByteOrder);
            double lat = NumberReader.ReadDouble(reader, wkbByteOrder);

            Coordinate coordinate;

            if (!includeAltitude)
            {
                coordinate = new Coordinate(lat, lon);
            }
            else
            {
                double z = NumberReader.ReadDouble(reader, wkbByteOrder);
                coordinate = new Coordinate(lat, lon, z);
            }

            if (includeM)
            {
                //Read past the measure value if included
                NumberReader.ReadDouble(reader, wkbByteOrder);
            }

            return(coordinate);
        }