DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/intersection/RectangleIntersectionBuilder.h
2024-12-25 07:49:36 +08:00

160 lines
4.2 KiB
C++

/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2014 Mika Heiskanen <mika.heiskanen@fmi.fi>
*
* 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 <geos/export.h>
#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 <memory>
#include <list>
#include <vector>
// 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<geom::Geometry> 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<geom::Polygon*> polygons;
std::list<geom::LineString*> lines;
std::list<geom::Point*> 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