using System.Collections;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Algorithm;
using GisSharpBlog.NetTopologySuite.Geometries;
using GisSharpBlog.NetTopologySuite.GeometriesGraph;
using GisSharpBlog.NetTopologySuite.Index.Quadtree;
using GisSharpBlog.NetTopologySuite.Utilities;
using System.Collections.Generic;
namespace GisSharpBlog.NetTopologySuite.Operation.Valid{
/// <summary>
/// Tests whether any of a set of <c>LinearRing</c>s are
/// nested inside another ring in the set, using a <c>Quadtree</c>
/// index to speed up the comparisons.
/// </summary>
public class QuadtreeNestedRingTester
{
private GeometryGraph graph; // used to find non-node vertices
private IList rings = new List<LinearRing>();
private IEnvelope totalEnv = new Envelope();
private Quadtree quadtree;
private ICoordinate nestedPt;
/// <summary>
///
/// </summary>
/// <param name="graph"></param>
public QuadtreeNestedRingTester(GeometryGraph graph)
{
this.graph = graph;
}
/// <summary>
///
/// </summary>
public ICoordinate NestedPoint
{
get
{
return nestedPt;
}
}
/// <summary>
///
/// </summary>
/// <param name="ring"></param>
public void Add(ILinearRing ring)
{
rings.Add(ring);
totalEnv.ExpandToInclude(ring.EnvelopeInternal);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool IsNonNested()
{
BuildQuadtree();
for (int i = 0; i < rings.Count; i++)
{
ILinearRing innerRing = (ILinearRing) rings[i];
ICoordinate[] innerRingPts = innerRing.Coordinates;
IList results = quadtree.Query((Envelope) innerRing.EnvelopeInternal);
for (int j = 0; j < results.Count; j++)
{
ILinearRing searchRing = (ILinearRing) results[j];
ICoordinate[] searchRingPts = searchRing.Coordinates;
if (innerRing == searchRing) continue;
if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal)) continue;
ICoordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph);
Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");
bool isInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts);
if (isInside)
{
nestedPt = innerRingPt;
return false;
}
}
}
return true;
}
/// <summary>
///
/// </summary>
private void BuildQuadtree()
{
quadtree = new Quadtree();
for (int i = 0; i < rings.Count; i++)
{
ILinearRing ring = (ILinearRing) rings[i];
Envelope env = (Envelope) ring.EnvelopeInternal;
quadtree.Insert(env, ring);
}
}
}
}
|