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; } } } }