GEOS 3.11.1
Envelope.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2006 Refractions Research Inc.
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
12 *
13 **********************************************************************
14 *
15 * Last port: geom/Envelope.java rev 1.46 (JTS-1.10)
16 *
17 **********************************************************************/
18
19#pragma once
20
21
22#include <geos/export.h>
23#include <geos/geom/Coordinate.h>
24
25#include <string>
26#include <vector>
27#include <ostream> // for operator<<
28#include <memory>
29#include <cassert>
30#include <algorithm>
31
32namespace geos {
33namespace geom { // geos::geom
34
35class Envelope;
36
38GEOS_DLL std::ostream& operator<< (std::ostream& os, const Envelope& o);
39
40class Coordinate;
41
58class GEOS_DLL Envelope {
59
60public:
61
62 friend std::ostream& operator<< (std::ostream& os, const Envelope& o);
63
64 typedef std::unique_ptr<Envelope> Ptr;
65
70 : minx(DoubleNotANumber)
71 , maxx(DoubleNotANumber)
72 , miny(DoubleNotANumber)
73 , maxy(DoubleNotANumber)
74 {};
75
84 Envelope(double x1, double x2, double y1, double y2)
85 {
86 init(x1, x2, y1, y2);
87 }
88
95 Envelope(const Coordinate& p1, const Coordinate& p2)
96 {
97 init(p1, p2);
98 }
99
105 explicit Envelope(const Coordinate& p)
106 {
107 init(p);
108 }
109
114 explicit Envelope(const std::string& str);
115
125 static bool intersects(const Coordinate& p1, const Coordinate& p2,
126 const Coordinate& q);
127
139 static bool intersects(
140 const Coordinate& p1, const Coordinate& p2,
141 const Coordinate& q1, const Coordinate& q2)
142 {
143 double minq = std::min(q1.x, q2.x);
144 double maxq = std::max(q1.x, q2.x);
145 double minp = std::min(p1.x, p2.x);
146 double maxp = std::max(p1.x, p2.x);
147 if(minp > maxq) {
148 return false;
149 }
150 if(maxp < minq) {
151 return false;
152 }
153 minq = std::min(q1.y, q2.y);
154 maxq = std::max(q1.y, q2.y);
155 minp = std::min(p1.y, p2.y);
156 maxp = std::max(p1.y, p2.y);
157 if(minp > maxq) {
158 return false;
159 }
160 if(maxp < minq) {
161 return false;
162 }
163 return true;
164 }
165
174 bool intersects(const Coordinate& a, const Coordinate& b) const;
175
179 void init()
180 {
181 setToNull();
182 };
183
192 void init(double x1, double x2, double y1, double y2)
193 {
194 if(x1 < x2) {
195 minx = x1;
196 maxx = x2;
197 }
198 else {
199 minx = x2;
200 maxx = x1;
201 }
202 if(y1 < y2) {
203 miny = y1;
204 maxy = y2;
205 }
206 else {
207 miny = y2;
208 maxy = y1;
209 }
210 };
211
218 void init(const Coordinate& p1, const Coordinate& p2)
219 {
220 init(p1.x, p2.x, p1.y, p2.y);
221 };
222
228 void init(const Coordinate& p)
229 {
230 init(p.x, p.x, p.y, p.y);
231 };
232
238 {
239 minx = maxx = miny = maxy = DoubleNotANumber;
240 };
241
248 bool isNull(void) const
249 {
250 return std::isnan(maxx);
251 };
252
258 double getWidth() const
259 {
260 if(isNull()) {
261 return 0;
262 }
263 return maxx - minx;
264 }
265
271 double getHeight() const
272 {
273 if(isNull()) {
274 return 0;
275 }
276 return maxy - miny;
277 }
278
285 double
286 getArea() const
287 {
288 return getWidth() * getHeight();
289 }
290
295 double getMaxY() const
296 {
297 assert(!isNull());
298 return maxy;
299 };
300
305 double getMaxX() const
306 {
307 assert(!isNull());
308 return maxx;
309 };
310
315 double getMinY() const
316 {
317 assert(!isNull());
318 return miny;
319 };
320
325 double getMinX() const
326 {
327 assert(!isNull());
328 return minx;
329 };
330
336 double getDiameter() const
337 {
338 if (isNull()) {
339 return 0.0;
340 }
341 double w = getWidth();
342 double h = getHeight();
343 return std::sqrt(w*w + h*h);
344 }
345
353 bool centre(Coordinate& centre) const;
354
364 bool intersection(const Envelope& env, Envelope& result) const;
365
372 void translate(double transX, double transY);
373
381 void expandBy(double deltaX, double deltaY);
382
390 void
391 expandBy(double p_distance)
392 {
393 expandBy(p_distance, p_distance);
394 };
395
403 {
404 expandToInclude(p.x, p.y);
405 };
406
417 void expandToInclude(double x, double y)
418 {
419 if(isNull()) {
420 minx = x;
421 maxx = x;
422 miny = y;
423 maxy = y;
424 }
425 else {
426 if(x < minx) {
427 minx = x;
428 }
429 if(x > maxx) {
430 maxx = x;
431 }
432 if(y < miny) {
433 miny = y;
434 }
435 if(y > maxy) {
436 maxy = y;
437 }
438 }
439 };
440
448 void expandToInclude(const Envelope* other)
449 {
450 if(isNull()) {
451 minx = other->minx;
452 maxx = other->maxx;
453 miny = other->miny;
454 maxy = other->maxy;
455 }
456 else {
457 if(other->minx < minx) {
458 minx = other->minx;
459 }
460 if(other->maxx > maxx) {
461 maxx = other->maxx;
462 }
463 if(other->miny < miny) {
464 miny = other->miny;
465 }
466 if(other->maxy > maxy) {
467 maxy = other->maxy;
468 }
469 }
470 };
471
472 void expandToInclude(const Envelope& other)
473 {
474 return expandToInclude(&other);
475 };
476
489 bool
490 contains(const Envelope& other) const
491 {
492 return covers(other);
493 }
494
495 bool
496 contains(const Envelope* other) const
497 {
498 return contains(*other);
499 }
500
508 bool
509 contains(const Coordinate& p) const
510 {
511 return covers(p.x, p.y);
512 }
513
524 bool
525 contains(double x, double y) const
526 {
527 return covers(x, y);
528 }
529
536 bool intersects(const Coordinate& other) const
537 {
538 return (other.x <= maxx && other.x >= minx &&
539 other.y <= maxy && other.y >= miny);
540 }
541
549 bool intersects(double x, double y) const
550 {
551 return (x <= maxx && x >= minx && y <= maxy && y >= miny);
552 }
553
560 bool intersects(const Envelope* other) const
561 {
562 return other->minx <= maxx &&
563 other->maxx >= minx &&
564 other->miny <= maxy &&
565 other->maxy >= miny;
566 }
567
568 bool intersects(const Envelope& other) const
569 {
570 return intersects(&other);
571 }
572
580 bool disjoint(const Envelope& other) const
581 {
582 return disjoint(&other);
583 }
584
585 bool disjoint(const Envelope* other) const
586 {
587 return !(other->minx <= maxx ||
588 other->maxx >= minx ||
589 other->miny <= maxy ||
590 other->maxy >= miny);
591 }
592
600 bool covers(double x, double y) const;
601
608 bool covers(const Coordinate* p) const
609 {
610 return covers(p->x, p->y);
611 }
612
619 bool covers(const Envelope& other) const;
620
621 bool
622 covers(const Envelope* other) const
623 {
624 return covers(*other);
625 }
626
627
634 bool equals(const Envelope* other) const;
635
641 std::string toString() const;
642
649 double distance(const Envelope& env) const
650 {
651 return std::sqrt(distanceSquared(env));
652 }
653
660 double distanceSquared(const Envelope& env) const
661 {
662 double dx = std::max(0.0,
663 std::max(maxx, env.maxx) - std::min(minx, env.minx) - (maxx - minx) -
664 (env.maxx - env.minx));
665 double dy = std::max(0.0,
666 std::max(maxy, env.maxy) - std::min(miny, env.miny) - (maxy - miny) -
667 (env.maxy - env.miny));
668
669 return dx * dx + dy * dy;
670 };
671
681 static double distanceToCoordinate(
682 const Coordinate& c,
683 const Coordinate& p0,
684 const Coordinate& p1)
685 {
686 return std::sqrt(distanceSquaredToCoordinate(c, p0, p1));
687 };
688
699 const Coordinate& c,
700 const Coordinate& p0,
701 const Coordinate& p1)
702 {
703 double xa = c.x - p0.x;
704 double xb = c.x - p1.x;
705 double ya = c.y - p0.y;
706 double yb = c.y - p1.y;
707
708 // If sign of a and b are not the same, then Envelope spans c and distance is zero.
709 double dx = (std::signbit(xa) == std::signbit(xb)) * std::min(std::abs(xa), std::abs(xb));
710 double dy = (std::signbit(ya) == std::signbit(yb)) * std::min(std::abs(ya), std::abs(yb));
711
712 return dx*dx + dy*dy;
713 }
714
715 std::size_t hashCode() const;
716
718 // GEOS_DLL bool operator==(const Envelope& a, const Envelope& b);
719 GEOS_DLL friend bool
720 operator==(const Envelope& a, const Envelope& b)
721 {
722 return a.equals(&b);
723 }
724
725 // GEOS_DLL bool operator!=(const Envelope& a, const Envelope& b);
726 GEOS_DLL friend bool
727 operator!=(const Envelope& a, const Envelope& b)
728 {
729 return !(a == b);
730 }
731
734 GEOS_DLL friend bool
735 operator< (const Envelope& a, const Envelope& b);
736
737private:
738
745 static std::vector<std::string> split(const std::string& str,
746 const std::string& delimiters = " ");
747
748 static double distance(double x0, double y0, double x1, double y1)
749 {
750 double dx = x1 - x0;
751 double dy = y1 - y0;
752 return std::sqrt(dx * dx + dy * dy);
753 }
754
756 double minx;
757
759 double maxx;
760
762 double miny;
763
765 double maxy;
766};
767
768
769
770
771} // namespace geos::geom
772} // namespace geos
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:58
double y
y-coordinate
Definition: Coordinate.h:81
double x
x-coordinate
Definition: Coordinate.h:78
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition: Envelope.h:58
double getMinX() const
Returns the Envelope minimum x-value. min x > max x indicates that this is a null Envelope.
Definition: Envelope.h:325
bool intersection(const Envelope &env, Envelope &result) const
Computes the intersection of two Envelopes.
Envelope(const Coordinate &p)
Creates an Envelope for a region defined by a single Coordinate.
Definition: Envelope.h:105
double distanceSquared(const Envelope &env) const
Computes the square of the distance between this and another Envelope.
Definition: Envelope.h:660
bool contains(const Envelope &other) const
Tests if the Envelope other lies wholly inside this Envelope (inclusive of the boundary).
Definition: Envelope.h:490
void expandToInclude(double x, double y)
Enlarges the boundary of the Envelope so that it contains (x,y).
Definition: Envelope.h:417
bool intersects(double x, double y) const
Check if the point (x, y) intersects (lies inside) the region of this Envelope.
Definition: Envelope.h:549
double getDiameter() const
Definition: Envelope.h:336
bool intersects(const Coordinate &a, const Coordinate &b) const
Check if the extent defined by two extremal points intersects the extent of this Envelope.
bool equals(const Envelope *other) const
Returns true if the Envelope other spatially equals this Envelope.
void setToNull()
Makes this Envelope a "null" envelope, that is, the envelope of the empty geometry.
Definition: Envelope.h:237
bool centre(Coordinate &centre) const
Computes the coordinate of the centre of this envelope (as long as it is non-null).
bool covers(double x, double y) const
Tests if the given point lies in or on the envelope.
double distance(const Envelope &env) const
Computes the distance between this and another Envelope.
Definition: Envelope.h:649
void init(const Coordinate &p1, const Coordinate &p2)
Initialize an Envelope to a region defined by two Coordinates.
Definition: Envelope.h:218
double getArea() const
Gets the area of this envelope.
Definition: Envelope.h:286
static double distanceSquaredToCoordinate(const Coordinate &c, const Coordinate &p0, const Coordinate &p1)
Computes the squared distance between one Coordinate and an Envelope defined by two other Coordinates...
Definition: Envelope.h:698
void expandToInclude(const Coordinate &p)
Enlarges the boundary of the Envelope so that it contains p. Does nothing if p is already on or withi...
Definition: Envelope.h:402
void expandBy(double deltaX, double deltaY)
Expands this envelope by a given distance in all directions. Both positive and negative distances are...
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:192
bool contains(double x, double y) const
Returns true if the given point lies in or on the envelope.
Definition: Envelope.h:525
double getHeight() const
Returns the difference between the maximum and minimum y values.
Definition: Envelope.h:271
Envelope()
Creates a null Envelope.
Definition: Envelope.h:69
Envelope(const std::string &str)
Create an Envelope from an Envelope string representation produced by Envelope::toString()
double getWidth() const
Returns the difference between the maximum and minimum x values.
Definition: Envelope.h:258
void init(const Coordinate &p)
Initialize an Envelope to a region defined by a single Coordinate.
Definition: Envelope.h:228
bool intersects(const Coordinate &other) const
Check if the point p intersects (lies inside) the region of this Envelope.
Definition: Envelope.h:536
double getMaxX() const
Returns the Envelope maximum x-value. min x > max x indicates that this is a null Envelope.
Definition: Envelope.h:305
double getMaxY() const
Returns the Envelope maximum y-value. min y > max y indicates that this is a null Envelope.
Definition: Envelope.h:295
static bool intersects(const Coordinate &p1, const Coordinate &p2, const Coordinate &q)
Test the point q to see whether it intersects the Envelope defined by p1-p2.
bool isNull(void) const
Returns true if this Envelope is a "null" envelope.
Definition: Envelope.h:248
Envelope(const Coordinate &p1, const Coordinate &p2)
Creates an Envelope for a region defined by two Coordinates.
Definition: Envelope.h:95
void expandBy(double p_distance)
Expands this envelope by a given distance in all directions.
Definition: Envelope.h:391
void expandToInclude(const Envelope *other)
Enlarges the boundary of the Envelope so that it contains other.
Definition: Envelope.h:448
bool contains(const Coordinate &p) const
Returns true if the given point lies in or on the envelope.
Definition: Envelope.h:509
bool disjoint(const Envelope &other) const
Definition: Envelope.h:580
void init()
Initialize to a null Envelope.
Definition: Envelope.h:179
static double distanceToCoordinate(const Coordinate &c, const Coordinate &p0, const Coordinate &p1)
Computes the distance between one Coordinate and an Envelope defined by two other Coordinates....
Definition: Envelope.h:681
static bool intersects(const Coordinate &p1, const Coordinate &p2, const Coordinate &q1, const Coordinate &q2)
Test the envelope defined by p1-p2 for intersection with the envelope defined by q1-q2.
Definition: Envelope.h:139
friend bool operator==(const Envelope &a, const Envelope &b)
Checks if two Envelopes are equal (2D only check)
Definition: Envelope.h:720
bool covers(const Coordinate *p) const
Tests if the given point lies in or on the envelope.
Definition: Envelope.h:608
std::string toString() const
Returns a string of the form Env[minx:maxx,miny:maxy].
bool intersects(const Envelope *other) const
Check if the region defined by other Envelope intersects the region of this Envelope.
Definition: Envelope.h:560
void translate(double transX, double transY)
Translates this envelope by given amounts in the X and Y direction.
bool covers(const Envelope &other) const
Tests if the Envelope other lies wholly inside this Envelope (inclusive of the boundary).
double getMinY() const
Returns the Envelope minimum y-value. min y > max y indicates that this is a null Envelope.
Definition: Envelope.h:315
Envelope(double x1, double x2, double y1, double y2)
Creates an Envelope for a region defined by maximum and minimum values.
Definition: Envelope.h:84
bool operator<(const Coordinate &a, const Coordinate &b)
Strict weak ordering operator for Coordinate.
Definition: Coordinate.h:245
Basic namespace for all GEOS functionalities.
Definition: geos.h:39