NetTopologySuite 说几何无效,但是 Sql 服务器说它有效
NetTopologySuite said that geometry is not valid, but Sql Server said that it's valid
我有多边形:
polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))
确实看起来不正常,但是 Sql Server 2017 说它是有效的。
但是当我试图用 NTE 阅读它时,它说它是无效的。这是简单的代码:
var wkt = @"polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))";
var wktReader2 = new WKTReader();
var initialGeometry = wktReader2.Read(wkt);
var t = initialGeometry.IsValid;
我尝试 'play' 使用 PrecisionModels 但没有结果。有什么建议吗?
您需要明确使用 IsValidOp
并设置 SelfTouchingRingFormingHoleValid = true
:
var ivo = new NetTopologySuite.Operation.Valid.IsValidOp(initialGeometry);
ivo.SelfTouchingRingFormingHoleValid = true;
bool t = ivo.IsValid;
您的多边形只有一个环定义 shell 和洞,不是分开的。要使其在 NTS 中有效,多边形的 WKT 将为
POLYGON ((0 0, 0 2, 2 2, 2 0, 1 0.1, 0 0), (1 0.1, 1.5 0.5, 1 1, 1 0.1),
(1 1, 1.5 1, 1.5 1.5, 1 1), (1 1, 0.5 1.5, 0.5 1, 1 1))
您是否按照 https://github.com/NetTopologySuite/NetTopologySuite/wiki/GettingStarted 尝试过“Buffer0”黑客攻击?我今天晚上遇到了类似的问题,并且在我为我的案例解决它时发现了这个问题。
Note:
Sometimes you will meet invalid geometries (Geometry.IsValid == false). These will cause issues while further processing them. In most cases you will be able to fix this using the Buffer0 trick:
geom = geom.Buffer(0);
var wkt = @"polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))";
var wktReader2 = new NetTopologySuite.IO.WKTReader();
var initialGeometry = wktReader2.Read(wkt);
var t = initialGeometry.IsValid;
_logger.LogInformation(t.ToString()); // False
var t2 = initialGeometry.Buffer(0).IsValid;
_logger.LogInformation(t2.ToString()); // True
我有多边形:
polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))
确实看起来不正常,但是 Sql Server 2017 说它是有效的。
但是当我试图用 NTE 阅读它时,它说它是无效的。这是简单的代码:
var wkt = @"polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))";
var wktReader2 = new WKTReader();
var initialGeometry = wktReader2.Read(wkt);
var t = initialGeometry.IsValid;
我尝试 'play' 使用 PrecisionModels 但没有结果。有什么建议吗?
您需要明确使用 IsValidOp
并设置 SelfTouchingRingFormingHoleValid = true
:
var ivo = new NetTopologySuite.Operation.Valid.IsValidOp(initialGeometry);
ivo.SelfTouchingRingFormingHoleValid = true;
bool t = ivo.IsValid;
您的多边形只有一个环定义 shell 和洞,不是分开的。要使其在 NTS 中有效,多边形的 WKT 将为
POLYGON ((0 0, 0 2, 2 2, 2 0, 1 0.1, 0 0), (1 0.1, 1.5 0.5, 1 1, 1 0.1),
(1 1, 1.5 1, 1.5 1.5, 1 1), (1 1, 0.5 1.5, 0.5 1, 1 1))
您是否按照 https://github.com/NetTopologySuite/NetTopologySuite/wiki/GettingStarted 尝试过“Buffer0”黑客攻击?我今天晚上遇到了类似的问题,并且在我为我的案例解决它时发现了这个问题。
Note: Sometimes you will meet invalid geometries (Geometry.IsValid == false). These will cause issues while further processing them. In most cases you will be able to fix this using the Buffer0 trick:
geom = geom.Buffer(0);
var wkt = @"polygon((0 0, 1 0.1, 1 1, 0.5 1, 0.5 1.5, 1 1, 1.5 1.5, 1.5 1, 1 1, 1.5 0.5, 1 0.1, 2 0, 2 2,0 2, 0 0))";
var wktReader2 = new NetTopologySuite.IO.WKTReader();
var initialGeometry = wktReader2.Read(wkt);
var t = initialGeometry.IsValid;
_logger.LogInformation(t.ToString()); // False
var t2 = initialGeometry.Buffer(0).IsValid;
_logger.LogInformation(t2.ToString()); // True