/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2014 Mika Heiskanen * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/ #pragma once #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class #endif #include #include #include // Forward declarations namespace geos { namespace geom { class Coordinate; class CoordinateSequence; class Geometry; class GeometryFactory; class Polygon; class LineString; class Point; } namespace operation { namespace intersection { class Rectangle; } } } namespace geos { namespace operation { // geos::operation namespace intersection { // geos::operation::intersection /** * \brief Rebuild geometries from subpaths left by clipping with a rectangle * * The RectangleIntersectionBuilder is used to maintain lists of polygons, * linestrings and points left from clipping a geom::Geometry with a Rectangle. * Once all clipping has been done, the class builds a valid geom::Geometry from * the components. * * @note This is a utility class needed by RectangleIntersection, and is not * intended for public use. */ class GEOS_DLL RectangleIntersectionBuilder { // Regular users are not supposed to use this utility class. friend class RectangleIntersection; public: ~RectangleIntersectionBuilder(); private: /** * \brief Build the result geometry from partial results and clean up */ std::unique_ptr build(); /** * \brief Build polygons from parts left by clipping one * * 1. Build exterior ring(s) from lines * 2. Attach polygons as holes to the exterior ring(s) */ void reconnectPolygons(const Rectangle& rect); /** * Reconnect disjointed parts * * When we clip a LinearRing we may get multiple linestrings. * Often the first and last ones can be reconnected to simplify * output. * * Sample clip with a rectangle 0,0 --> 10,10 without reconnecting: * * Input: POLYGON ((5 10,0 0,10 0,5 10)) * Output: MULTILINESTRING ((5 10,0 0),(10 0,5 10)) * Desired: LINESTRING (10 0,5 10,0 0) * * TODO: If there is a very sharp spike from inside the rectangle * outside, and then back in, it is possible that the * intersection points at the edge are equal. In this * case we could reconnect the linestrings. The task is * the same we're already doing for the 1st/last linestrings, * we'd just do it for any adjacent pair as well. */ void reconnect(); void reverseLines(); /** * Export parts to another container */ void release(RectangleIntersectionBuilder& parts); // Adding Geometry components void add(geom::Polygon* g); void add(geom::LineString* g); void add(geom::Point* g); // Trivial methods bool empty() const; void clear(); // Added components std::list polygons; std::list lines; std::list points; /** * \brief Close a ring clockwise along rectangle edges * * Only the 4 corners and x1,y1 need to be considered. The possible * cases are: * * x1,y1 * corner1 x1,y1 * corner1 corner2 x1,y1 * corner1 corner2 corner3 x1,y1 * corner1 corner2 corner3 corner4 x1,y1 */ void close_boundary( const Rectangle& rect, geom::CoordinateSequence* ring, double x1, double y1, double x2, double y2); void close_ring(const Rectangle& rect, geom::CoordinateSequence* ring); RectangleIntersectionBuilder(const geom::GeometryFactory& f) : _gf(f) {} const geom::GeometryFactory& _gf; }; // class RectangleIntersectionBuilder } // namespace geos::operation::intersection } // namespace geos::operation } // namespace geos