/// <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); }
/// <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)); }
/// <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); }
/// <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); }