1

我使用 NetTopologySuite 作为 SqlGeometries 的 .net 核心替代品。尽管它具有 M 属性,但似乎它不支持点或坐标中的 M 值。例如这个简单的代码:

using NetTopologySuite.Geometries;
using System.Diagnostics;

namespace PlaygroundCore
{
    class Program
    {
        static void Main(string[] args)
        {
            var p3 = new Point(1, 2, 3);
            p3.Y = 8;
            p3.M = 1;
            var m = p3.M;

            Debug.WriteLine(p3);
            Debug.WriteLine(p3.M);
            Debug.WriteLine(m);
        }
    }
}

输出

POINT (1 8 3)
NaN
NaN

M 值似乎被完全拒绝了。这是实现中的错误吗?有没有办法用 M 值创建点/坐标/线串?

4

2 回答 2

2

默认坐标序列是CoordinateArraySequence当前不支持M值,但看起来DotSpatialAffineCoordinateSequence确实支持 M 值。为了使M价值观发挥作用,我必须执行以下操作

using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Implementation;
using System.Diagnostics;

namespace NetTopologyTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //This sequence has to be initialized with ordinates XYZM. If you construct it
            //with just XYZ values, then you can't add M values to it later.
            var coordinateSequence = new DotSpatialAffineCoordinateSequence(new[] { 1.0, 2.0 }, new[] { 3.0 }, new[] { 4.0 });
            var sequenceFactory = new DotSpatialAffineCoordinateSequenceFactory(GeoAPI.Geometries.Ordinates.XYZM);
            var geometryFactory = new GeometryFactory(sequenceFactory);
            var p3 = new Point(coordinateSequence, geometryFactory);
            p3.Y = 8;
            p3.M = 1;
            var m = p3.M;

            Debug.WriteLine(p3);
            Debug.WriteLine(p3.M);
            Debug.WriteLine(m);
        }
    }
}
于 2018-12-13T16:28:44.963 回答
0

是的,这是默认实现中缺少的错误ICoordinateSequence功能。看起来他们已经开始进行更改以支持 M 值,但这些更改并没有在所有地方进行。以下是代码中不支持 M 值的至少一个区域,这最终导致了您所看到的问题。

引用 p3.M 时,它使用这些 get 和 set 方法。

    public double M
    {
        get
        {
            if (CoordinateSequence == null)
                throw new ArgumentOutOfRangeException("M called on empty Point");
            return CoordinateSequence.GetOrdinate(0, Ordinate.M);
        }
        set => CoordinateSequence.SetOrdinate(0, Ordinate.M, value);
    }

然后依次调用GetOrdinateSetOrdinateCoordinateArraySequence

    /// <summary>
    /// Returns the ordinate of a coordinate in this sequence.
    /// Ordinate indices 0 and 1 are assumed to be X and Y.
    /// Ordinate indices greater than 1 have user-defined semantics
    /// (for instance, they may contain other dimensions or measure values).
    /// </summary>
    /// <param name="index">The coordinate index in the sequence.</param>
    /// <param name="ordinate">The ordinate index in the coordinate (in range [0, dimension-1]).</param>
    /// <returns></returns>
    public double GetOrdinate(int index, Ordinate ordinate)
    {
        switch (ordinate)
        {
            case Ordinate.X:
                return Coordinates[index].X;
            case Ordinate.Y:
                return Coordinates[index].Y;
            case Ordinate.Z:
                return Coordinates[index].Z;
            default:
                return double.NaN;
        }
    }

    /// <summary>
    /// Sets the value for a given ordinate of a coordinate in this sequence.
    /// </summary>
    /// <param name="index">The coordinate index in the sequence.</param>
    /// <param name="ordinate">The ordinate index in the coordinate (in range [0, dimension-1]).</param>
    /// <param name="value">The new ordinate value.</param>
    public void SetOrdinate(int index, Ordinate ordinate, double value)
    {
        switch (ordinate)
        {
            case Ordinate.X:
                Coordinates[index].X = value;
                break;
            case Ordinate.Y:
                Coordinates[index].Y = value;
                break;
            case Ordinate.Z:
                Coordinates[index].Z = value;
                break;
            //default:
            //    //throw new ArgumentException("invalid ordinate index: " + ordinate);
        }
    }

正如您所看到的,当您调用SetOrdinateOrdinate.M没有真正设置,并且调用GetOrdinateOrdinate.M将始终返回 NaN。

如果你真的想使用 NetTopologySuite,你可以从这里分叉回购https://github.com/NetTopologySuite/NetTopologySuite并进行默认情况下支持M值所需的更新,但我想有很多事情需要做改变了。如果您确实更新它,我相信维护 NetTopologySuite GitHub 存储库的人会很感激任何更改的拉取请求。

于 2018-12-13T15:51:33.637 回答