NetTopologySuite / NetTopologySuite.Features

An implementation of Feature and FeatureCollection
BSD 3-Clause "New" or "Revised" License
8 stars 14 forks source link

Add FeatureCollection ctor with IList<Feature> parameter #9

Closed ondrejsv closed 3 years ago

ondrejsv commented 5 years ago

Add a FeatureCollection constructor with a List parameter for quickly constructing a FeatureCollection instance based on some other list of Feature instances.

There was a similar constructor in the pre-2.0 version: https://github.com/NetTopologySuite/NetTopologySuite.Features/blob/3840d11e9c3911ae6ba9b8ef9ec88e74fcbfe604/NetTopologySuite.Features/Features/FeatureCollection.cs#L65

Now the only way to make such a FeatureCollection instance is an ugly foreach loop.

airbreather commented 3 years ago

Parameter type is IEnumerable<IFeature>, so we will always do a copy -- otherwise, this is done.

mircowidmer commented 4 months ago

I'm using the following dependency in my project:

<PackageReference Include="NetTopologySuite" Version="2.5.0"/>

I assume, that I'm able to use the collection constructor, that is implemented here: https://github.com/NetTopologySuite/NetTopologySuite.Features/blob/develop/src/NetTopologySuite.Features/FeatureCollection.cs

The implementation of FeatureCollection I have access to is the following:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;

using NetTopologySuite.Geometries;

namespace NetTopologySuite.Features
{
    ///<summary>
    /// Represents a feature collection.
    ///</summary>
    [Serializable]
    public sealed class FeatureCollection : Collection<IFeature>, ISerializable
    {
        /// <summary>
        /// The bounding box of this <see cref="FeatureCollection"/>
        /// </summary>
        private Envelope _boundingBox;

        /// <summary>
        /// Initializes a new instance of the <see cref="FeatureCollection"/> class.
        /// </summary>
        public FeatureCollection()
            : base(new List<IFeature>())
        {
        }

        private FeatureCollection(SerializationInfo info, StreamingContext context)
            : base((List<IFeature>)info.GetValue("features", typeof(List<IFeature>)))
        {
            _boundingBox = info.GetBoundingBox();
        }

        /// <summary>
        /// Gets or sets the (optional) <see href="http://geojson.org/geojson-spec.html#geojson-objects"> Bounding box (<c>bbox</c>) Object</see>.
        /// </summary>
        /// <value>
        /// A <see cref="Envelope"/> describing the bounding box or <see langword="null"/>.
        /// </value>
        public Envelope BoundingBox
        {
            get
            {
                if (_boundingBox is null)
                {
                    _boundingBox = ComputeBoundingBox();
                }

                return _boundingBox?.Copy();
            }

            set => _boundingBox = value;
        }

        /// <summary>
        /// Function to compute the bounding box (when it isn't set)
        /// </summary>
        /// <returns>A bounding box for this <see cref="FeatureCollection"/></returns>
        private Envelope ComputeBoundingBox()
        {
            if (!Feature.ComputeBoundingBoxWhenItIsMissing)
            {
                return null;
            }

            var res = new Envelope();
            foreach (var feature in (List<IFeature>)Items)
            {
                if (feature is null)
                {
                    continue;
                }

                if (!(feature.BoundingBox is null))
                {
                    res.ExpandToInclude(feature.BoundingBox);
                }
                else if (!(feature.Geometry is null))
                {
                    res.ExpandToInclude(feature.Geometry.EnvelopeInternal);
                }
            }

            return res;
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddBoundingBox(_boundingBox);
            info.AddValue("features", Items);
        }
    }
}

Unfortunately I don't see the constructor public FeatureCollection(IEnumerable<IFeature> features) which is implemented in the NetTopologySuite.Features class and I don't get it why.

FObermaier commented 3 months ago

This change has not been released in form of a nuget package yet. Sorry, will do that asap.

FObermaier commented 3 months ago

@mircowidmer: v2.2.0 was released