/// <summary> /// Initializes a new instance of the ShapefileHeader class with values read in from the stream. /// </summary> /// <remarks>Reads the header information from the stream.</remarks> /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param> public ShapefileHeader(BigEndianBinaryReader shpBinaryReader) { if (shpBinaryReader == null) throw new ArgumentNullException("shpBinaryReader"); _fileCode = shpBinaryReader.ReadInt32BE(); if (_fileCode != Shapefile.ShapefileId) throw new ShapefileException("The first four bytes of this file indicate this is not a shape file."); // skip 5 unsed bytes shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); _fileLength = shpBinaryReader.ReadInt32BE(); _version = shpBinaryReader.ReadInt32(); Debug.Assert(_version == 1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}",_version)); int shapeType = shpBinaryReader.ReadInt32(); _shapeType = (ShapeGeometryTypes) Enum.Parse(typeof(ShapeGeometryTypes), shapeType.ToString()); //read in and store the bounding box double[] coords = new double[4]; for (int i = 0; i < 4; i++) coords[i] = shpBinaryReader.ReadDouble(); _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // skip z and m bounding boxes. for (int i = 0; i < 4; i++) shpBinaryReader.ReadDouble(); }
/// <summary> /// Initializes a new instance of the ShapefileHeader class with values read in from the stream. /// </summary> /// <remarks>Reads the header information from the stream.</remarks> /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param> public ShapefileHeader(BigEndianBinaryReader shpBinaryReader) { if (shpBinaryReader == null) { throw new ArgumentNullException("shpBinaryReader"); } _fileCode = shpBinaryReader.ReadInt32BE(); if (_fileCode != Shapefile.ShapefileId) { throw new ShapefileException("The first four bytes of this file indicate this is not a shape file."); } // skip 5 unsed bytes shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); _fileLength = shpBinaryReader.ReadInt32BE(); _version = shpBinaryReader.ReadInt32(); Debug.Assert(_version == 1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}", _version)); int shapeType = shpBinaryReader.ReadInt32(); _shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeType.ToString()); //read in and store the bounding box double[] coords = new double[4]; for (int i = 0; i < 4; i++) { coords[i] = shpBinaryReader.ReadDouble(); } _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // skip z and m bounding boxes. for (int i = 0; i < 4; i++) { shpBinaryReader.ReadDouble(); } }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivant geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes) Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) return null; if ( ! ( shapeType == ShapeGeometryTypes.MultiPoint || shapeType == ShapeGeometryTypes.MultiPointM || shapeType == ShapeGeometryTypes.MultiPointZ || shapeType == ShapeGeometryTypes.MultiPointZM)) throw new ShapefileException("Attempting to load a non-multipoint as multipoint."); // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) box[i] = file.ReadDouble(); // Read points int numPoints = file.ReadInt32(); IPoint[] points = new IPoint[numPoints]; for (int i = 0; i < numPoints; i++) points[i] = geometryFactory.CreatePoint(new Coordinate(file.ReadDouble(), file.ReadDouble())); return geometryFactory.CreateMultiPoint(points); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes) Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) return null; if ( ! ( shapeType == ShapeGeometryTypes.Point || shapeType == ShapeGeometryTypes.PointM || shapeType == ShapeGeometryTypes.PointZ || shapeType == ShapeGeometryTypes.PointZM )) throw new ShapefileException("Attempting to load a point as point."); double x= file.ReadDouble(); double y= file.ReadDouble(); ICoordinate external = new Coordinate(x,y); geometryFactory.PrecisionModel.MakePrecise( external); return geometryFactory.CreatePoint(external); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) { return(null); } if (!(shapeType == ShapeGeometryTypes.Point || shapeType == ShapeGeometryTypes.PointM || shapeType == ShapeGeometryTypes.PointZ || shapeType == ShapeGeometryTypes.PointZM)) { throw new ShapefileException("Attempting to load a point as point."); } double x = file.ReadDouble(); double y = file.ReadDouble(); ICoordinate external = new Coordinate(x, y); geometryFactory.PrecisionModel.MakePrecise(external); return(geometryFactory.CreatePoint(external)); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) return null; if( ! ( shapeType == ShapeGeometryTypes.LineString || shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM )) throw new ShapefileException("Attempting to load a non-arc as arc."); //read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { double d= file.ReadDouble(); box[i] =d; } int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); int[] partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ILineString[] lines = new ILineString[numParts]; int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity=length; ICoordinate external; for (int i = 0; i < length; i++) { external = new Coordinate(file.ReadDouble(),file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise( external); points.Add(external); } if (numPoints < 2) lines[part] = geometryFactory.CreateLineString(null as Topology.Geometries.ICoordinate[]); else lines[part] = geometryFactory.CreateLineString(points.ToArray()); } //If we have Z-coordinates, read them.. if (shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM) { //z-Bounds double zMin = file.ReadDouble(); double zMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); if (numPoints > 1) { lines[part].Coordinates[i].Z = val; } } } } //If we have M-coordinates, read them.. if (shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZM) { //m-Bounds double mMin = file.ReadDouble(); double mMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //dont store.. } } } return geometryFactory.CreateMultiLineString(lines); }
/// <summary> /// /// </summary> /// <param name="beReader"></param> private void ReadFeatureHeader(BigEndianBinaryReader beReader) { int recordNumber = beReader.ReadInt32BE(); int contentLength = beReader.ReadInt32BE(); int shapeType = beReader.ReadInt32(); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) { return(null); } if (!(shapeType == ShapeGeometryTypes.LineString || shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM)) { throw new ShapefileException("Attempting to load a non-arc as arc."); } //read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { double d = file.ReadDouble(); box[i] = d; } int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); int[] partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) { partOffsets[i] = file.ReadInt32(); } ILineString[] lines = new ILineString[numParts]; int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; ICoordinate external; for (int i = 0; i < length; i++) { external = new Coordinate(file.ReadDouble(), file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise(external); points.Add(external); } if (numPoints < 2) { lines[part] = geometryFactory.CreateLineString(null as Topology.Geometries.ICoordinate[]); } else { lines[part] = geometryFactory.CreateLineString(points.ToArray()); } } //If we have Z-coordinates, read them.. if (shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM) { //z-Bounds double zMin = file.ReadDouble(); double zMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); if (numPoints > 1) { lines[part].Coordinates[i].Z = val; } } } } //If we have M-coordinates, read them.. if (shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZM) { //m-Bounds double mMin = file.ReadDouble(); double mMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //dont store.. } } } return(geometryFactory.CreateMultiLineString(lines)); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) return null; if ( ! ( shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM)) throw new ShapefileException("Attempting to load a non-polygon as polygon."); // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) box[i] = file.ReadDouble(); int[] partOffsets; int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; for (int i = 0; i < length; i++) { ICoordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble() ); geometryFactory.PrecisionModel.MakePrecise( external); ICoordinate internalCoord = external; // Thanks to Abhay Menon! if (!Double.IsNaN(internalCoord.Y) && !Double.IsNaN(internalCoord.X)) points.Add(internalCoord); } if (points.Count > 0) // Thanks to Abhay Menon! { ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) shells.Add(ring); else { // Orientation check if (CGAlgorithms.IsCCW(points.ToArray())) holes.Add(ring); else shells.Add(ring); } } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) holesForShells.Add(new ArrayList()); // Find holes for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = (ILinearRing) holes[i]; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; ICoordinate testPt = testRing.GetCoordinateN(0); ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (ILinearRing) shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) isContained = true; // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) minShell = tryRing; // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList) holesForShells[j]; holesForThisShell.Add(testRing); } } } //If we have Z-coordinates, read them.. if (shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM) { //z-Bounds double zMin = file.ReadDouble(); double zMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //lines[part].Coordinates[i].Z = val; } } } //If we have M-coordinates, read them.. if (shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZM) { //m-Bounds double mMin = file.ReadDouble(); double mMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //dont store.. } } } IPolygon[] polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) polygons[i] = (geometryFactory.CreatePolygon((ILinearRing) shells[i], (ILinearRing[]) ((ArrayList)holesForShells[i]).ToArray(typeof(ILinearRing)))); if (polygons.Length == 1) return polygons[0]; // It's a multi part return geometryFactory.CreateMultiPolygon(polygons); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (shapeType == ShapeGeometryTypes.NullShape) { return(null); } if (!(shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM)) { throw new ShapefileException("Attempting to load a non-polygon as polygon."); } // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { box[i] = file.ReadDouble(); } int[] partOffsets; int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) { partOffsets[i] = file.ReadInt32(); } ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; for (int i = 0; i < length; i++) { ICoordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise(external); ICoordinate internalCoord = external; // Thanks to Abhay Menon! if (!Double.IsNaN(internalCoord.Y) && !Double.IsNaN(internalCoord.X)) { points.Add(internalCoord); } } if (points.Count > 0) // Thanks to Abhay Menon! { ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) { shells.Add(ring); } else { // Orientation check if (CGAlgorithms.IsCCW(points.ToArray())) { holes.Add(ring); } else { shells.Add(ring); } } } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) { holesForShells.Add(new ArrayList()); } // Find holes for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = (ILinearRing)holes[i]; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; ICoordinate testPt = testRing.GetCoordinateN(0); ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (ILinearRing)shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.EnvelopeInternal; } bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) { isContained = true; } // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList)holesForShells[j]; holesForThisShell.Add(testRing); } } } //If we have Z-coordinates, read them.. if (shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM) { //z-Bounds double zMin = file.ReadDouble(); double zMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //lines[part].Coordinates[i].Z = val; } } } //If we have M-coordinates, read them.. if (shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZM) { //m-Bounds double mMin = file.ReadDouble(); double mMax = file.ReadDouble(); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; for (int i = 0; i < length; i++) { double val = file.ReadDouble(); //dont store.. } } } IPolygon[] polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) { polygons[i] = (geometryFactory.CreatePolygon((ILinearRing)shells[i], (ILinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(ILinearRing)))); } if (polygons.Length == 1) { return(polygons[0]); } // It's a multi part return(geometryFactory.CreateMultiPolygon(polygons)); }