Last active
November 26, 2015 07:24
-
-
Save osya/1e8cc0063ee9a75def65 to your computer and use it in GitHub Desktop.
Доработка NTS, чтобы он делал UNION для невалидных полигонов #CSharp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using GeoAPI.Geometries; | |
using NetTopologySuite.Geometries; | |
using NetTopologySuite.Simplify; | |
namespace NetTopologySuite.Operation.Overlay.Snap | |
{ | |
/// <summary> | |
/// Performs an overlay operation using snapping and enhanced precision | |
/// to improve the robustness of the result. | |
/// This class only uses snapping | |
/// if an error is detected when running the standard JTS overlay code. | |
/// Errors detected include thrown exceptions | |
/// (in particular, <see cref="TopologyException" />) | |
/// and invalid overlay computations. | |
/// </summary> | |
public class SnapIfNeededOverlayOp | |
{ | |
public static IGeometry Overlay(IGeometry g0, IGeometry g1, SpatialFunction opCode) | |
{ | |
var op = new SnapIfNeededOverlayOp(g0, g1); | |
return op.GetResultGeometry(opCode); | |
} | |
public static IGeometry Intersection(IGeometry g0, IGeometry g1) | |
{ | |
return Overlay(g0, g1, SpatialFunction.Intersection); | |
} | |
public static IGeometry Union(IGeometry g0, IGeometry g1) | |
{ | |
return Overlay(g0, g1, SpatialFunction.Union); | |
} | |
public static IGeometry Difference(IGeometry g0, IGeometry g1) | |
{ | |
return Overlay(g0, g1, SpatialFunction.Difference); | |
} | |
public static IGeometry SymDifference(IGeometry g0, IGeometry g1) | |
{ | |
return Overlay(g0, g1, SpatialFunction.SymDifference); | |
} | |
private readonly IGeometry[] _geom = new IGeometry[2]; | |
public SnapIfNeededOverlayOp(IGeometry g1, IGeometry g2) | |
{ | |
_geom[0] = g1; | |
_geom[1] = g2; | |
} | |
public IGeometry GetResultGeometry(SpatialFunction opCode) | |
{ | |
IGeometry result = null; | |
var isSuccess = false; | |
Exception savedException = null; | |
try | |
{ | |
// try basic operation with input geometries | |
result = OverlayOp.Overlay(_geom[0], _geom[1], opCode); | |
var isValid = true; | |
// not needed if noding validation is used | |
// boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result); | |
// if (isValid) | |
isSuccess = true; | |
} | |
catch (Exception ex) | |
{ | |
savedException = ex; | |
// Ignore this exception, since the operation will be rerun | |
} | |
if (!isSuccess) | |
{ | |
// this may still throw an exception | |
// if so, throw the original exception since it has the input coordinates | |
try | |
{ | |
result = SnapOverlayOp.Overlay(_geom[0], _geom[1], opCode); | |
isSuccess = true; | |
} | |
catch (Exception) | |
{ | |
; | |
} | |
} | |
if (!isSuccess) | |
{ | |
try | |
{ | |
var simplified0 = DouglasPeuckerSimplifier.Simplify(_geom[0], 1); | |
var buffered0 = simplified0.Buffer(1); | |
var simplified1 = DouglasPeuckerSimplifier.Simplify(_geom[1], 1); | |
var buffered1 = simplified1.Buffer(1); | |
result = OverlayOp.Overlay(buffered0, buffered1, opCode); | |
} | |
catch (Exception) | |
{ | |
throw savedException; | |
} | |
} | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment