237 lines
5.5 KiB
C
237 lines
5.5 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>
|
||
|
#include <memory>
|
||
|
|
||
|
#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
|
||
|
|
||
|
// Forward declarations
|
||
|
namespace geos {
|
||
|
namespace geom {
|
||
|
class GeometryFactory;
|
||
|
class Geometry;
|
||
|
class Polygon;
|
||
|
class LinearRing;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace geos {
|
||
|
namespace operation { // geos::operation
|
||
|
namespace intersection { // geos::operation::intersection
|
||
|
|
||
|
/**
|
||
|
* \brief Clipping rectangle
|
||
|
*
|
||
|
* A clipping rectangle defines the boundaries of the rectangle
|
||
|
* by defining the limiting x- and y-coordinates. The clipping
|
||
|
* rectangle must be non-empty. In addition, methods are provided
|
||
|
* for specifying the location of a given coordinate with respect
|
||
|
* to the clipping rectangle similarly to the Cohen-Sutherland
|
||
|
* clipping algorithm.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
class GEOS_DLL Rectangle {
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* \brief Construct a clipping rectangle
|
||
|
*
|
||
|
* @param x1 x-coordinate of the left edge
|
||
|
* @param y1 y-coordinate of the bottom edge
|
||
|
* @param x2 x-coordinate of the right edge
|
||
|
* @param y2 y-coordinate of the right edge
|
||
|
* @throws IllegalArgumentException if the rectangle is empty
|
||
|
*/
|
||
|
|
||
|
Rectangle(double x1, double y1, double x2, double y2);
|
||
|
|
||
|
/**
|
||
|
* @return the minimum x-coordinate of the rectangle
|
||
|
*/
|
||
|
double
|
||
|
xmin() const
|
||
|
{
|
||
|
return xMin;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return the minimum y-coordinate of the rectangle
|
||
|
*/
|
||
|
|
||
|
double
|
||
|
ymin() const
|
||
|
{
|
||
|
return yMin;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @return the maximum x-coordinate of the rectangle
|
||
|
*/
|
||
|
|
||
|
double
|
||
|
xmax() const
|
||
|
{
|
||
|
return xMax;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @return the maximum y-coordinate of the rectangle
|
||
|
*/
|
||
|
|
||
|
double
|
||
|
ymax() const
|
||
|
{
|
||
|
return yMax;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return the rectangle as a polygon geometry
|
||
|
*
|
||
|
* @note Ownership transferred to caller
|
||
|
*/
|
||
|
std::unique_ptr<geom::Polygon> toPolygon(const geom::GeometryFactory& f) const;
|
||
|
|
||
|
std::unique_ptr<geom::LinearRing> toLinearRing(const geom::GeometryFactory& f) const;
|
||
|
|
||
|
/**
|
||
|
* @brief Position with respect to a clipping rectangle
|
||
|
*/
|
||
|
|
||
|
enum Position {
|
||
|
Inside = 1,
|
||
|
Outside = 2,
|
||
|
|
||
|
Left = 4,
|
||
|
Top = 8,
|
||
|
Right = 16,
|
||
|
Bottom = 32,
|
||
|
|
||
|
TopLeft = Top | Left, // 12
|
||
|
TopRight = Top | Right, // 24
|
||
|
BottomLeft = Bottom | Left, // 36
|
||
|
BottomRight = Bottom | Right // 48
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @brief Test if the given position is on a Rectangle edge
|
||
|
* @param pos Rectangle::Position
|
||
|
* @return `true`, if the position is on an edge
|
||
|
*/
|
||
|
|
||
|
static bool
|
||
|
onEdge(Position pos)
|
||
|
{
|
||
|
return (pos > Outside);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Test if the given positions are on the same Rectangle edge
|
||
|
* @param pos1 [Position](@ref Rectangle::Position) of first coordinate
|
||
|
* @param pos2 [Position](@ref Rectangle::Position) of second coordinate
|
||
|
* @return `true`, if the positions are on the same edge
|
||
|
*/
|
||
|
|
||
|
static bool
|
||
|
onSameEdge(Position pos1, Position pos2)
|
||
|
{
|
||
|
return onEdge(Position(pos1 & pos2));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Establish position of coordinate with respect to a Rectangle
|
||
|
* @param x x-coordinate
|
||
|
* @param y y-coordinate
|
||
|
* @return [Position](@ref Rectangle::Position) of the coordinate
|
||
|
*/
|
||
|
|
||
|
Position
|
||
|
position(double x, double y) const
|
||
|
{
|
||
|
// We assume the point to be inside and test it first
|
||
|
if(x > xMin && x < xMax && y > yMin && y < yMax) {
|
||
|
return Inside;
|
||
|
}
|
||
|
// Next we assume the point to be outside and test it next
|
||
|
if(x < xMin || x > xMax || y < yMin || y > yMax) {
|
||
|
return Outside;
|
||
|
}
|
||
|
// Slower cases
|
||
|
unsigned int pos = 0;
|
||
|
if(x == xMin) {
|
||
|
pos |= Left;
|
||
|
}
|
||
|
else if(x == xMax) {
|
||
|
pos |= Right;
|
||
|
}
|
||
|
if(y == yMin) {
|
||
|
pos |= Bottom;
|
||
|
}
|
||
|
else if(y == yMax) {
|
||
|
pos |= Top;
|
||
|
}
|
||
|
return Position(pos);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Next edge in clock-wise direction
|
||
|
* @param pos [Position](@ref Rectangle::Position)
|
||
|
* @return next [Position](@ref Rectangle::Position) in clock-wise direction
|
||
|
*/
|
||
|
|
||
|
static Position
|
||
|
nextEdge(Position pos)
|
||
|
{
|
||
|
switch(pos) {
|
||
|
case BottomLeft:
|
||
|
case Left:
|
||
|
return Top;
|
||
|
case TopLeft:
|
||
|
case Top:
|
||
|
return Right;
|
||
|
case TopRight:
|
||
|
case Right:
|
||
|
return Bottom;
|
||
|
case BottomRight:
|
||
|
case Bottom:
|
||
|
return Left;
|
||
|
/* silences compiler warnings, Inside & Outside are not handled explicitly */
|
||
|
default:
|
||
|
return pos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
Rectangle();
|
||
|
double xMin;
|
||
|
double yMin;
|
||
|
double xMax;
|
||
|
double yMax;
|
||
|
|
||
|
}; // class RectangleIntersection
|
||
|
|
||
|
} // namespace geos::operation::intersection
|
||
|
} // namespace geos::operation
|
||
|
} // namespace geos
|
||
|
|