Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RawCoordinateSequenceFactory"/> class.
        /// </summary>
        /// <param name="ordinateGroups">
        /// A sequence of zero or more <see cref="Ordinates"/> flags representing ordinate values
        /// that should be allocated together.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when <paramref name="ordinateGroups"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown when a given flag appears in more than one element of
        /// <paramref name="ordinateGroups"/>.
        /// </exception>
        /// <remarks>
        /// Any flags not represented in <paramref name="ordinateGroups"/>, and any spatial or
        /// measure dimensions beyond the 16th, will be allocated together, SoA-style.
        /// <para/>
        /// Elements without any bits set will be silently ignored.
        /// </remarks>
        public RawCoordinateSequenceFactory(IEnumerable <Ordinates> ordinateGroups)
        {
            if (ordinateGroups is null)
            {
                throw new ArgumentNullException(nameof(ordinateGroups));
            }

            var seenOrdinates      = Ordinates.None;
            var ordinateGroupsList = new List <Ordinates>();

            foreach (var ordinateGroup in ordinateGroups)
            {
                if ((ordinateGroup & seenOrdinates) != Ordinates.None)
                {
                    throw new ArgumentException("Each ordinate may show up in at most one group.", nameof(ordinateGroups));
                }

                seenOrdinates |= ordinateGroup;

                if (OrdinatesUtility.OrdinatesToDimension(ordinateGroup) < 2)
                {
                    // it would have been equally correct to omit this
                    continue;
                }

                _ordinatesInGroups |= ordinateGroup;
                ordinateGroupsList.Add(ordinateGroup);
            }

            _ordinateGroups = ordinateGroupsList.ToArray();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Writes a binary encoded PostGIS of the given <paramref name="geometry"/> to to an array of bytes.
        /// </summary>
        /// <param name="geometry">The geometry</param>
        /// <param name="ordinates">The ordinates of each geometry's coordinate. <see cref="Ordinates.XY"/> area always written.</param>
        /// <returns>An array of bytes.</returns>
        private byte[] Write(IGeometry geometry, Ordinates ordinates)
        {
            var coordinateSpace = 8 * OrdinatesUtility.OrdinatesToDimension(ordinates);
            var bytes           = GetBytes(geometry, coordinateSpace);

            Write(geometry, ordinates, new MemoryStream(bytes));

            return(bytes);
        }
        /// <summary>
        /// Writes out a given <see cref="Geometry"/> to a byte array.
        /// </summary>
        /// <param name="geometry">The <see cref="Geometry"/> to write.</param>
        /// <returns>The byte array.</returns>
        public byte[] Write(Geometry geometry)
        {
            var maxCoords       = HandleOrdinates == Ordinates.None ? Ordinates.XYZM : HandleOrdinates;
            int coordinateSpace = 8 * OrdinatesUtility.OrdinatesToDimension(maxCoords & CheckOrdinates(geometry));

            byte[] bytes = GetBytes(geometry, coordinateSpace);
            Write(geometry, new MemoryStream(bytes));

            return(bytes);
        }
        /// <summary>
        /// Creates an instance of this class
        /// </summary>
        /// <param name="coordinates">The coordinates</param>
        /// <param name="ordinates"></param>
        public DotSpatialAffineCoordinateSequence(IReadOnlyCollection <Coordinate> coordinates, Ordinates ordinates)
            : base(coordinates?.Count ?? 0, OrdinatesUtility.OrdinatesToDimension(ordinates & Ordinates.XYZM), OrdinatesUtility.OrdinatesToMeasures(ordinates & Ordinates.XYZM))
        {
            coordinates = coordinates ?? Array.Empty <Coordinate>();

            _xy = new double[2 * coordinates.Count];
            if (HasZ)
            {
                _z = new double[coordinates.Count];
            }

            if (HasM)
            {
                _m = new double[coordinates.Count];
            }

            var xy = MemoryMarshal.Cast <double, XYStruct>(_xy);

            using (var coordinatesEnumerator = coordinates.GetEnumerator())
            {
                for (int i = 0; i < xy.Length; i++)
                {
                    if (!coordinatesEnumerator.MoveNext())
                    {
                        ThrowForInconsistentCount();
                    }

                    var coordinate = coordinatesEnumerator.Current;

                    xy[i].X = coordinate.X;
                    xy[i].Y = coordinate.Y;
                    if (_z != null)
                    {
                        _z[i] = coordinate.Z;
                    }

                    if (_m != null)
                    {
                        _m[i] = coordinate.M;
                    }
                }

                if (coordinatesEnumerator.MoveNext())
                {
                    ThrowForInconsistentCount();
                }
            }

            void ThrowForInconsistentCount() => throw new ArgumentException("IReadOnlyCollection<T>.Count is inconsistent with IEnumerable<T> implementation.", nameof(coordinates));
        }
        /// <summary>
        /// Constructs a sequence of a given size, populated with new Coordinates.
        /// </summary>
        /// <param name="size">The size of the sequence to create.</param>
        /// <param name="ordinates">The kind of ordinates.</param>
        public DotSpatialAffineCoordinateSequence(int size, Ordinates ordinates)
            : base(size, OrdinatesUtility.OrdinatesToDimension(ordinates & Ordinates.XYZM), OrdinatesUtility.OrdinatesToMeasures(ordinates & Ordinates.XYZM))
        {
            _xy = new double[2 * size];

            if (HasZ)
            {
                _z = NullOrdinateArray(size);
            }

            if (HasM)
            {
                _m = NullOrdinateArray(size);
            }
        }
        private static Ordinate[] ToOrdinateArray(Ordinates ordinates)
        {
            var result    = new Ordinate[OrdinatesUtility.OrdinatesToDimension(ordinates)];
            int nextIndex = 0;

            for (int i = 0; i < 32; i++)
            {
                if (ordinates.HasFlag((Ordinates)(1 << i)))
                {
                    result[nextIndex++] = (Ordinate)i;
                }
            }

            return(result);
        }
        /// <summary>
        /// Creates a sequence based on the given coordinate sequence.
        /// </summary>
        /// <param name="coordSeq">The coordinate sequence.</param>
        /// <param name="ordinates">The ordinates to copy</param>
        public DotSpatialAffineCoordinateSequence(CoordinateSequence coordSeq, Ordinates ordinates)
            : base(coordSeq?.Count ?? 0, OrdinatesUtility.OrdinatesToDimension(ordinates & Ordinates.XYZM), OrdinatesUtility.OrdinatesToMeasures(ordinates & Ordinates.XYZM))
        {
            if (coordSeq is DotSpatialAffineCoordinateSequence dsCoordSeq)
            {
                _xy = (double[])dsCoordSeq._xy.Clone();

                if (HasZ)
                {
                    _z = ((double[])dsCoordSeq._z?.Clone()) ?? NullOrdinateArray(Count);
                }

                if (HasM)
                {
                    _m = ((double[])dsCoordSeq._m?.Clone()) ?? NullOrdinateArray(Count);
                }
            }
            else
            {
                _xy = new double[2 * Count];
                if (HasZ)
                {
                    _z = new double[Count];
                }

                if (HasM)
                {
                    _m = new double[Count];
                }

                var xy = MemoryMarshal.Cast <double, XYStruct>(_xy);
                for (int i = 0; i < xy.Length; i++)
                {
                    xy[i].X = coordSeq.GetX(i);
                    xy[i].Y = coordSeq.GetY(i);
                    if (_z != null)
                    {
                        _z[i] = coordSeq.GetZ(i);
                    }

                    if (_m != null)
                    {
                        _m[i] = coordSeq.GetM(i);
                    }
                }
            }
        }
 /// <summary>
 /// Creates a <see cref="ICoordinateSequence" /> of the specified size and ordinates.
 /// For this to be useful, the <see cref="ICoordinateSequence" /> implementation must be mutable.
 /// </summary>
 /// <param name="size">The number of coordinates</param>
 /// <param name="ordinates">
 /// The ordinates each coordinate has. <see cref="Ordinates.XY"/> is fix, <see cref="Ordinates.Z"/> and <see cref="Ordinates.M"/> can be set.
 /// </param>
 /// <returns></returns>
 public ICoordinateSequence Create(int size, Ordinates ordinates)
 {
     return(Create(size, OrdinatesUtility.OrdinatesToDimension(ordinates)));
 }