C#净拓扑匹配M值
我使用NetTopologySuite作为SQLGeometrics的.net核心替代品。它似乎不支持点或坐标中的M值,尽管它有M个属性。例如,以下简单代码:C#净拓扑匹配M值,c#,.net-core,nettopologysuite,C#,.net Core,Nettopologysuite,我使用NetTopologySuite作为SQLGeometrics的.net核心替代品。它似乎不支持点或坐标中的M值,尽管它有M个属性。例如,以下简单代码: using NetTopologySuite.Geometries; using System.Diagnostics; namespace PlaygroundCore { class Program { static void Main(string[] args) {
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值似乎被完全拒绝。这是实现中的一个bug吗?有没有办法用M值创建点/坐标/线串?是的,这是默认实现的ICoordinateSequence
中缺少的一个bug功能。看起来他们已经开始进行更改以支持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);
}
然后依次调用coordinarraysequence中的getorigin
和setorigin
/// <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);
}
}
//
///返回此序列中坐标的纵坐标。
///纵坐标指数0和1假定为X和Y。
///大于1的纵坐标索引具有用户定义的语义
///(例如,它们可能包含其他标注或测量值)。
///
///序列中的坐标索引。
///坐标中的坐标索引(范围[0,维度-1])。
///
公共双坐标(整数索引,坐标)
{
开关(纵坐标)
{
案例X:
返回坐标[index].X;
案例Y:
返回坐标[index].Y;
案例Z:
返回坐标[index].Z;
违约:
返回double.NaN;
}
}
///
///设置此序列中坐标的给定坐标的值。
///
///序列中的坐标索引。
///坐标中的坐标索引(范围[0,维度-1])。
///新的纵坐标值。
公共空坐标(整数索引、坐标坐标、双值)
{
开关(纵坐标)
{
案例X:
坐标[索引]。X=值;
打破
案例Y:
坐标[索引]。Y=值;
打破
案例Z:
坐标[index].Z=值;
打破
//默认值:
////抛出新的ArgumentException(“无效的纵坐标索引:“+纵坐标”);
}
}
正如您所看到的,当您使用origin.M
调用setorigin
时,没有设置任何内容,而使用origin.M
调用getorigin
时,它将始终返回NaN
如果你真的想使用NetTopologySuite,你可以从这里开始回购,并在默认情况下进行必要的更新,以支持M
值,但我认为有许多事情需要更改。如果您确实更新了它,我相信维护NetTopologySuite GitHub repo的家伙们会很乐意接受包含任何更改的pull请求。默认坐标序列是CoordinaryArraySequence
,目前不支持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);
}
}
}
这不是一个bug,它取决于坐标序列(工厂)可以处理什么。(默认)CooeDateSequence和irs工厂可以处理atm三,第三个是Z。感谢TJ提供的替代解决方案@FOBER迈尔在实现一个接口(在这种情况下,I点)时,我会考虑它,如果不是一个bug,至少是坏的/不需要的设计,具有一个可调用的SETER,但不是一个接口属性的吸气剂。不管引擎盖下面是什么,因为这是用户可以公开看到的。@Johan,您更喜欢NotSupportedException
?我见过很多只部分实现的公共接口。@FObermaier我更喜欢正确的实现。当它是一个官方的Microsoft.NET nuget包(Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite)时,我希望它能按预期工作。好吧,这就解释了问题。我可能错了,但NetTopologySuite不是使其与实体框架核心一起工作的唯一选项(即,能够从数据库中获取和保存几何图形)吗?