#c# #nettopologysuite
Вопрос:
У меня есть многоугольник:
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;
Я попытался «поиграть» с точными моделями, но безрезультатно. Есть какие-нибудь советы?
Ответ №1:
Вам нужно использовать IsValidOp
явно и установить SelfTouchingRingFormingHoleValid = true
:
var ivo = new NetTopologySuite.Operation.Valid.IsValidOp(initialGeometry);
ivo.SelfTouchingRingFormingHoleValid = true;
bool t = ivo.IsValid;
Ваш многоугольник имеет только одно кольцо, определяющее оболочку и отверстия, а не отдельные. Чтобы он был действителен в 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))
Ответ №2:
Вы пробовали взломать «Buffer0», согласно https://github.com/NetTopologySuite/NetTopologySuite/wiki/GettingStarted. Сегодня вечером я столкнулся с аналогичной проблемой и нашел этот вопрос так же, как я решил его для своего случая.
Примечание: Иногда вы встретите недопустимые геометрии (Геометрия.isValid == ложь). Это вызовет проблемы при их дальнейшей обработке. В большинстве случаев вы сможете исправить это с помощью трюка Buffer0:
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
Комментарии:
1. В настоящее время вы должны использовать
NetTopologySuite.Geometries.Utilities.GeometryFixer.Fix(invalidGeometry)
для исправления недопустимых геометрий.