/// <inheritdoc cref="IGeometryReader{TSource}.Read(Stream)"/>>
        public IGeometry Read(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            using (var reader = new BinaryReader(stream))
            {
                var header   = GeoPackageBinaryHeader.Read(reader);
                var services = new NtsGeometryServices(_coordinateSequenceFactory,
                                                       _precisionModel, HandleSRID ? header.SrsId : -1);
                // NOTE: GeoPackage handle SRID in header, so no need to read this also in wkb;
                const bool dontHandleSRID = false;
                var        wkbReader      = new WKBReader(services)
                {
                    HandleSRID      = dontHandleSRID,
                    HandleOrdinates = HandleOrdinates,
                    RepairRings     = RepairRings
                };
                var geom = wkbReader.Read(stream);
                if (HandleSRID)
                {
                    geom.SRID = header.SrsId;
                }
                return(geom);
            }
        }
        /// <inheritdoc cref="IGeometryWriter{TSink}.Write(IGeometry, Stream)"/>>
        public void Write(IGeometry geom, Stream stream)
        {
            if (geom == null)
            {
                throw new ArgumentNullException(nameof(geom));
            }
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            using (var writer = new BinaryWriter(stream))
            {
                int byteOrder = (int)ByteOrder;
                int ordinates;
                switch (HandleOrdinates)
                {
                case Ordinates.None:
                    ordinates = 0;
                    break;

                case Ordinates.XY:
                    ordinates = 1;
                    break;

                case Ordinates.XYZ:
                    ordinates = 2;
                    break;

                case Ordinates.XYM:
                    ordinates = 3;
                    break;

                case Ordinates.XYZM:
                    ordinates = 4;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("HandleOrdinates");
                }
                int  isEmpty = geom.IsEmpty ? 1 : 0;
                byte flags   = (byte)(byteOrder + (ordinates << 1) + (isEmpty << 4));
                var  header  = new GeoPackageBinaryHeader
                {
                    Extent = geom.EnvelopeInternal,
                    Flags  = flags,
                    SrsId  = HandleSRID ? geom.SRID : -1
                };
                GeoPackageBinaryHeader.Write(writer, header);

                bool emitZ = (HandleOrdinates & Ordinates.Z) == Ordinates.Z;
                bool emitM = (HandleOrdinates & Ordinates.M) == Ordinates.M;
                // NOTE: GeoPackage handle SRID in header, so no need to store this also in wkb;
                // actually, trying to store srid in wkb resunts in an invalid gpkg blob value...
                const bool dontHandleSRID = false;
                var        wkbWriter      = new WKBWriter(ByteOrder, dontHandleSRID, emitZ, emitM);
                wkbWriter.Write(geom, stream);
            }
        }
예제 #3
0
        public static GeoPackageBinaryHeader Read(BinaryReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var header = new GeoPackageBinaryHeader
            {
                _magic   = reader.ReadBytes(2),
                _version = reader.ReadByte(),
                _flags   = reader.ReadByte()
            };

            bool swap = header.Endianess == 0;

            int srsid = swap
                ? SwapByteOrder(reader.ReadInt32())
                : reader.ReadInt32();

            header._srs_id = srsid;

            var ordinates = header.Ordinates;

            if (ordinates == Ordinates.None)
            {
                header._extent = new Envelope(
                    double.MinValue, double.MaxValue,
                    double.MinValue, double.MaxValue);
                header._zrange = Interval.Create(double.MinValue, double.MaxValue);
                header._mrange = Interval.Create(double.MinValue, double.MaxValue);
                return(header);
            }

            double minx = swap
                ? SwapByteOrder(reader.ReadDouble())
                : reader.ReadDouble();
            double maxx = swap
                ? SwapByteOrder(reader.ReadDouble())
                : reader.ReadDouble();
            double miny = swap
                ? SwapByteOrder(reader.ReadDouble())
                : reader.ReadDouble();
            double maxy = swap
                ? SwapByteOrder(reader.ReadDouble())
                : reader.ReadDouble();

            header._extent = new Envelope(minx, maxx, miny, maxy);

            if ((ordinates & Ordinates.Z) == Ordinates.Z)
            {
                double min = swap
                    ? SwapByteOrder(reader.ReadDouble())
                    : reader.ReadDouble();
                double max = swap
                    ? SwapByteOrder(reader.ReadDouble())
                    : reader.ReadDouble();
                var range = Interval.Create(min, max);
                header._zrange = range;
            }

            if ((ordinates & Ordinates.M) == Ordinates.M)
            {
                double min = swap
                    ? SwapByteOrder(reader.ReadDouble())
                    : reader.ReadDouble();
                double max = swap
                    ? SwapByteOrder(reader.ReadDouble())
                    : reader.ReadDouble();
                var range = Interval.Create(min, max);
                header._mrange = range;
            }

            return(header);
        }
예제 #4
0
        public static void Write(BinaryWriter writer, GeoPackageBinaryHeader header)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (header == null)
            {
                throw new ArgumentNullException(nameof(header));
            }

            writer.Write(header._magic);
            writer.Write(header._version);
            writer.Write(header._flags);

            bool swap = header.Endianess == 0;

            int srsid = swap
                ? SwapByteOrder(header._srs_id)
                : header._srs_id;

            writer.Write(srsid);

            var ordinates = header.Ordinates;

            if (ordinates == Ordinates.None)
            {
                return;
            }

            var    envelope = header._extent;
            double minx     = swap
                ? SwapByteOrder(envelope.MinX)
                : envelope.MinX;
            double maxx = swap
                ? SwapByteOrder(envelope.MaxX)
                : envelope.MaxX;
            double miny = swap
                ? SwapByteOrder(envelope.MinY)
                : envelope.MinY;
            double maxy = swap
                ? SwapByteOrder(envelope.MaxY)
                : envelope.MaxY;

            writer.Write(minx);
            writer.Write(maxx);
            writer.Write(miny);
            writer.Write(maxy);

            if ((ordinates & Ordinates.Z) == Ordinates.Z)
            {
                var    range = header._zrange;
                double min   = swap
                    ? SwapByteOrder(range.Min)
                    : range.Min;
                writer.Write(min);
                double max = swap
                    ? SwapByteOrder(range.Max)
                    : range.Max;
                writer.Write(max);
            }

            if ((ordinates & Ordinates.M) == Ordinates.M)
            {
                var    range = header._mrange;
                double min   = swap
                    ? SwapByteOrder(range.Min)
                    : range.Min;
                writer.Write(min);
                double max = swap
                    ? SwapByteOrder(range.Max)
                    : range.Max;
                writer.Write(max);
            }
        }