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