private Polygon ReadWkbPolygon(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the Number of rings in this Polygon. int numRings = (int)readUInt32(reader, byteOrder); return(new Polygon(CoordinateCollectionEnumerator(numRings + 1, reader, byteOrder, type, null), spatialReference)); }
private MapPoint ReadCoordinate(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { double X = readDouble(reader, byteOrder); double Y = readDouble(reader, byteOrder); double Z = ((uint)type > 1000 && (uint)type < 2000 || (int)type > 3000) ? readDouble(reader, byteOrder) : double.NaN; double M = ((uint)type > 2000) ? readDouble(reader, byteOrder) : double.NaN; bool hasZ = ((uint)type > 1000 && (uint)type < 2000 || (int)type > 3000); if ((uint)type > 2000) // HasM { if (hasZ) { return(Esri.ArcGISRuntime.Geometry.MapPoint.CreateWithM(X, Y, Z, M, spatialReference)); } else { return(Esri.ArcGISRuntime.Geometry.MapPoint.CreateWithM(X, Y, M, spatialReference)); } } if (hasZ) { return(new Esri.ArcGISRuntime.Geometry.MapPoint(X, Y, Z, spatialReference)); } else { return(new Esri.ArcGISRuntime.Geometry.MapPoint(X, Y, spatialReference)); } }
private IPolygon ReadPolygon(BinaryReader reader, WkbGeometryType geometryType, Ordinates ordinates) { if (geometryType == WkbGeometryType.Polygon) { var rings = ReadSingleExteriorRingPolygon(reader, ordinates).Cast <IGeometry>(); return(CreatePolycurve <IPolygon>(rings, ordinates)); } if (geometryType == WkbGeometryType.MultiPolygon) { int polygonCount = checked ((int)reader.ReadUInt32()); List <IGeometry> allRings = new List <IGeometry>(); for (int i = 0; i < polygonCount; i++) { ReadWkbType(reader, false, out geometryType, out ordinates); allRings.AddRange(ReadSingleExteriorRingPolygon(reader, ordinates)); } return(CreatePolycurve <IPolygon>(allRings, ordinates)); } throw new NotSupportedException( $"Cannot read {geometryType} as polygon."); }
private static void CheckType(WkbGeometryType expected, uint actual) { if (actual != (uint)expected) { throw new ArgumentException($"Invalid wkb geometry type, expected {expected}, actual {actual}"); } }
/// <summary> /// Reads Geometry from the reader. /// </summary> /// <param name="reader">The reader used to read data from input stream.</param> /// <returns>Geometry read from the input.</returns> private static Geometry ReadGeometry(BinaryReader reader) { WkbGeometryType geometryType = (WkbGeometryType)reader.ReadUInt32(); bool is3D, isMeasured; WkbGeometryType basicType; WkbReader.GetGeometryTypeDetails(geometryType, out basicType, out is3D, out isMeasured); switch (basicType) { case WkbGeometryType.Point: return(WkbReader.ReadPoint(reader, is3D, isMeasured)); case WkbGeometryType.LineString: return(WkbReader.ReadLineString(reader, is3D, isMeasured)); case WkbGeometryType.Polygon: return(WkbReader.ReadPolygon(reader, is3D, isMeasured)); case WkbGeometryType.MultiPoint: return(WkbReader.ReadMultiPoint(reader, is3D, isMeasured)); case WkbGeometryType.MultiLineString: return(WkbReader.ReadMultiLineString(reader, is3D, isMeasured)); case WkbGeometryType.MultiPolygon: return(WkbReader.ReadMultiPolygon(reader, is3D, isMeasured)); case WkbGeometryType.GeometryCollection: return(WkbReader.ReadGeometryCollection(reader, is3D, isMeasured)); default: throw new WkbFormatException("Unknown geometry type."); } }
/// <summary> /// Reads a LineString or multiple LineString geometries using the specified reader. /// </summary> /// <typeparam name="TMultipoint"></typeparam> /// <typeparam name="TLinestring"></typeparam> /// <typeparam name="TPoint"></typeparam> /// <param name="reader"></param> /// <param name="geometryType"></param> /// <param name="ordinates"></param> /// <param name="geometryBuilder"></param> /// <returns></returns> protected static IEnumerable <TLinestring> ReadLinestrings <TMultipoint, TLinestring, TPoint>( [NotNull] BinaryReader reader, WkbGeometryType geometryType, Ordinates ordinates, [NotNull] GeometryBuilderBase <TMultipoint, TLinestring, TPoint> geometryBuilder) { IEnumerable <TLinestring> linestrings; if (geometryType == WkbGeometryType.MultiLineString || geometryType == WkbGeometryType.Polygon || geometryType == WkbGeometryType.MultiPolygon) { linestrings = ReadLinestrings(reader, ordinates, geometryBuilder); } else if (geometryType == WkbGeometryType.LineString) { TLinestring linestring = ReadLinestringCore(reader, ordinates, geometryBuilder); linestrings = new[] { linestring }; } else { throw new NotSupportedException( $"Cannot read {geometryType} as lineString or multiple lineStrings."); } return(linestrings); }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> protected virtual IGeometry Read(BinaryReader reader) { WkbGeometryType geometryType = (WkbGeometryType)reader.ReadInt32(); switch (geometryType) { case WkbGeometryType.Point: return(ReadPoint(reader)); case WkbGeometryType.LineString: return(ReadLineString(reader)); case WkbGeometryType.Polygon: return(ReadPolygon(reader)); case WkbGeometryType.MultiPoint: return(ReadMultiPoint(reader)); case WkbGeometryType.MultiLineString: return(ReadMultiLineString(reader)); case WkbGeometryType.MultiPolygon: return(ReadMultiPolygon(reader)); case WkbGeometryType.GeometryCollection: return(ReadGeometryCollection(reader)); default: throw new ArgumentException("Geometry type not recognized. GeometryCode: " + geometryType); } }
protected void WriteWkbType(WkbGeometryType geometryType, Ordinates ordinates) { // Byte order: NDR / little endian Writer.Write(true); uint type = (uint)ordinates + (uint)geometryType; Writer.Write(type); }
private byte[] WriteEmptyPolycuve([NotNull] MemoryStream memoryStream, WkbGeometryType geometryType, Ordinates ordinates) { WriteWkbType(WkbGeometryType.Polygon, ordinates); Writer.Write(0); return(memoryStream.ToArray()); }
private Polygon ReadWkbPolygon(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the Number of rings in this Polygon. int numRings = (int)readUInt32(reader, byteOrder); List <IEnumerable <MapPoint> > rings = new List <IEnumerable <MapPoint> >(); foreach (var ring in CoordinateCollectionEnumerator(numRings, reader, byteOrder, type, null)) { rings.Add(new List <MapPoint>(ring)); } return(new Polygon(rings, spatialReference)); }
private static IPolyline ReadPolyline(BinaryReader reader, WkbGeometryType geometryType, Ordinates ordinates) { var geometryBuilder = new WksPointListBuilder(); IEnumerable <WKSPointZ[]> linestrings = ReadLinestrings(reader, geometryType, ordinates, geometryBuilder); IEnumerable <IPath> paths = ToPaths(linestrings, geometryType, ordinates, geometryBuilder); return(CreatePolycurve <IPolyline>(paths, ordinates)); }
/// <summary> /// Adjust WkbGeometryType according to the Geometry object dimensions. /// </summary> /// <param name="geometry">The geometry object.</param> /// <param name="baseType">WkbGeometryType for the 2D, non-measured version of the geometry object.</param> /// <returns>The WkbGeometryType of the geometry object.</returns> private static WkbGeometryType AdjustGeometryType(IGeometry geometry, WkbGeometryType baseType) { WkbGeometryType result = baseType; if (geometry.Is3D) { result += 1000; } if (geometry.IsMeasured) { result += 2000; } return(result); }
protected static void ReadWkbType([NotNull] BinaryReader reader, bool skipEndianness, out WkbGeometryType geometryType, out Ordinates ordinates) { if (!skipEndianness) { reader.ReadBoolean(); } int type = checked ((int)reader.ReadUInt32()); geometryType = (WkbGeometryType)(type % 1000); ordinates = GetOrdinates(type); }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> protected virtual IGeometry ReadGeometryCollection(BinaryReader reader) { int numGeometries = reader.ReadInt32(); IGeometry[] geometries = new Geometry[numGeometries]; for (int i = 0; i < numGeometries; i++) { ReadByteOrder(reader); WkbGeometryType geometryType = (WkbGeometryType)reader.ReadInt32(); switch (geometryType) { case WkbGeometryType.Point: geometries[i] = ReadPoint(reader); break; case WkbGeometryType.LineString: geometries[i] = ReadLineString(reader); break; case WkbGeometryType.Polygon: geometries[i] = ReadPolygon(reader); break; case WkbGeometryType.MultiPoint: geometries[i] = ReadMultiPoint(reader); break; case WkbGeometryType.MultiLineString: geometries[i] = ReadMultiLineString(reader); break; case WkbGeometryType.MultiPolygon: geometries[i] = ReadMultiPolygon(reader); break; case WkbGeometryType.GeometryCollection: geometries[i] = ReadGeometryCollection(reader); break; default: throw new ArgumentException("Should never reach here!"); } } return(Factory.CreateGeometryCollection(geometries)); }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> protected virtual IGeometry ReadMultiPolygon(BinaryReader reader) { int numGeometries = reader.ReadInt32(); Polygon[] polygons = new Polygon[numGeometries]; for (int i = 0; i < numGeometries; i++) { ReadByteOrder(reader); WkbGeometryType geometryType = (WkbGeometryType)reader.ReadInt32(); if (geometryType != WkbGeometryType.Polygon) { throw new ArgumentException("Polygon feature expected"); } polygons[i] = ReadPolygon(reader) as Polygon; } return(Factory.CreateMultiPolygon(polygons)); }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> protected virtual IGeometry ReadMultiLineString(BinaryReader reader) { int numGeometries = reader.ReadInt32(); LineString[] strings = new LineString[numGeometries]; for (int i = 0; i < numGeometries; i++) { ReadByteOrder(reader); WkbGeometryType geometryType = (WkbGeometryType)reader.ReadInt32(); if (geometryType != WkbGeometryType.LineString) { throw new ArgumentException("LineString feature expected"); } strings[i] = ReadLineString(reader) as LineString; } return(Factory.CreateMultiLineString(strings)); }
private static IEnumerable <IPath> ToPaths(IEnumerable <WKSPointZ[]> wksLinestrings, WkbGeometryType geometryType, Ordinates ordinates, WksPointListBuilder geometryBuilder) { IPath pathTemplate = CreateEmptyPath(ordinates); foreach (WKSPointZ[] wksPoints in wksLinestrings) { IPath resultPath = geometryType == WkbGeometryType.MultiLineString ? GeometryFactory.Clone(pathTemplate) : pathTemplate; GeometryUtils.SetWKSPointZs(resultPath, wksPoints); yield return(resultPath); } }
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(); WkbGeometryType type = (WkbGeometryType)ReadInt32(data); switch (type) { case WkbGeometryType.Point: ReadPoint(data, results); return; case WkbGeometryType.LineString: ReadLineString(data, results); return; case WkbGeometryType.Polygon: ReadPolygon(data, results); break; case WkbGeometryType.MultiPoint: ReadMultiPoint(data, results); break; case WkbGeometryType.MultiLineString: ReadMultiLineString(data, results); break; case WkbGeometryType.MultiPolygon: ReadMultiPolygon(data, results); break; case WkbGeometryType.GeometryCollection: ReadGeometryCollection(data, results); break; } } }
private void WriteGeometryType(IOgcGeometry geometry, WkbGeometryType baseType, WkbBinaryWriter writer) { if (geometry.IsEmpty) { writer.Write((uint)baseType); } else { var typeCode = (uint)baseType; if (geometry.Is3D && _settings.MaxDimesions > 2) { typeCode += 1000; } if (geometry.IsMeasured && _settings.MaxDimesions > 3) { typeCode += 2000; } writer.Write(typeCode); } }
/// <summary> /// Reads only a single geometry into a feature. This may be a multi-part geometry. /// </summary> /// <param name="data"></param> /// <param name="results"></param> public static void ReadFeature(Stream data, FeatureSetPack results) { _endian = (ByteOrder)data.ReadByte(); WkbGeometryType type = (WkbGeometryType)ReadInt32(data); switch (type) { case WkbGeometryType.Point: ReadPoint(data, results); return; case WkbGeometryType.LineString: ReadLineString(data, results); return; case WkbGeometryType.Polygon: ReadPolygon(data, results); break; case WkbGeometryType.MultiPoint: ReadMultiPoint(data, results); break; case WkbGeometryType.MultiLineString: ReadMultiLineString(data, results); break; case WkbGeometryType.MultiPolygon: ReadMultiPolygon(data, results); break; case WkbGeometryType.GeometryCollection: ReadGeometryCollection(data, results); break; } }
private void WriteGeometryType(IGeometry geometry, WkbGeometryType baseType, WkbBinaryWriter writer) { if (geometry.IsEmpty) { writer.Write((uint)baseType); } else { var typeCode = (uint)baseType; if (geometry.Is3D && _settings.MaxDimesions > 2) typeCode += 1000; if (geometry.IsMeasured && _settings.MaxDimesions > 3) typeCode += 2000; writer.Write(typeCode); } }
/// <summary> /// Adjust WkbGeometryType according to the Geometry object dimensions. /// </summary> /// <param name="geometry">The geometry object.</param> /// <param name="baseType">WkbGeometryType for the 2D, non-measured version of the geometry object.</param> /// <returns>The WkbGeometryType of the geometry object.</returns> private static WkbGeometryType AdjustGeometryType(IGeometry geometry, WkbGeometryType baseType) { WkbGeometryType result = baseType; if (geometry.Is3D) { result += 1000; } if (geometry.IsMeasured) { result += 2000; } return result; }
/// <summary> /// Gets details form the WkbGeometryType value. /// </summary> /// <param name="type">The value to be examined.</param> /// <param name="basicType">Outputs type striped of dimension information.</param> /// <param name="is3D">Outputs bool value indicating whether type represents 3D geometry.</param> /// <param name="isMeasured">Outputs bool value indicating whether type represents measured geometry.</param> private static void GetGeometryTypeDetails(WkbGeometryType type, out WkbGeometryType basicType, out bool is3D, out bool isMeasured) { is3D = ((int)type > 1000 && (int)type < 2000) || (int)type > 3000; isMeasured = (int)type > 2000; basicType = (WkbGeometryType)((int)type % 1000); }
private Geometry Read(BinaryReader reader, SpatialReference spatialReference) { // Get the first byte in the array. This specifies if the WKB is in // XDR (big-endian) format of NDR (little-endian) format. byte byteOrder = reader.ReadByte(); if (!Enum.IsDefined(typeof(WkbByteOrder), byteOrder)) { throw new ArgumentException("Byte order not recognized"); } // Get the type of this geometry. uint type = (uint)readUInt32(reader, (WkbByteOrder)byteOrder); if (!Enum.IsDefined(typeof(WkbGeometryType), type)) { throw new ArgumentException("Geometry type not recognized"); } WkbGeometryType wkbtype = (WkbGeometryType)type; switch ((WkbGeometryType)type) { //XY / YX formats case WkbGeometryType.wkbPoint: case WkbGeometryType.wkbPointZ: case WkbGeometryType.wkbPointM: case WkbGeometryType.wkbPointZM: return(ReadWkbPoint(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbLineString: case WkbGeometryType.wkbLineStringZ: case WkbGeometryType.wkbLineStringM: case WkbGeometryType.wkbLineStringZM: return(ReadWkbLineString(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbPolygon: case WkbGeometryType.wkbPolygonZ: case WkbGeometryType.wkbPolygonM: case WkbGeometryType.wkbPolygonZM: return(ReadWkbPolygon(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbMultiPoint: case WkbGeometryType.wkbMultiPointZ: case WkbGeometryType.wkbMultiPointM: case WkbGeometryType.wkbMultiPointZM: return(ReadWkbMultiPoint(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbMultiLineString: case WkbGeometryType.wkbMultiLineStringZ: case WkbGeometryType.wkbMultiLineStringM: case WkbGeometryType.wkbMultiLineStringZM: return(ReadWkbMultiLineString(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbMultiPolygon: case WkbGeometryType.wkbMultiPolygonZ: case WkbGeometryType.wkbMultiPolygonM: case WkbGeometryType.wkbMultiPolygonZM: return(ReadWkbMultiPolygon(reader, (WkbByteOrder)byteOrder, wkbtype, spatialReference)); case WkbGeometryType.wkbGeometryCollection: case WkbGeometryType.wkbGeometryCollectionZ: case WkbGeometryType.wkbGeometryCollectionM: case WkbGeometryType.wkbGeometryCollectionZM: throw new NotSupportedException("GeometryCollection"); //return ReadWkbGeometryCollection(reader, (WkbByteOrder)byteOrder, wkbtype); default: throw new NotSupportedException("Geometry type '" + type.ToString() + "' not supported"); } }
private Polygon ReadWkbMultiPolygon(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the number of Polygons. int numPolygons = (int)readUInt32(reader, byteOrder); // Create a new array for the Polygons. List <IEnumerable <MapPoint> > rings = new List <IEnumerable <MapPoint> >(); // Loop on the number of polygons. for (int i = 0; i < numPolygons; i++) { // read polygon header reader.BaseStream.Seek(5, SeekOrigin.Current); //reader.ReadByte(); //readUInt32(reader, byteOrder); // TODO: Validate type int numRings = (int)readUInt32(reader, byteOrder); rings.AddRange(CoordinateCollectionEnumerator(numRings + 1, reader, byteOrder, type, spatialReference)); } //Create and return the MultiPolygon. return(new Polygon(rings)); }
private Polyline ReadWkbMultiLineString(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the number of linestrings in this multilinestring. int numLineStrings = (int)readUInt32(reader, byteOrder); List <IEnumerable <MapPoint> > mline = new List <IEnumerable <MapPoint> >(numLineStrings); // Create a new array for the linestrings . // Loop on the number of linestrings. for (int i = 0; i < numLineStrings; i++) { // ReadGeometry linestring header reader.BaseStream.Seek(5, SeekOrigin.Current); //reader.ReadByte(); //readUInt32(reader, byteOrder); // Create the next linestring and add it to the array. mline.Add(ReadCoordinates(reader, byteOrder, type, null)); } // Create and return the MultiLineString. return(new Polyline(mline, spatialReference)); }
private Multipoint ReadWkbMultiPoint(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the number of points in this multipoint. int numPoints = (int)readUInt32(reader, byteOrder); // Create a new array for the points. List <MapPoint> points = new List <MapPoint>(numPoints); // Loop on the number of points. for (int i = 0; i < numPoints; i++) { // ReadGeometry point header reader.BaseStream.Seek(5, SeekOrigin.Current); //reader.ReadByte(); //readUInt32(reader, byteOrder); // TODO: Validate type // Create the next point and add it to the point array. points.Add(ReadWkbPoint(reader, byteOrder, type, null)); } return(new Multipoint(points, spatialReference)); }
IEnumerable <IEnumerable <MapPoint> > CoordinateCollectionEnumerator(int count, BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { for (int i = 0; i < count; i++) { yield return(ReadCoordinates(reader, byteOrder, type, spatialReference)); } }
/// <summary> /// Attempts to read in an entry to the specified feature type. If the feature type does not match /// the geometry type, this will return null. (A Point geometry will be accepted by MultiPoint /// feature type, but not the other way arround. Either way, this will advance the reader /// through the shape feature. Using the Unspecified will always return the shape it reads, /// or null in the case of mixed feature collections which are not supported. /// </summary> /// <param name="data"></param> /// <param name="featureType"></param> /// <returns></returns> public static Shape ReadShape(Stream data, FeatureType featureType) { _endian = (ByteOrder)data.ReadByte(); WkbGeometryType type = (WkbGeometryType)ReadInt32(data); Shape result; switch (type) { case WkbGeometryType.Point: result = ReadPoint(data); if (featureType == FeatureType.Point || featureType == FeatureType.MultiPoint || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.LineString: result = ReadLineString(data); if (featureType == FeatureType.Line || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.Polygon: result = ReadPolygon(data); if (featureType == FeatureType.Polygon || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.MultiPoint: result = ReadMultiPoint(data); if (featureType == FeatureType.MultiPoint || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.MultiLineString: result = ReadMultiLineString(data); if (featureType == FeatureType.Line || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.MultiPolygon: result = ReadMultiPolygon(data); if (featureType == FeatureType.Polygon || featureType == FeatureType.Unspecified) { return(result); } return(null); case WkbGeometryType.GeometryCollection: throw new ArgumentException("Mixed shape type collections are not supported by this method."); } return(null); }
private Polyline ReadWkbLineString(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { return(new Polyline(ReadCoordinates(reader, byteOrder, type, null), spatialReference)); }
private IEnumerable <MapPoint> ReadCoordinates(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Get the number of points in this linestring. int numPoints = (int)readUInt32(reader, byteOrder); // Loop on the number of points in the ring. for (int i = 0; i < numPoints; i++) { yield return(ReadCoordinate(reader, byteOrder, type, null)); } }
private MapPoint ReadWkbPoint(BinaryReader reader, WkbByteOrder byteOrder, WkbGeometryType type, SpatialReference spatialReference) { // Create and return the point. return(ReadCoordinate(reader, byteOrder, type, spatialReference)); }