private static void ReadMultiLineString(Stream data, FeatureSetPack results) { int numLineStrings = ReadInt32(data); ShapeRange shp = new ShapeRange(FeatureType.Line); List <double[]> strings = new List <double[]>(); int partOffset = 0; for (int iString = 0; iString < numLineStrings; iString++) { // Each of these needs to read a full WKBLineString data.Seek(5, SeekOrigin.Current); // ignore header int numPoints = ReadInt32(data); double[] coords = ReadDouble(data, 2 * numPoints); PartRange lPrt = new PartRange(FeatureType.Line) { PartOffset = partOffset, NumVertices = numPoints }; shp.Parts.Add(lPrt); partOffset += coords.Length / 2; strings.Add(coords); } double[] allVertices = new double[partOffset * 2]; int offset = 0; foreach (double[] ring in strings) { Array.Copy(ring, 0, allVertices, offset, ring.Length); offset += ring.Length; } results.Add(allVertices, shp); }
/// <summary> /// This assumes that the byte order and shapetype have already been read. /// </summary> /// <param name="data"></param> /// <param name="results"></param> private static void ReadPoint(Stream data, FeatureSetPack results) { ShapeRange sr = new ShapeRange(FeatureType.MultiPoint); PartRange prt = new PartRange(FeatureType.MultiPoint); prt.NumVertices = 1; sr.Parts.Add(prt); double[] coord = ReadDouble(data, 2); results.Add(coord, sr); }
private static void ReadMultiPolygon(Stream data, FeatureSetPack results) { int numPolygons = ReadInt32(data); ShapeRange lShp = new ShapeRange(FeatureType.Polygon); List <double[]> rings = new List <double[]>(); int partOffset = 0; for (int iPoly = 0; iPoly < numPolygons; iPoly++) { data.Seek(5, SeekOrigin.Current); // endian and geometry type int numRings = ReadInt32(data); for (int iRing = 0; iRing < numRings; iRing++) { int numPoints = ReadInt32(data); // ring structures are like a linestring without the final point. double[] coords = ReadDouble(data, 2 * numPoints); if (iRing == 0) { // By shapefile standard, the shell should be clockwise if (IsCounterClockwise(coords)) { coords = ReverseCoords(coords); } } else { // By shapefile standard, the holes should be counter clockwise. if (!IsCounterClockwise(coords)) { coords = ReverseCoords(coords); } } PartRange lPrt = new PartRange(FeatureType.Polygon) { PartOffset = partOffset, NumVertices = numPoints }; lShp.Parts.Add(lPrt); partOffset += coords.Length / 2; rings.Add(coords); } } double[] allVertices = new double[partOffset * 2]; int offset = 0; foreach (double[] ring in rings) { Array.Copy(ring, 0, allVertices, offset, ring.Length); offset += ring.Length; } results.Add(allVertices, lShp); }
/// <summary> /// Gets a FeatureSetPack from the WKB /// </summary> /// <param name="data"></param> /// <returns></returns> public static FeatureSetPack GetFeatureSets(Stream data) { FeatureSetPack result = new FeatureSetPack(); while (data.Position < data.Length) { ReadFeature(data, result); } result.StopEditing(); return(result); }
private static void ReadLineString(Stream data, FeatureSetPack results) { int count = ReadInt32(data); double[] coords = ReadDouble(data, 2 * count); ShapeRange lShp = new ShapeRange(FeatureType.Line); PartRange lPrt = new PartRange(FeatureType.Line); lPrt.NumVertices = count; lShp.Parts.Add(lPrt); results.Add(coords, lShp); }
private static void ReadMultiPoint(Stream data, FeatureSetPack results) { int count = ReadInt32(data); ShapeRange sr = new ShapeRange(FeatureType.MultiPoint); PartRange prt = new PartRange(FeatureType.MultiPoint); prt.NumVertices = count; sr.Parts.Add(prt); double[] vertices = new double[count * 2]; for (int iPoint = 0; iPoint < count; iPoint++) { data.ReadByte(); // ignore endian ReadInt32(data); // ignore geometry type double[] coord = ReadDouble(data, 2); Array.Copy(coord, 0, vertices, iPoint * 2, 2); } results.Add(vertices, sr); }
private static void ReadGeometryCollection(Stream data, FeatureSetPack results) { int numGeometries = ReadInt32(data); // Don't worry about "multi-parting" these. Simply create a separate shape // entry for every single geometry here since we have to split out the features // based on feature type. (currently we don't have a mixed feature type for drawing.) for (int i = 0; i < numGeometries; i++) { endian = (ByteOrder)data.ReadByte(); WKBGeometryTypes type = (WKBGeometryTypes)ReadInt32(data); switch (type) { case WKBGeometryTypes.WKBPoint: ReadPoint(data, results); return; case WKBGeometryTypes.WKBLineString: ReadLineString(data, results); return; case WKBGeometryTypes.WKBPolygon: ReadPolygon(data, results); break; case WKBGeometryTypes.WKBMultiPoint: ReadMultiPoint(data, results); break; case WKBGeometryTypes.WKBMultiLineString: ReadMultiLineString(data, results); break; case WKBGeometryTypes.WKBMultiPolygon: ReadMultiPolygon(data, results); break; case WKBGeometryTypes.WKBGeometryCollection: ReadGeometryCollection(data, results); break; } } }
/// <summary> /// Reads only a single geometry into a feature. This may be a multi-part geometry. /// </summary> /// <param name="data">The data to read the features from.</param> /// <param name="results">FeatureSetPack the read features get added to.</param> public static void ReadFeature(Stream data, FeatureSetPack results) { endian = (ByteOrder)data.ReadByte(); WKBGeometryTypes type = (WKBGeometryTypes)ReadInt32(data); switch (type) { case WKBGeometryTypes.WKBPoint: ReadPoint(data, results); return; case WKBGeometryTypes.WKBLineString: ReadLineString(data, results); return; case WKBGeometryTypes.WKBPolygon: ReadPolygon(data, results); break; case WKBGeometryTypes.WKBMultiPoint: ReadMultiPoint(data, results); break; case WKBGeometryTypes.WKBMultiLineString: ReadMultiLineString(data, results); break; case WKBGeometryTypes.WKBMultiPolygon: ReadMultiPolygon(data, results); break; case WKBGeometryTypes.WKBGeometryCollection: ReadGeometryCollection(data, results); break; } }
/// <summary> /// Creates the FeatureSetPackEnumerator based on the specified FeaturSetPack /// </summary> /// <param name="parent">The Pack</param> public FeatureSetPackEnumerator(FeatureSetPack parent) { _parent = parent; _index = -1; }