using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Geometries;
namespace GisSharpBlog.NetTopologySuite.IO
{
///
/// A class for reading shapefiles data.
///
[Obsolete("Use ShapefileReader instead")]
public class MyShapeFileReader
{
///
/// Shape features reader.
///
protected ShapeReader shapeReader = null;
private int length = 0;
///
/// Default empty constructor
///
public MyShapeFileReader()
{
shapeReader = new ShapeReader();
}
///
///
///
///
public MyShapeFileReader(GeometryFactory factory)
{
shapeReader = new ShapeReader(factory);
}
///
/// Reads a shapefile containing geographic data,
/// and returns a collection of all the features contained.
/// Since NTS Geometry Model not support Z and M data, those informations are ignored if presents in shapefile.
///
/// Shapefile path.
/// GeometryCollection containing all geometries in shapefile.
public IGeometryCollection Read(string filepath)
{
using (Stream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Read(stream);
}
}
///
/// Reads a generic stream containing geographic data saved as shapefile structure,
/// and returns a collection of all the features contained.
/// Since NTS Geometry Model not support Z and M data, those informations are ignored if presents in shapefile.
///
/// Shapefile data stream.
/// GeometryCollection containing all geometries in shapefile.
protected IGeometryCollection Read(Stream stream)
{
// Read big endian values
using (BigEndianBinaryReader beReader = new BigEndianBinaryReader(stream))
{
// Verify File Code
int fileCode = beReader.ReadInt32BE();
Debug.Assert(fileCode == 9994);
stream.Seek(20, SeekOrigin.Current);
length = beReader.ReadInt32BE();
// Read little endian values
using (BinaryReader leReader = new BinaryReader(stream))
{
ArrayList list = null;
// Verify Version
int version = leReader.ReadInt32();
Debug.Assert(version == 1000);
// ShapeTypes
int shapeType = leReader.ReadInt32();
switch ((ShapeGeometryType) shapeType)
{
case ShapeGeometryType.Point:
case ShapeGeometryType.PointZ:
case ShapeGeometryType.PointM:
case ShapeGeometryType.PointZM:
list = new ArrayList(ReadPointData(stream));
break;
case ShapeGeometryType.LineString:
case ShapeGeometryType.LineStringZ:
case ShapeGeometryType.LineStringM:
case ShapeGeometryType.LineStringZM:
list = new ArrayList(ReadLineStringData(stream));
break;
case ShapeGeometryType.Polygon:
case ShapeGeometryType.PolygonZ:
case ShapeGeometryType.PolygonM:
case ShapeGeometryType.PolygonZM:
list = new ArrayList(ReadPolygonData(stream));
break;
case ShapeGeometryType.MultiPoint:
case ShapeGeometryType.MultiPointZ:
case ShapeGeometryType.MultiPointM:
case ShapeGeometryType.MultiPointZM:
list = new ArrayList(ReadMultiPointData(stream));
break;
case ShapeGeometryType.MultiPatch:
throw new NotImplementedException("FeatureType " + shapeType + " not supported.");
default:
throw new ArgumentOutOfRangeException("FeatureType " + shapeType + " not recognized by the system");
}
IGeometryCollection collection = shapeReader.CreateGeometryCollection(list);
return collection;
}
}
}
///
/// Reads Point shapefile
///
///
protected IList ReadPointData(Stream stream)
{
IList list = new ArrayList();
// Jump to first header
stream.Seek(100, SeekOrigin.Begin);
// Read big endian informations
using (BigEndianBinaryReader beReader = new BigEndianBinaryReader(stream))
{
// Read little endian informations
using (BinaryReader leReader = new BinaryReader(stream))
{
// For each header
while (stream.Position < stream.Length)
{
ReadFeatureHeader(beReader);
ICoordinate coordinate = shapeReader.ReadCoordinate(leReader);
IGeometry point = shapeReader.CreatePoint(coordinate);
list.Add(point);
}
}
}
return list;
}
///
/// Reads LineString shapefile
///
///
///
protected IList ReadLineStringData(Stream stream)
{
IList list = new ArrayList();
// Jump to first header
stream.Seek(100, SeekOrigin.Begin);
// Read big endian informations
using (BigEndianBinaryReader beReader = new BigEndianBinaryReader(stream))
{
// Read little endian informations
using (BinaryReader leReader = new BinaryReader(stream))
{
// For each header
while (stream.Position < stream.Length)
{
ReadFeatureHeader(beReader);
shapeReader.ReadBoundingBox(leReader);
int[] indexParts = null;
int numParts = shapeReader.ReadNumParts(leReader);
int numPoints = shapeReader.ReadNumPoints(leReader);
indexParts = shapeReader.ReadIndexParts(leReader, numParts);
ICoordinate[] coordinates = shapeReader.ReadCoordinates(leReader, numPoints);
list.Add(numParts == 1 ? shapeReader.CreateLineString(coordinates) : shapeReader.CreateMultiLineString(numPoints, indexParts, coordinates));
}
}
}
return list;
}
///
/// Reads Polygon shapefile
///
///
///
protected IList ReadPolygonData(Stream stream)
{
IList list = new ArrayList();
// Jump to first header
stream.Seek(100, SeekOrigin.Begin);
// Read big endian informations
using (BigEndianBinaryReader beReader = new BigEndianBinaryReader(stream))
{
// Read little endian informations
using (BinaryReader reader = new BinaryReader(stream))
{
// For each header
while (stream.Position < stream.Length)
{
ReadFeatureHeader(beReader);
shapeReader.ReadBoundingBox(reader);
int[] indexParts = null;
int numParts = shapeReader.ReadNumParts(reader);
int numPoints = shapeReader.ReadNumPoints(reader);
indexParts = shapeReader.ReadIndexParts(reader, numParts);
ICoordinate[] coordinates = shapeReader.ReadCoordinates(reader, numPoints);
list.Add(numParts == 1 ? shapeReader.CreateSimpleSinglePolygon(coordinates) : shapeReader.CreateSingleOrMultiPolygon(numPoints, indexParts, coordinates));
}
}
}
return list;
}
///
/// Reads MultiPoint shapefile
///
///
///
protected IList ReadMultiPointData(Stream stream)
{
IList list = new ArrayList();
// Jump to first header
stream.Seek(100, SeekOrigin.Begin);
// Read big endian informations
using (BigEndianBinaryReader beReader = new BigEndianBinaryReader(stream))
{
// Read little endian informations
using (BinaryReader reader = new BinaryReader(stream))
{
// For each header
while (stream.Position < stream.Length)
{
ReadFeatureHeader(beReader);
shapeReader.ReadBoundingBox(reader);
int numPoints = shapeReader.ReadNumPoints(reader);
ICoordinate[] coords = new ICoordinate[numPoints];
for (int i = 0; i < numPoints; i++)
{
coords[i] = shapeReader.ReadCoordinate(reader);
}
list.Add(shapeReader.CreateMultiPoint(coords));
}
}
}
return list;
}
///
///
///
///
private void ReadFeatureHeader(BigEndianBinaryReader beReader)
{
int recordNumber = beReader.ReadInt32BE();
int contentLength = beReader.ReadInt32BE();
int shapeType = beReader.ReadInt32();
}
}
}