C# NetTopologySuite M-значения

Я использую NetTopologySuite в качестве замены ядра.net для SqlGeometries. Кажется, что он не поддерживает 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

Значение М, по-видимому, полностью отклонено. Это ошибка в реализации? Есть ли способ создания точек / координат / линейных строк с М-значениями?

2 ответа

Последовательность координат по умолчанию CoordinateArraySequence который в настоящее время не поддерживает M значения, но это выглядит как DotSpatialAffineCoordinateSequence поддерживает значения М Получить 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);
        }
    }
}

Да, это ошибка, которая отсутствует в реализации по умолчанию 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);
    }

Который затем в свою очередь вызывает GetOrdinate а также SetOrdinate в CoordinateArraySequence

    /// <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);
        }
    }

Который, как вы можете видеть, когда вы звоните SetOrdinate с Ordinate.M на самом деле ничего не устанавливается, и при звонке GetOrdinate с Ordinate.M он всегда будет возвращать NaN.

Если вы действительно хотите использовать NetTopologySuite, вы можете раскошелиться на репозиторий здесь https://github.com/NetTopologySuite/NetTopologySuite и сделать обновления, необходимые для поддержки M значения по умолчанию, но я предполагаю, что есть много вещей, которые необходимо изменить. Если вы его обновите, я уверен, что ребята, поддерживающие репозиторий NetTopologySuite GitHub, будут благодарны за любой запрос на внесение изменений.

Другие вопросы по тегам