/// <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)); }
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); }
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); }
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); }
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 <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 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)); }
private Point ReadPoint(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM) { return(new Point(ReadCoordinate(reader, wkbByteOrder, type, includeAltitude, includeM))); }
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"); } } }
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); }
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 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); }