GEOS 3.12.0
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 CoordinateXY& p1, const CoordinateXY& p2)
96 {
97 init(p1, p2);
98 }
99
105 explicit Envelope(const CoordinateXY& p)
106 : minx(p.x)
107 , maxx(p.x)
108 , miny(p.y)
109 , maxy(p.y)
110 {
111 }
112
117 explicit Envelope(const std::string& str);
118
128 static bool intersects(const CoordinateXY& p1, const CoordinateXY& p2,
129 const CoordinateXY& q);
130
142 static bool intersects(
143 const CoordinateXY& p1, const CoordinateXY& p2,
144 const CoordinateXY& q1, const CoordinateXY& q2)
145 {
146 double minq = std::min(q1.x, q2.x);
147 double maxq = std::max(q1.x, q2.x);
148 double minp = std::min(p1.x, p2.x);
149 double maxp = std::max(p1.x, p2.x);
150 if(minp > maxq) {
151 return false;
152 }
153 if(maxp < minq) {
154 return false;
155 }
156 minq = std::min(q1.y, q2.y);
157 maxq = std::max(q1.y, q2.y);
158 minp = std::min(p1.y, p2.y);
159 maxp = std::max(p1.y, p2.y);
160 if(minp > maxq) {
161 return false;
162 }
163 if(maxp < minq) {
164 return false;
165 }
166 return true;
167 }
168
177 bool intersects(const CoordinateXY& a, const CoordinateXY& b) const;
178
182 void init()
183 {
184 setToNull();
185 };
186
195 void init(double x1, double x2, double y1, double y2)
196 {
197 if(x1 < x2) {
198 minx = x1;
199 maxx = x2;
200 }
201 else {
202 minx = x2;
203 maxx = x1;
204 }
205 if(y1 < y2) {
206 miny = y1;
207 maxy = y2;
208 }
209 else {
210 miny = y2;
211 maxy = y1;
212 }
213 };
214
221 void init(const CoordinateXY& p1, const CoordinateXY& p2)
222 {
223 init(p1.x, p2.x, p1.y, p2.y);
224 };
225
231 void init(const CoordinateXY& p)
232 {
233 init(p.x, p.x, p.y, p.y);
234 };
235
241 {
242 minx = maxx = miny = maxy = DoubleNotANumber;
243 };
244
251 bool isNull(void) const
252 {
253 return std::isnan(maxx);
254 };
255
261 double getWidth() const
262 {
263 if(isNull()) {
264 return 0;
265 }
266 return maxx - minx;
267 }
268
274 double getHeight() const
275 {
276 if(isNull()) {
277 return 0;
278 }
279 return maxy - miny;
280 }
281
288 double
289 getArea() const
290 {
291 return getWidth() * getHeight();
292 }
293
297 bool
298 isFinite() const
299 {
300 return std::isfinite(getArea());
301 }
302
307 double getMaxY() const
308 {
309 assert(!isNull());
310 return maxy;
311 };
312
317 double getMaxX() const
318 {
319 assert(!isNull());
320 return maxx;
321 };
322
327 double getMinY() const
328 {
329 assert(!isNull());
330 return miny;
331 };
332
337 double getMinX() const
338 {
339 assert(!isNull());
340 return minx;
341 };
342
348 double getDiameter() const
349 {
350 if (isNull()) {
351 return 0.0;
352 }
353 double w = getWidth();
354 double h = getHeight();
355 return std::sqrt(w*w + h*h);
356 }
357
365 bool centre(CoordinateXY& centre) const;
366
376 bool intersection(const Envelope& env, Envelope& result) const;
377
384 void translate(double transX, double transY);
385
393 void expandBy(double deltaX, double deltaY);
394
402 void
403 expandBy(double p_distance)
404 {
405 expandBy(p_distance, p_distance);
406 };
407
414 void expandToInclude(const CoordinateXY& p)
415 {
416 expandToInclude(p.x, p.y);
417 };
418
429 void expandToInclude(double x, double y)
430 {
431 if(isNull()) {
432 minx = x;
433 maxx = x;
434 miny = y;
435 maxy = y;
436 }
437 else {
438 if(x < minx) {
439 minx = x;
440 }
441 if(x > maxx) {
442 maxx = x;
443 }
444 if(y < miny) {
445 miny = y;
446 }
447 if(y > maxy) {
448 maxy = y;
449 }
450 }
451 };
452
460 void expandToInclude(const Envelope* other)
461 {
462 if(isNull()) {
463 minx = other->minx;
464 maxx = other->maxx;
465 miny = other->miny;
466 maxy = other->maxy;
467 }
468 else {
469 if(std::isless(other->minx, minx)) {
470 minx = other->minx;
471 }
472 if(std::isgreater(other->maxx, maxx)) {
473 maxx = other->maxx;
474 }
475 if(std::isless(other->miny, miny)) {
476 miny = other->miny;
477 }
478 if(std::isgreater(other->maxy, maxy)) {
479 maxy = other->maxy;
480 }
481 }
482 };
483
484 void expandToInclude(const Envelope& other)
485 {
486 return expandToInclude(&other);
487 };
488
501 bool
502 contains(const Envelope& other) const
503 {
504 return covers(other);
505 }
506
507 bool
508 contains(const Envelope* other) const
509 {
510 return contains(*other);
511 }
512
520 bool
521 contains(const CoordinateXY& p) const
522 {
523 return covers(p.x, p.y);
524 }
525
536 bool
537 contains(double x, double y) const
538 {
539 return covers(x, y);
540 }
541
548 bool intersects(const CoordinateXY& other) const
549 {
550 return (std::islessequal(other.x, maxx) && std::isgreaterequal(other.x, minx) &&
551 std::islessequal(other.y, maxy) && std::isgreaterequal(other.y, miny));
552 }
553
561 bool intersects(double x, double y) const
562 {
563 return std::islessequal(x, maxx) &&
564 std::isgreaterequal(x, minx) &&
565 std::islessequal(y, maxy) &&
566 std::isgreaterequal(y, miny);
567 }
568
575 bool intersects(const Envelope* other) const
576 {
577 return std::islessequal(other->minx, maxx) &&
578 std::isgreaterequal(other->maxx, minx) &&
579 std::islessequal(other->miny, maxy) &&
580 std::isgreaterequal(other->maxy, miny);
581 }
582
583 bool intersects(const Envelope& other) const
584 {
585 return intersects(&other);
586 }
587
595 bool disjoint(const Envelope& other) const
596 {
597 return !intersects(other);
598 }
599
600 bool disjoint(const Envelope* other) const
601 {
602 return !intersects(other);
603 }
604
612 bool covers(double x, double y) const {
613 return std::isgreaterequal(x, minx) &&
614 std::islessequal(x, maxx) &&
615 std::isgreaterequal(y, miny) &&
616 std::islessequal(y, maxy);
617 }
618
625 bool covers(const CoordinateXY* p) const
626 {
627 return covers(p->x, p->y);
628 }
629
636 bool covers(const Envelope& other) const;
637
638 bool
639 covers(const Envelope* other) const
640 {
641 return covers(*other);
642 }
643
644
651 bool equals(const Envelope* other) const;
652
658 bool isfinite() const;
659
665 std::string toString() const;
666
673 double distance(const Envelope& env) const
674 {
675 return std::sqrt(distanceSquared(env));
676 }
677
681 double maxDistance(const Envelope& other) const
682 {
683 Coordinate p(std::min(minx, other.minx), std::min(miny, other.miny));
684 Coordinate q(std::max(maxx, other.maxx), std::max(maxy, other.maxy));
685 return p.distance(q);
686 }
687
694 double distanceSquared(const Envelope& env) const
695 {
696 double dx = std::max(0.0,
697 std::max(maxx, env.maxx) - std::min(minx, env.minx) - (maxx - minx) -
698 (env.maxx - env.minx));
699 double dy = std::max(0.0,
700 std::max(maxy, env.maxy) - std::min(miny, env.miny) - (maxy - miny) -
701 (env.maxy - env.miny));
702
703 return dx * dx + dy * dy;
704 };
705
715 static double distanceToCoordinate(
716 const CoordinateXY& c,
717 const CoordinateXY& p0,
718 const CoordinateXY& p1)
719 {
720 return std::sqrt(distanceSquaredToCoordinate(c, p0, p1));
721 };
722
733 const CoordinateXY& c,
734 const CoordinateXY& p0,
735 const CoordinateXY& p1)
736 {
737 double xa = c.x - p0.x;
738 double xb = c.x - p1.x;
739 double ya = c.y - p0.y;
740 double yb = c.y - p1.y;
741
742 // If sign of a and b are not the same, then Envelope spans c and distance is zero.
743 double dx = (std::signbit(xa) == std::signbit(xb)) * std::min(std::abs(xa), std::abs(xb));
744 double dy = (std::signbit(ya) == std::signbit(yb)) * std::min(std::abs(ya), std::abs(yb));
745
746 return dx*dx + dy*dy;
747 }
748
749 std::size_t hashCode() const
750 {
751 auto hash = std::hash<double>{};
752
753 //Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
754 std::size_t result = 17;
755 result = 37 * result + hash(minx);
756 result = 37 * result + hash(maxx);
757 result = 37 * result + hash(miny);
758 result = 37 * result + hash(maxy);
759 return result;
760 }
761
762 struct GEOS_DLL HashCode
763 {
764 std::size_t operator()(const Envelope& e) const
765 {
766 return e.hashCode();
767 };
768 };
769
771 // GEOS_DLL bool operator==(const Envelope& a, const Envelope& b);
772 GEOS_DLL friend bool
773 operator==(const Envelope& a, const Envelope& b)
774 {
775 return a.equals(&b);
776 }
777
778 // GEOS_DLL bool operator!=(const Envelope& a, const Envelope& b);
779 GEOS_DLL friend bool
780 operator!=(const Envelope& a, const Envelope& b)
781 {
782 return !(a == b);
783 }
784
787 GEOS_DLL friend bool
788 operator< (const Envelope& a, const Envelope& b);
789
790private:
791
798 static std::vector<std::string> split(const std::string& str,
799 const std::string& delimiters = " ");
800
801 static double distance(double x0, double y0, double x1, double y1)
802 {
803 double dx = x1 - x0;
804 double dy = y1 - y0;
805 return std::sqrt(dx * dx + dy * dy);
806 }
807
809 double minx;
810
812 double maxx;
813
815 double miny;
816
818 double maxy;
819};
820
821
822
823
824} // namespace geos::geom
825} // namespace geos
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:216
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:337
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:414
bool contains(const CoordinateXY &p) const
Returns true if the given point lies in or on the envelope.
Definition Envelope.h:521
bool intersection(const Envelope &env, Envelope &result) const
Computes the intersection of two Envelopes.
double distanceSquared(const Envelope &env) const
Computes the square of the distance between this and another Envelope.
Definition Envelope.h:694
bool contains(const Envelope &other) const
Tests if the Envelope other lies wholly inside this Envelope (inclusive of the boundary).
Definition Envelope.h:502
void expandToInclude(double x, double y)
Enlarges the boundary of the Envelope so that it contains (x,y).
Definition Envelope.h:429
bool intersects(double x, double y) const
Check if the point (x, y) intersects (lies inside) the region of this Envelope.
Definition Envelope.h:561
bool isfinite() const
double getDiameter() const
Definition Envelope.h:348
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:240
bool covers(double x, double y) const
Tests if the given point lies in or on the envelope.
Definition Envelope.h:612
bool centre(CoordinateXY &centre) const
Computes the coordinate of the centre of this envelope (as long as it is non-null).
double distance(const Envelope &env) const
Computes the distance between this and another Envelope.
Definition Envelope.h:673
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:715
double getArea() const
Gets the area of this envelope.
Definition Envelope.h:289
void init(const CoordinateXY &p1, const CoordinateXY &p2)
Initialize an Envelope to a region defined by two Coordinates.
Definition Envelope.h:221
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:195
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.
bool contains(double x, double y) const
Returns true if the given point lies in or on the envelope.
Definition Envelope.h:537
double getHeight() const
Returns the difference between the maximum and minimum y values.
Definition Envelope.h:274
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()
bool isFinite() const
Returns true if this Envelope covers a finite region.
Definition Envelope.h:298
double getWidth() const
Returns the difference between the maximum and minimum x values.
Definition Envelope.h:261
double getMaxX() const
Returns the Envelope maximum x-value. min x > max x indicates that this is a null Envelope.
Definition Envelope.h:317
bool intersects(const CoordinateXY &a, const CoordinateXY &b) const
Check if the extent defined by two extremal points intersects the extent of this Envelope.
double getMaxY() const
Returns the Envelope maximum y-value. min y > max y indicates that this is a null Envelope.
Definition Envelope.h:307
bool isNull(void) const
Returns true if this Envelope is a "null" envelope.
Definition Envelope.h:251
void init(const CoordinateXY &p)
Initialize an Envelope to a region defined by a single Coordinate.
Definition Envelope.h:231
void expandBy(double p_distance)
Expands this envelope by a given distance in all directions.
Definition Envelope.h:403
bool covers(const CoordinateXY *p) const
Tests if the given point lies in or on the envelope.
Definition Envelope.h:625
void expandToInclude(const Envelope *other)
Enlarges the boundary of the Envelope so that it contains other.
Definition Envelope.h:460
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:142
Envelope(const CoordinateXY &p)
Creates an Envelope for a region defined by a single Coordinate.
Definition Envelope.h:105
bool disjoint(const Envelope &other) const
Definition Envelope.h:595
void init()
Initialize to a null Envelope.
Definition Envelope.h:182
friend bool operator==(const Envelope &a, const Envelope &b)
Checks if two Envelopes are equal (2D only check)
Definition Envelope.h:773
Envelope(const CoordinateXY &p1, const CoordinateXY &p2)
Creates an Envelope for a region defined by two Coordinates.
Definition Envelope.h:95
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:575
bool intersects(const CoordinateXY &other) const
Check if the point p intersects (lies inside) the region of this Envelope.
Definition Envelope.h:548
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:732
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:327
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
double maxDistance(const Envelope &other) const
Computes the maximum distance between points in this and another Envelope.
Definition Envelope.h:681
Basic namespace for all GEOS functionalities.
Definition geos.h:39