// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System.Collections.Generic; using System.Linq; using Core.Common.Base.Geometry; using GeoAPI.Geometries; using NetTopologySuite.Geometries; namespace Core.Common.Geometry { public class AdvancedMath2D { /// /// Calculates the intersection between two polygons, which can result in any number of polygons which represent the intersecting area. Polygons /// are defined by collections of points. /// /// Points of the first polygon. /// Points of the second polygon. /// A collection of point collections. Each point collection describes an intersecting area of the polygons. /// public static IEnumerable> PolygonIntersectionWithPolygon(IEnumerable pointsOfPolygonA, IEnumerable pointsOfPolygonB) { Polygon polygonA = PointsToPolygon(pointsOfPolygonA); Polygon polygonB = PointsToPolygon(pointsOfPolygonB); try { IGeometry intersection = polygonA.Intersection(polygonB); return BuildSepearteAreasFromCoordinateList(intersection.Coordinates); } catch (TopologyException e) { throw new InvalidPolygonException(e.Message, e); } } private static Polygon PointsToPolygon(IEnumerable points) { var pointList = points.ToList(); if (!pointList.First().Equals(pointList.Last())) { pointList.Add(pointList.First()); } var coordinates = pointList.Select(p => new Coordinate(p.X, p.Y)).ToArray(); return new Polygon(new LinearRing(coordinates)); } private static IEnumerable> BuildSepearteAreasFromCoordinateList(Coordinate[] coordinates) { var areas = new List>(); HashSet area = new HashSet(); foreach (var coordinate in coordinates) { var added = area.Add(new Point2D(coordinate.X, coordinate.Y)); if (!added) { areas.Add(area); area = new HashSet(); } } return areas; } } }