GEOS  3.11.0beta2
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 
32 namespace geos {
33 namespace geom { // geos::geom
34 
35 class Envelope;
36 
38 GEOS_DLL std::ostream& operator<< (std::ostream& os, const Envelope& o);
39 
40 class Coordinate;
41 
58 class GEOS_DLL Envelope {
59 
60 public:
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 
237  void setToNull()
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 
737 private:
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: Angle.h:25