160 lines
4.2 KiB
C++
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
|
|
|