Envelope.h
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2006 Refractions Research Inc.
*
* 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.
*
**********************************************************************
*
* Last port: geom/Envelope.java rev 1.46 (JTS-1.10)
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/geom/Coordinate.h>
#include <string>
#include <vector>
#include <ostream> // for operator<<
#include <memory>
#include <cassert>
#include <algorithm>
namespace geos {
namespace geom { // geos::geom
class Envelope;
GEOS_DLL std::ostream& operator<< (std::ostream& os, const Envelope& o);
class Coordinate;
class GEOS_DLL Envelope {
public:
friend std::ostream& operator<< (std::ostream& os, const Envelope& o);
typedef std::unique_ptr<Envelope> Ptr;
Envelope()
: minx(DoubleNotANumber)
, maxx(DoubleNotANumber)
, miny(DoubleNotANumber)
, maxy(DoubleNotANumber)
{};
Envelope(double x1, double x2, double y1, double y2)
{
init(x1, x2, y1, y2);
}
Envelope(const CoordinateXY& p1, const CoordinateXY& p2)
{
init(p1, p2);
}
explicit Envelope(const CoordinateXY& p)
: minx(p.x)
, maxx(p.x)
, miny(p.y)
, maxy(p.y)
{
}
explicit Envelope(const std::string& str);
static bool intersects(const CoordinateXY& p1, const CoordinateXY& p2,
const CoordinateXY& q);
static bool intersects(
const CoordinateXY& p1, const CoordinateXY& p2,
const CoordinateXY& q1, const CoordinateXY& q2)
{
double minq = std::min(q1.x, q2.x);
double maxq = std::max(q1.x, q2.x);
double minp = std::min(p1.x, p2.x);
double maxp = std::max(p1.x, p2.x);
if(minp > maxq) {
return false;
}
if(maxp < minq) {
return false;
}
minq = std::min(q1.y, q2.y);
maxq = std::max(q1.y, q2.y);
minp = std::min(p1.y, p2.y);
maxp = std::max(p1.y, p2.y);
if(minp > maxq) {
return false;
}
if(maxp < minq) {
return false;
}
return true;
}
bool intersects(const CoordinateXY& a, const CoordinateXY& b) const;
void init()
{
setToNull();
};
void init(double x1, double x2, double y1, double y2)
{
if(x1 < x2) {
minx = x1;
maxx = x2;
}
else {
minx = x2;
maxx = x1;
}
if(y1 < y2) {
miny = y1;
maxy = y2;
}
else {
miny = y2;
maxy = y1;
}
};
void init(const CoordinateXY& p1, const CoordinateXY& p2)
{
init(p1.x, p2.x, p1.y, p2.y);
};
void init(const CoordinateXY& p)
{
init(p.x, p.x, p.y, p.y);
};
void setToNull()
{
minx = maxx = miny = maxy = DoubleNotANumber;
};
bool isNull(void) const
{
return std::isnan(maxx);
};
double getWidth() const
{
if(isNull()) {
return 0;
}
return maxx - minx;
}
double getHeight() const
{
if(isNull()) {
return 0;
}
return maxy - miny;
}
double
getArea() const
{
return getWidth() * getHeight();
}
double
getPerimeter() const
{
return 2*getWidth() + 2*getHeight();
}
bool
isFinite() const
{
return std::isfinite(getArea());
}
double getMaxY() const
{
assert(!isNull());
return maxy;
};
double getMaxX() const
{
assert(!isNull());
return maxx;
};
double getMinY() const
{
assert(!isNull());
return miny;
};
double getMinX() const
{
assert(!isNull());
return minx;
};
double getDiameter() const
{
if (isNull()) {
return 0.0;
}
double w = getWidth();
double h = getHeight();
return std::sqrt(w*w + h*h);
}
bool centre(CoordinateXY& centre) const;
bool intersection(const Envelope& env, Envelope& result) const;
Envelope intersection(const Envelope& env) const;
void translate(double transX, double transY);
void expandBy(double deltaX, double deltaY);
void
expandBy(double p_distance)
{
expandBy(p_distance, p_distance);
};
void expandToInclude(const CoordinateXY& p)
{
expandToInclude(p.x, p.y);
};
void expandToInclude(double x, double y)
{
if(isNull()) {
minx = x;
maxx = x;
miny = y;
maxy = y;
}
else {
if(x < minx) {
minx = x;
}
if(x > maxx) {
maxx = x;
}
if(y < miny) {
miny = y;
}
if(y > maxy) {
maxy = y;
}
}
};
void expandToInclude(const Envelope* other)
{
if(isNull()) {
minx = other->minx;
maxx = other->maxx;
miny = other->miny;
maxy = other->maxy;
}
else {
if(std::isless(other->minx, minx)) {
minx = other->minx;
}
if(std::isgreater(other->maxx, maxx)) {
maxx = other->maxx;
}
if(std::isless(other->miny, miny)) {
miny = other->miny;
}
if(std::isgreater(other->maxy, maxy)) {
maxy = other->maxy;
}
}
};
void expandToInclude(const Envelope& other)
{
return expandToInclude(&other);
};
bool
contains(const Envelope& other) const
{
return covers(other);
}
bool
contains(const Envelope* other) const
{
return contains(*other);
}
bool
contains(const CoordinateXY& p) const
{
return covers(p.x, p.y);
}
bool
contains(double x, double y) const
{
return covers(x, y);
}
bool intersects(const CoordinateXY& other) const
{
return (std::islessequal(other.x, maxx) && std::isgreaterequal(other.x, minx) &&
std::islessequal(other.y, maxy) && std::isgreaterequal(other.y, miny));
}
bool intersects(double x, double y) const
{
return std::islessequal(x, maxx) &&
std::isgreaterequal(x, minx) &&
std::islessequal(y, maxy) &&
std::isgreaterequal(y, miny);
}
bool intersects(const Envelope* other) const
{
return std::islessequal(other->minx, maxx) &&
std::isgreaterequal(other->maxx, minx) &&
std::islessequal(other->miny, maxy) &&
std::isgreaterequal(other->maxy, miny);
}
bool intersects(const Envelope& other) const
{
return intersects(&other);
}
bool disjoint(const Envelope& other) const
{
return !intersects(other);
}
bool disjoint(const Envelope* other) const
{
return !intersects(other);
}
bool covers(double x, double y) const {
return std::isgreaterequal(x, minx) &&
std::islessequal(x, maxx) &&
std::isgreaterequal(y, miny) &&
std::islessequal(y, maxy);
}
bool covers(const CoordinateXY* p) const
{
return covers(p->x, p->y);
}
bool covers(const Envelope& other) const;
bool
covers(const Envelope* other) const
{
return covers(*other);
}
bool equals(const Envelope* other) const;
bool isfinite() const;
std::string toString() const;
double distance(const Envelope& env) const
{
return std::sqrt(distanceSquared(env));
}
double maxDistance(const Envelope& other) const
{
Coordinate p(std::min(minx, other.minx), std::min(miny, other.miny));
Coordinate q(std::max(maxx, other.maxx), std::max(maxy, other.maxy));
return p.distance(q);
}
double distanceSquared(const Envelope& env) const
{
double dx = std::max(0.0,
std::max(maxx, env.maxx) - std::min(minx, env.minx) - (maxx - minx) -
(env.maxx - env.minx));
double dy = std::max(0.0,
std::max(maxy, env.maxy) - std::min(miny, env.miny) - (maxy - miny) -
(env.maxy - env.miny));
return dx * dx + dy * dy;
};
static double distanceToCoordinate(
const CoordinateXY& c,
const CoordinateXY& p0,
const CoordinateXY& p1)
{
return std::sqrt(distanceSquaredToCoordinate(c, p0, p1));
};
static double distanceSquaredToCoordinate(
const CoordinateXY& c,
const CoordinateXY& p0,
const CoordinateXY& p1)
{
double xa = c.x - p0.x;
double xb = c.x - p1.x;
double ya = c.y - p0.y;
double yb = c.y - p1.y;
// If sign of a and b are not the same, then Envelope spans c and distance is zero.
double dx = (std::signbit(xa) == std::signbit(xb)) * std::min(std::abs(xa), std::abs(xb));
double dy = (std::signbit(ya) == std::signbit(yb)) * std::min(std::abs(ya), std::abs(yb));
return dx*dx + dy*dy;
}
std::size_t hashCode() const
{
auto hash = std::hash<double>{};
//Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
std::size_t result = 17;
result = 37 * result + hash(minx);
result = 37 * result + hash(maxx);
result = 37 * result + hash(miny);
result = 37 * result + hash(maxy);
return result;
}
struct GEOS_DLL HashCode
{
std::size_t operator()(const Envelope& e) const
{
return e.hashCode();
};
};
// GEOS_DLL bool operator==(const Envelope& a, const Envelope& b);
GEOS_DLL friend bool
operator==(const Envelope& a, const Envelope& b)
{
return a.equals(&b);
}
// GEOS_DLL bool operator!=(const Envelope& a, const Envelope& b);
GEOS_DLL friend bool
operator!=(const Envelope& a, const Envelope& b)
{
return !(a == b);
}
GEOS_DLL friend bool
operator< (const Envelope& a, const Envelope& b);
private:
static std::vector<std::string> split(const std::string& str,
const std::string& delimiters = " ");
static double distance(double x0, double y0, double x1, double y1)
{
double dx = x1 - x0;
double dy = y1 - y0;
return std::sqrt(dx * dx + dy * dy);
}
double minx;
double maxx;
double miny;
double maxy;
};
} // namespace geos::geom
} // namespace geos
geos::geom::Coordinate
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:217
geos::geom::Envelope
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition Envelope.h:59
geos::geom::Envelope::getMinX
double getMinX() const
Returns the Envelope minimum x-value. Null envelopes do not have maximum values.
Definition Envelope.h:350
geos::geom::Envelope::expandToInclude
void expandToInclude(const CoordinateXY &p)
Enlarges the boundary of the Envelope so that it contains p. Does nothing if p is already on or withi...
Definition Envelope.h:437
geos::geom::Envelope::contains
bool contains(const CoordinateXY &p) const
Returns true if the given point lies in or on the envelope.
Definition Envelope.h:544
geos::geom::Envelope::intersection
bool intersection(const Envelope &env, Envelope &result) const
Computes the intersection of two Envelopes.
geos::geom::Envelope::distanceSquared
double distanceSquared(const Envelope &env) const
Computes the square of the distance between this and another Envelope.
Definition Envelope.h:717
geos::geom::Envelope::contains
bool contains(const Envelope &other) const
Tests if the Envelope other lies wholly inside this Envelope (inclusive of the boundary).
Definition Envelope.h:525
geos::geom::Envelope::expandToInclude
void expandToInclude(double x, double y)
Enlarges the boundary of the Envelope so that it contains (x,y).
Definition Envelope.h:452
geos::geom::Envelope::intersects
bool intersects(double x, double y) const
Check if the point (x, y) intersects (lies inside) the region of this Envelope.
Definition Envelope.h:584
geos::geom::Envelope::isfinite
bool isfinite() const
geos::geom::Envelope::getDiameter
double getDiameter() const
Definition Envelope.h:361
geos::geom::Envelope::equals
bool equals(const Envelope *other) const
Returns true if the Envelope other spatially equals this Envelope.
geos::geom::Envelope::setToNull
void setToNull()
Makes this Envelope a "null" envelope, that is, the envelope of the empty geometry.
Definition Envelope.h:241
geos::geom::Envelope::covers
bool covers(double x, double y) const
Tests if the given point lies in or on the envelope.
Definition Envelope.h:635
geos::geom::Envelope::centre
bool centre(CoordinateXY &centre) const
Computes the coordinate of the centre of this envelope (as long as it is non-null).
geos::geom::Envelope::distance
double distance(const Envelope &env) const
Computes the distance between this and another Envelope.
Definition Envelope.h:696
geos::geom::Envelope::distanceToCoordinate
static double distanceToCoordinate(const CoordinateXY &c, const CoordinateXY &p0, const CoordinateXY &p1)
Computes the distance between one Coordinate and an Envelope defined by two other Coordinates....
Definition Envelope.h:738
geos::geom::Envelope::getArea
double getArea() const
Gets the area of this envelope.
Definition Envelope.h:290
geos::geom::Envelope::getPerimeter
double getPerimeter() const
Gets the perimeter of this envelope.
Definition Envelope.h:302
geos::geom::Envelope::init
void init(const CoordinateXY &p1, const CoordinateXY &p2)
Initialize an Envelope to a region defined by two Coordinates.
Definition Envelope.h:222
geos::geom::Envelope::expandBy
void expandBy(double deltaX, double deltaY)
Expands this envelope by a given distance in all directions. Both positive and negative distances are...
geos::geom::Envelope::init
void init(double x1, double x2, double y1, double y2)
Initialize an Envelope for a region defined by maximum and minimum values.
Definition Envelope.h:196
geos::geom::Envelope::intersects
static bool intersects(const CoordinateXY &p1, const CoordinateXY &p2, const CoordinateXY &q)
Test the point q to see whether it intersects the Envelope defined by p1-p2.
geos::geom::Envelope::contains
bool contains(double x, double y) const
Returns true if the given point lies in or on the envelope.
Definition Envelope.h:560
geos::geom::Envelope::getHeight
double getHeight() const
Returns the difference between the maximum and minimum y values.
Definition Envelope.h:275
geos::geom::Envelope::Envelope
Envelope()
Creates a null Envelope.
Definition Envelope.h:70
geos::geom::Envelope::Envelope
Envelope(const std::string &str)
Create an Envelope from an Envelope string representation produced by Envelope::toString().
geos::geom::Envelope::isFinite
bool isFinite() const
Returns true if this Envelope covers a finite region.
Definition Envelope.h:311
geos::geom::Envelope::getWidth
double getWidth() const
Returns the difference between the maximum and minimum x values.
Definition Envelope.h:262
geos::geom::Envelope::getMaxX
double getMaxX() const
Returns the Envelope maximum x-value. Null envelopes do not have maximum values.
Definition Envelope.h:330
geos::geom::Envelope::intersects
bool intersects(const CoordinateXY &a, const CoordinateXY &b) const
Check if the extent defined by two extremal points intersects the extent of this Envelope.
geos::geom::Envelope::getMaxY
double getMaxY() const
Returns the Envelope maximum y-value. Null envelopes do not have maximum values.
Definition Envelope.h:320
geos::geom::Envelope::isNull
bool isNull(void) const
Returns true if this Envelope is a "null" envelope.
Definition Envelope.h:252
geos::geom::Envelope::init
void init(const CoordinateXY &p)
Initialize an Envelope to a region defined by a single Coordinate.
Definition Envelope.h:232
geos::geom::Envelope::expandBy
void expandBy(double p_distance)
Expands this envelope by a given distance in all directions.
Definition Envelope.h:426
geos::geom::Envelope::covers
bool covers(const CoordinateXY *p) const
Tests if the given point lies in or on the envelope.
Definition Envelope.h:648
geos::geom::Envelope::expandToInclude
void expandToInclude(const Envelope *other)
Enlarges the boundary of the Envelope so that it contains other.
Definition Envelope.h:483
geos::geom::Envelope::intersects
static bool intersects(const CoordinateXY &p1, const CoordinateXY &p2, const CoordinateXY &q1, const CoordinateXY &q2)
Test the envelope defined by p1-p2 for intersection with the envelope defined by q1-q2.
Definition Envelope.h:143
geos::geom::Envelope::Envelope
Envelope(const CoordinateXY &p)
Creates an Envelope for a region defined by a single Coordinate.
Definition Envelope.h:106
geos::geom::Envelope::intersection
Envelope intersection(const Envelope &env) const
Computes the intersection of two Envelopes.
geos::geom::Envelope::disjoint
bool disjoint(const Envelope &other) const
Definition Envelope.h:618
geos::geom::Envelope::init
void init()
Initialize to a null Envelope.
Definition Envelope.h:183
geos::geom::Envelope::operator==
friend bool operator==(const Envelope &a, const Envelope &b)
Checks if two Envelopes are equal (2D only check).
Definition Envelope.h:796
geos::geom::Envelope::Envelope
Envelope(const CoordinateXY &p1, const CoordinateXY &p2)
Creates an Envelope for a region defined by two Coordinates.
Definition Envelope.h:96
geos::geom::Envelope::toString
std::string toString() const
Returns a string of the form Env[minx:maxx,miny:maxy].
geos::geom::Envelope::intersects
bool intersects(const Envelope *other) const
Check if the region defined by other Envelope intersects the region of this Envelope.
Definition Envelope.h:598
geos::geom::Envelope::intersects
bool intersects(const CoordinateXY &other) const
Check if the point p intersects (lies inside) the region of this Envelope.
Definition Envelope.h:571
geos::geom::Envelope::distanceSquaredToCoordinate
static double distanceSquaredToCoordinate(const CoordinateXY &c, const CoordinateXY &p0, const CoordinateXY &p1)
Computes the squared distance between one Coordinate and an Envelope defined by two other Coordinates...
Definition Envelope.h:755
geos::geom::Envelope::translate
void translate(double transX, double transY)
Translates this envelope by given amounts in the X and Y direction.
geos::geom::Envelope::covers
bool covers(const Envelope &other) const
Tests if the Envelope other lies wholly inside this Envelope (inclusive of the boundary).
geos::geom::Envelope::getMinY
double getMinY() const
Returns the Envelope minimum y-value. Null envelopes do not have maximum values.
Definition Envelope.h:340
geos::geom::Envelope::Envelope
Envelope(double x1, double x2, double y1, double y2)
Creates an Envelope for a region defined by maximum and minimum values.
Definition Envelope.h:85
geos::geom::Envelope::maxDistance
double maxDistance(const Envelope &other) const
Computes the maximum distance between points in this and another Envelope.
Definition Envelope.h:704
geos::geom
Definition Angle.h:26
geos
Basic namespace for all GEOS functionalities.
Definition geos.h:38