using System;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Geometries;
namespace GisSharpBlog.NetTopologySuite.Algorithm
{
///
/// Computes a point in the interior of an linear point.
/// Algorithm:
/// Find an interior vertex which is closest to
/// the centroid of the linestring.
/// If there is no interior vertex, find the endpoint which is
/// closest to the centroid.
///
public class InteriorPointLine
{
private readonly ICoordinate centroid = null;
private double minDistance = Double.MaxValue;
///
///
///
///
public InteriorPointLine(IGeometry g)
{
InteriorPoint = null;
centroid = g.Centroid.Coordinate;
AddInterior(g);
if (InteriorPoint == null)
{
AddEndpoints(g);
}
}
///
///
///
public ICoordinate InteriorPoint { get; private set; }
///
/// Tests the interior vertices (if any)
/// defined by a linear Geometry for the best inside point.
/// If a Geometry is not of dimension 1 it is not tested.
///
/// The point to add.
private void AddInterior(IGeometry geom)
{
if (geom is ILineString)
{
AddInterior(geom.Coordinates);
}
else if (geom is IGeometryCollection)
{
IGeometryCollection gc = (IGeometryCollection) geom;
foreach (IGeometry geometry in gc.Geometries)
{
AddInterior(geometry);
}
}
}
///
///
///
///
private void AddInterior(ICoordinate[] pts)
{
for (int i = 1; i < pts.Length - 1; i++)
{
Add(pts[i]);
}
}
///
/// Tests the endpoint vertices
/// defined by a linear Geometry for the best inside point.
/// If a Geometry is not of dimension 1 it is not tested.
///
/// The point to add.
private void AddEndpoints(IGeometry geom)
{
if (geom is ILineString)
{
AddEndpoints(geom.Coordinates);
}
else if (geom is IGeometryCollection)
{
IGeometryCollection gc = (IGeometryCollection) geom;
foreach (IGeometry geometry in gc.Geometries)
{
AddEndpoints(geometry);
}
}
}
///
///
///
///
private void AddEndpoints(ICoordinate[] pts)
{
Add(pts[0]);
Add(pts[pts.Length - 1]);
}
///
///
///
///
private void Add(ICoordinate point)
{
double dist = point.Distance(centroid);
if (dist < minDistance)
{
InteriorPoint = new Coordinate(point);
minDistance = dist;
}
}
}
}