private static Geometry.GeometryCollection<Geometry> ReadGeometryCollection(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { Int32 geometryCount = reader.ReadInt32(); Geometry.GeometryCollection<Geometry> multi = new Geometry.GeometryCollection<Geometry>(geometryCount); multi.SRID = SRID; List<Geometry> geometries = multi.Geometries; WkbGeometryTypes geometryType; WkbCoordinateSystem cs2; int? SRID2; for (int j = 0; j < geometryCount; j++) { reader.ReadByte(); // Byte order byte geometryType = ReadGeometryType(reader, out cs2, out SRID2); switch (geometryType) { case WkbGeometryTypes.WkbPoint: case WkbGeometryTypes.WkbPointZ: case WkbGeometryTypes.WkbPointM: case WkbGeometryTypes.WkbPointZM: geometries.Add(ReadPoint(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbLineString: case WkbGeometryTypes.WkbLineStringZ: case WkbGeometryTypes.WkbLineStringM: case WkbGeometryTypes.WkbLineStringZM: geometries.Add(ReadLineString(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbPolygon: case WkbGeometryTypes.WkbPolygonZ: case WkbGeometryTypes.WkbPolygonM: case WkbGeometryTypes.WkbPolygonZM: geometries.Add(ReadPolygon(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbMultiPoint: case WkbGeometryTypes.WkbMultiPointZ: case WkbGeometryTypes.WkbMultiPointM: case WkbGeometryTypes.WkbMultiPointZM: geometries.Add(ReadMultiPoint(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbMultiLineString: case WkbGeometryTypes.WkbMultiLineStringZ: case WkbGeometryTypes.WkbMultiLineStringM: case WkbGeometryTypes.WkbMultiLineStringZM: geometries.Add(ReadMultiLineString(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbMultiPolygon: geometries.Add(ReadMultiPolygon(reader, SRID2, cs2)); break; case WkbGeometryTypes.WkbGeometryCollection: case WkbGeometryTypes.WkbGeometryCollectionZ: case WkbGeometryTypes.WkbGeometryCollectionM: case WkbGeometryTypes.WkbGeometryCollectionZM: geometries.Add(ReadGeometryCollection(reader, SRID2, cs2)); break; default: throw new ArgumentException("Geometry type not recognized. GeometryCode: " + geometryType); } } return multi; }
private static WkbGeometryTypes ReadGeometryType(BinaryReader reader, out WkbCoordinateSystem coordinateSystem, out Int32? SRID) { UInt32 type = reader.ReadUInt32(); if ((type & (0x80000000 | 0x40000000)) == (0x80000000 | 0x40000000)) coordinateSystem = WkbCoordinateSystem.XYZM; else if ((type & 0x80000000) == 0x80000000) coordinateSystem = WkbCoordinateSystem.XYZ; else if ((type & 0x40000000) == 0x40000000) coordinateSystem = WkbCoordinateSystem.XYM; else coordinateSystem = WkbCoordinateSystem.XY; if ((type & 0x20000000) != 0) { SRID = reader.ReadInt32(); } else { SRID = null; } UInt32 ordinate = (type & 0xffff) / 1000; switch (ordinate) { case 1: coordinateSystem = WkbCoordinateSystem.XYZ; break; case 2: coordinateSystem = WkbCoordinateSystem.XYM; break; case 3: coordinateSystem = WkbCoordinateSystem.XYZM; break; } return (WkbGeometryTypes)((type & 0xffff) % 1000); }
private static Geometry.MultiPolygon ReadMultiPolygon(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { Int32 geometryCount = reader.ReadInt32(); Geometry.MultiPolygon multi = new Geometry.MultiPolygon(geometryCount); multi.SRID = SRID; List<Geometry.Polygon> polygons = multi.Geometries; WkbGeometryTypes geometryType; WkbCoordinateSystem cs2; int? SRID2; for (int j = 0; j < geometryCount; j++) { reader.ReadByte(); // Byte order byte geometryType = ReadGeometryType(reader, out cs2, out SRID2); if (geometryType != WkbGeometryTypes.WkbPolygon) { throw new ArgumentException("Polygon expected"); } polygons.Add(ReadPolygon(reader, SRID, cs)); } return multi; }
private static Geometry.MultiLineString ReadMultiLineString(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { Int32 geometryCount = reader.ReadInt32(); Geometry.MultiLineString multi = new Geometry.MultiLineString(geometryCount); multi.SRID = SRID; List<Geometry.LineString> lines = multi.Geometries; WkbGeometryTypes geometryType; WkbCoordinateSystem cs2; int? SRID2; for (int j = 0; j < geometryCount; j++) { reader.ReadByte(); // Byte order byte geometryType = ReadGeometryType(reader, out cs2, out SRID2); if (geometryType != WkbGeometryTypes.WkbLineString) { throw new ArgumentException("LineString expected"); } lines.Add(ReadLineString(reader, SRID, cs)); } return multi; }
private static Geometry.Polygon ReadPolygon(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { Int32 ringCount = reader.ReadInt32(); Geometry.Polygon poly = new Geometry.Polygon(ringCount); poly.SRID = SRID; List<Geometry.LineString> holes = poly.Holes; if (ringCount > 0) { poly.Exterior = ReadLineString(reader, SRID, cs); } for (int j = 1; j < ringCount; j++) { holes.Add(ReadLineString(reader, SRID, cs)); } return poly; }
private static Geometry.LineString ReadLineString(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { Int32 pointCount = reader.ReadInt32(); Geometry.LineString ls = new Geometry.LineString(pointCount); ls.SRID = SRID; List<Geometry.Point> points = ls.Points; for (int j = 0; j < pointCount; j++) { points.Add(ReadPoint(reader, SRID, cs)); } return ls; }
private static Geometry.Point ReadPoint(BinaryReader reader, int? SRID, WkbCoordinateSystem cs) { double x = reader.ReadDouble(); double y = reader.ReadDouble(); Geometry.Point pt = new Geometry.Point(x, y); pt.SRID = SRID; switch (cs) { case WkbCoordinateSystem.XY: break; case WkbCoordinateSystem.XYZ: { pt.Z = reader.ReadDouble(); } break; case WkbCoordinateSystem.XYM: { pt.M = reader.ReadDouble(); } break; case WkbCoordinateSystem.XYZM: { pt.Z = reader.ReadDouble(); pt.M = reader.ReadDouble(); } break; default: throw new ArgumentException(String.Format("Coordinate system not supported: {0}", cs)); } return pt; }