// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SharpMap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// SOURCECODE IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
/*
* Copyright (C) 2002 Urban Science Applications, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.IO;
namespace SharpMap.Converters.WellKnownBinary
{
///
/// Converts a instance to a Well-known Binary string representation.
///
///
/// The Well-known Binary Representation for (WKBGeometry) provides a portable
/// representation of a value as a contiguous stream of bytes. It permits
/// values to be exchanged between an ODBC client and an SQL database in binary form.
/// The Well-known Binary Representation for is obtained by serializing a
/// instance as a sequence of numeric types drawn from the set {Unsigned Integer, Double} and
/// then serializing each numeric type as a sequence of bytes using one of two well defined,
/// standard, binary representations for numeric types (NDR, XDR). The specific binary encoding
/// (NDR or XDR) used for a geometry byte stream is described by a one byte tag that precedes
/// the serialized bytes. The only difference between the two encodings of geometry is one of
/// byte order, the XDR encoding is Big Endian, the NDR encoding is Little Endian.
///
public class GeometryToWKB
{
//private const byte WKBByteOrder = 0;
///
/// Writes a geometry to a byte array using little endian byte encoding
///
/// The geometry to write
/// WKB representation of the geometry
public static byte[] Write(IGeometry geometry)
{
return Write(geometry, WkbByteOrder.Ndr);
}
///
/// Writes a geometry to a byte array using the specified encoding.
///
/// The geometry to write
/// Byte order
/// WKB representation of the geometry
public static byte[] Write(IGeometry geometry, WkbByteOrder wkbByteOrder)
{
byte[] result = null;
switch (wkbByteOrder)
{
case WkbByteOrder.Ndr:
result = new WKBWriter(ByteOrder.LittleEndian).Write(geometry);
break;
case WkbByteOrder.Xdr:
result = new WKBWriter(ByteOrder.BigEndian).Write(geometry);
break;
}
return result;
// MemoryStream ms = new MemoryStream();
// BinaryWriter bw = new BinaryWriter(ms);
//
// //Write the byteorder format.
// bw.Write((byte)wkbByteOrder);
//
// //Write the type of this geometry
// WriteType(g, bw, wkbByteOrder);
//
// //Write the geometry
// WriteGeometry(g, bw, wkbByteOrder);
//
// return ms.ToArray();
}
//
// #region Methods
// ///
// /// Writes the type number for this geometry.
// ///
// /// The geometry to determine the type of.
// /// Binary Writer
// /// Byte order
// private static void WriteType(Geometry geometry, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Determine the type of the geometry.
// switch (geometry.GetType().FullName)
// {
// //Points are type 1.
// case "SharpMap.Geometries.Point":
// WriteUInt32((uint)WKBGeometryType.wkbPoint, bWriter, byteorder);
// break;
// //Linestrings are type 2.
// case "SharpMap.Geometries.LineString":
// WriteUInt32((uint)WKBGeometryType.wkbLineString, bWriter, byteorder);
// break;
// //Polygons are type 3.
// case "SharpMap.Geometries.Polygon":
// WriteUInt32((uint)WKBGeometryType.wkbPolygon, bWriter, byteorder);
// break;
// //Mulitpoints are type 4.
// case "SharpMap.Geometries.MultiPoint":
// WriteUInt32((uint)WKBGeometryType.wkbMultiPoint, bWriter, byteorder);
// break;
// //Multilinestrings are type 5.
// case "SharpMap.Geometries.MultiLineString":
// WriteUInt32((uint)WKBGeometryType.wkbMultiLineString, bWriter, byteorder);
// break;
// //Multipolygons are type 6.
// case "SharpMap.Geometries.MultiPolygon":
// WriteUInt32((uint)WKBGeometryType.wkbMultiPolygon, bWriter, byteorder);
// break;
// //Geometrycollections are type 7.
// case "SharpMap.Geometries.GeometryCollection":
// WriteUInt32((uint)WKBGeometryType.wkbGeometryCollection, bWriter, byteorder);
// break;
// //If the type is not of the above 7 throw an exception.
// default:
// throw new ArgumentException("Invalid Geometry Type");
// }
// }
//
// ///
// /// Writes the geometry to the binary writer.
// ///
// /// The geometry to be written.
// ///
// /// Byte order
// private static void WriteGeometry(Geometry geometry, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// switch (geometry.GetType().FullName)
// {
// //Write the point.
// case "SharpMap.Geometries.Point":
// WritePoint((Point)geometry, bWriter, byteorder);
// break;
// case "SharpMap.Geometries.LineString":
// LineString ls = (LineString)geometry;
// WriteLineString(ls, bWriter, byteorder);
// break;
// case "SharpMap.Geometries.Polygon":
// WritePolygon((Polygon)geometry, bWriter, byteorder);
// break;
// //Write the Multipoint.
// case "SharpMap.Geometries.MultiPoint":
// WriteMultiPoint((MultiPoint)geometry, bWriter,byteorder);
// break;
// //Write the Multilinestring.
// case "SharpMap.Geometries.MultiLineString":
// WriteMultiLineString((MultiLineString)geometry, bWriter,byteorder);
// break;
// //Write the Multipolygon.
// case "SharpMap.Geometries.MultiPolygon":
// WriteMultiPolygon((MultiPolygon)geometry, bWriter,byteorder);
// break;
// //Write the Geometrycollection.
// case "SharpMap.Geometries.GeometryCollection":
// WriteGeometryCollection((GeometryCollection)geometry, bWriter,byteorder);
// break;
// //If the type is not of the above 7 throw an exception.
// default:
// throw new ArgumentException("Invalid Geometry Type");
// }
// }
//
// ///
// /// Writes a point.
// ///
// /// The point to be written.
// /// Stream to write to.
// /// Byte order
// private static void WritePoint(Point point, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Write the x coordinate.
// WriteDouble(point.X, bWriter, byteorder);
// //Write the y coordinate.
// WriteDouble(point.Y, bWriter, byteorder);
// }
//
//
//
// ///
// /// Writes a linestring.
// ///
// /// The linestring to be written.
// /// Stream to write to.
// /// Byte order
// private static void WriteLineString(LineString ls, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Write the number of points in this linestring.
// WriteUInt32((uint)ls.Vertices.Count,bWriter,byteorder);
//
// //Loop on each vertices.
// foreach (Point p in ls.Vertices)
// WritePoint(p, bWriter, byteorder);
// }
//
//
// ///
// /// Writes a polygon.
// ///
// /// The polygon to be written.
// /// Stream to write to.
// /// Byte order
// private static void WritePolygon(Polygon poly, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Get the number of rings in this polygon.
// int numRings = poly.InteriorRings.Count + 1;
//
// //Write the number of rings to the stream (add one for the shell)
// WriteUInt32((uint)numRings, bWriter, byteorder);
//
// //Write the exterior of this polygon.
// WriteLineString((LineString)poly.ExteriorRing, bWriter, byteorder);
//
// //Loop on the number of rings - 1 because we already wrote the shell.
// foreach (LinearRing lr in poly.InteriorRings)
// //Write the (lineString)LinearRing.
// WriteLineString((LineString)lr, bWriter, byteorder);
// }
//
// ///
// /// Writes a multipoint.
// ///
// /// The multipoint to be written.
// /// Stream to write to.
// /// Byte order
// private static void WriteMultiPoint(MultiPoint mp, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Write the number of points.
// WriteUInt32((uint)mp.Points.Count, bWriter, byteorder);
//
// //Loop on the number of points.
// foreach (Point p in mp.Points)
// {
// //Write Points Header
// bWriter.Write((byte)byteorder);
// WriteUInt32((uint)WKBGeometryType.wkbPoint, bWriter, byteorder);
// //Write each point.
// WritePoint((Point)p, bWriter, byteorder);
// }
// }
//
// ///
// /// Writes a multilinestring.
// ///
// /// The multilinestring to be written.
// /// Stream to write to.
// /// Byte order
// private static void WriteMultiLineString(MultiLineString mls, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Write the number of linestrings.
// WriteUInt32((uint)mls.LineStrings.Count, bWriter, byteorder);
//
// //Loop on the number of linestrings.
// foreach (LineString ls in mls.LineStrings)
// {
// //Write LineString Header
// bWriter.Write((byte)byteorder);
// WriteUInt32((uint)WKBGeometryType.wkbLineString, bWriter, byteorder);
// //Write each linestring.
// WriteLineString(ls, bWriter, byteorder);
// }
// }
//
// ///
// /// Writes a multipolygon.
// ///
// /// The mulitpolygon to be written.
// /// Stream to write to.
// /// Byte order
// private static void WriteMultiPolygon(MultiPolygon mp, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Write the number of polygons.
// WriteUInt32((uint)mp.Polygons.Count, bWriter, byteorder);
//
// //Loop on the number of polygons.
// foreach (Polygon poly in mp.Polygons)
// {
// //Write polygon header
// bWriter.Write((byte)byteorder);
// WriteUInt32((uint)WKBGeometryType.wkbPolygon, bWriter, byteorder);
// //Write each polygon.
// WritePolygon(poly, bWriter, byteorder);
// }
// }
//
//
// ///
// /// Writes a geometrycollection.
// ///
// /// The geometrycollection to be written.
// /// Stream to write to.
// /// Byte order
// private static void WriteGeometryCollection(GeometryCollection gc, BinaryWriter bWriter, WkbByteOrder byteorder)
// {
// //Get the number of geometries in this geometrycollection.
// int numGeometries = gc.NumGeometries;
//
// //Write the number of geometries.
// WriteUInt32((uint)numGeometries, bWriter, byteorder);
//
// //Loop on the number of geometries.
// for (int i = 0; i < numGeometries; i++)
// {
// //Write the byte-order format of the following geometry.
// bWriter.Write((byte)byteorder);
// //Write the type of each geometry.
// WriteType(gc[i], bWriter, byteorder);
// //Write each geometry.
// WriteGeometry(gc[i], bWriter, byteorder);
// }
// }
// #endregion
//
// ///
// /// Writes an unsigned integer to the binarywriter using the specified encoding
// ///
// /// Value to write
// /// Binary Writer
// /// byteorder
// private static void WriteUInt32(UInt32 value, BinaryWriter writer, WkbByteOrder byteOrder)
// {
// if (byteOrder == WkbByteOrder.Xdr)
// {
// byte[] bytes = BitConverter.GetBytes(value);
// Array.Reverse(bytes);
// writer.Write(BitConverter.ToUInt32(bytes, 0));
// }
// else
// writer.Write(value);
// }
//
// ///
// /// Writes a double to the binarywriter using the specified encoding
// ///
// /// Value to write
// /// Binary Writer
// /// byteorder
// private static void WriteDouble(double value, BinaryWriter writer, WkbByteOrder byteOrder)
// {
// if (byteOrder == WkbByteOrder.Xdr)
// {
// byte[] bytes = BitConverter.GetBytes(value);
// Array.Reverse(bytes);
// writer.Write(BitConverter.ToDouble(bytes, 0));
// }
// else
// writer.Write(value);
// }
}
}