LSSTApplications  17.0+11,17.0+113,17.0+64,18.0.0+13,18.0.0+28,18.0.0+5,18.0.0+66,18.0.0-4-g68ffd23,18.1.0-1-g0001055+8,18.1.0-1-g03d53ef+1,18.1.0-1-g1349e88+42,18.1.0-1-g2505f39+33,18.1.0-1-g5315e5e+1,18.1.0-1-g5e4b7ea+10,18.1.0-1-g7e8fceb+1,18.1.0-1-g85f8cd4+35,18.1.0-1-gd55f500+24,18.1.0-12-g42eabe8e+26,18.1.0-14-g259bd21+5,18.1.0-14-gd04256d+31,18.1.0-2-g4903023+9,18.1.0-2-g5f9922c+11,18.1.0-2-gd3b74e5+2,18.1.0-2-gfbf3545+19,18.1.0-2-gfefb8b5+30,18.1.0-20-g4b62d031a,18.1.0-21-gb3d55290+13,18.1.0-22-gcd16eb0+1,18.1.0-3-g52aa583+16,18.1.0-3-g8f4a2b1+29,18.1.0-3-gb69f684+26,18.1.0-4-g1ee41a7+1,18.1.0-5-g6dbcb01+27,18.1.0-5-gc286bb7+3,18.1.0-6-g857e778+2,18.1.0-7-gae09a6d+14,18.1.0-8-g42b2ab3+8,18.1.0-8-gc69d46e+13,18.1.0-9-gee19f03,w.2019.42
LSSTDataManagementBasePackage
Box.h
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2014-2015 AURA/LSST.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 
23 #ifndef LSST_SPHGEOM_BOX_H_
24 #define LSST_SPHGEOM_BOX_H_
25 
29 
30 #include <iosfwd>
31 
32 #include "AngleInterval.h"
33 #include "LonLat.h"
35 #include "Region.h"
36 #include "UnitVector3d.h"
37 
38 
39 namespace lsst {
40 namespace sphgeom {
41 
54 class Box : public Region {
55 public:
56  static constexpr uint8_t TYPE_CODE = 'b';
57 
58  // Factory functions
59  static Box fromDegrees(double lon1, double lat1, double lon2, double lat2) {
60  return Box(NormalizedAngleInterval::fromDegrees(lon1, lon2),
61  AngleInterval::fromDegrees(lat1, lat2));
62  }
63 
64  static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
65  return Box(NormalizedAngleInterval::fromRadians(lon1, lon2),
66  AngleInterval::fromRadians(lat1, lat2));
67  }
68 
69  static Box empty() { return Box(); }
70 
71  static Box full() { return Box(allLongitudes(), allLatitudes()); }
72 
78 
83  }
84 
88  return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
89  }
90 
92  Box() {}
93 
95  explicit Box(LonLat const & p) :
96  _lon(p.getLon()),
97  _lat(p.getLat())
98  {
99  _enforceInvariants();
100  }
101 
105  Box(LonLat const & p1, LonLat const & p2) :
106  _lon(p1.getLon(), p2.getLon()),
107  _lat(p1.getLat(), p2.getLat())
108  {
109  _enforceInvariants();
110  }
111 
114  Box(LonLat const & p, Angle w, Angle h) :
116  _lat(AngleInterval(p.getLat()).dilatedBy(h))
117  {
118  _enforceInvariants();
119  }
120 
123  Box(NormalizedAngleInterval const & lon, AngleInterval const & lat) :
124  _lon(lon),
125  _lat(lat)
126  {
127  _enforceInvariants();
128  }
129 
131  bool operator==(Box const & b) const {
132  return _lon == b._lon && _lat == b._lat;
133  }
134 
135  bool operator!=(Box const & b) const { return !(*this == b); }
136 
138  bool operator==(LonLat const & p) const {
139  return _lat == p.getLat() && _lon == p.getLon();
140  }
141 
142  bool operator!=(LonLat const & p) const { return !(*this == p); }
143 
145  NormalizedAngleInterval const & getLon() const { return _lon; }
146 
148  AngleInterval const & getLat() const { return _lat; }
149 
151  bool isEmpty() const { return _lat.isEmpty(); }
152 
155  bool isFull() const { return _lon.isFull() && _lat == allLatitudes(); }
156 
159  LonLat getCenter() const {
160  return LonLat(_lon.getCenter(), _lat.getCenter());
161  }
162 
165  NormalizedAngle getWidth() const { return _lon.getSize(); }
166 
169  Angle getHeight() const { return _lat.getSize(); }
170 
174  bool contains(LonLat const & x) const {
175  return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
176  }
177 
178  bool contains(Box const & x) const {
179  return _lat.contains(x._lat) && _lon.contains(x._lon);
180  }
182 
186  bool isDisjointFrom(LonLat const & x) const { return !intersects(x); }
187 
188  bool isDisjointFrom(Box const & x) const { return !intersects(x); }
190 
194  bool intersects(LonLat const & x) const {
195  return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
196  }
197 
198  bool intersects(Box const & x) const {
199  return _lat.intersects(x._lat) && _lon.intersects(x._lon);
200  }
202 
206  bool isWithin(LonLat const & x) const {
207  return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
208  }
209 
210  bool isWithin(Box const & x) const {
211  return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
212  }
214 
217  Box & clipTo(LonLat const & x) {
218  _lon.clipTo(x.getLon());
219  _lat.clipTo(x.getLat());
220  _enforceInvariants();
221  return *this;
222  }
223 
227  Box & clipTo(Box const & x) {
228  _lon.clipTo(x.getLon());
229  _lat.clipTo(x.getLat());
230  _enforceInvariants();
231  return *this;
232  }
233 
235  Box clippedTo(LonLat const & x) const { return Box(*this).clipTo(x); }
236 
240  Box clippedTo(Box const & x) const { return Box(*this).clipTo(x); }
241 
246  Box & expandTo(LonLat const & x) {
247  _lon.expandTo(x.getLon());
248  _lat.expandTo(x.getLat());
249  return *this;
250  }
251 
252  Box & expandTo(Box const & x) {
253  _lon.expandTo(x.getLon());
254  _lat.expandTo(x.getLat());
255  return *this;
256  }
258 
263  Box expandedTo(LonLat const & x) const { return Box(*this).expandTo(x); }
264  Box expandedTo(Box const & x) const { return Box(*this).expandTo(x); }
266 
272  Box & dilateBy(Angle r);
273  Box dilatedBy(Angle r) const { return Box(*this).dilateBy(r); }
274 
290  Box & dilateBy(Angle w, Angle h);
291  Box dilatedBy(Angle w, Angle h) const { return Box(*this).dilateBy(w, h); }
292  Box & erodeBy(Angle r) { return dilateBy(-r); }
293  Box & erodeBy(Angle w, Angle h) { return dilateBy(-w, -h); }
294  Box erodedBy(Angle r) const { return dilatedBy(-r); }
295  Box erodedBy(Angle w, Angle h) const { return dilatedBy(-w, -h); }
296 
297  Relationship relate(LonLat const & p) const { return relate(Box(p)); }
298 
300  double getArea() const;
301 
302  // Region interface
303  std::unique_ptr<Region> clone() const override {
304  return std::unique_ptr<Box>(new Box(*this));
305  }
306 
307  Box getBoundingBox() const override { return *this; }
308  Box3d getBoundingBox3d() const override;
309  Circle getBoundingCircle() const override;
310 
311  bool contains(UnitVector3d const & v) const override {
312  return contains(LonLat(v));
313  }
314 
315  Relationship relate(Region const & r) const override {
316  // Dispatch on the type of r.
317  return invert(r.relate(*this));
318  }
319 
320  Relationship relate(Box const & b) const override {
321  Relationship r1 = _lon.relate(b._lon);
322  Relationship r2 = _lat.relate(b._lat);
323  // If the box longitude or latitude intervals are disjoint, then the
324  // boxes are disjoint. The other spatial relationships must hold for
325  // both the longitude and latitude intervals in order to hold for the
326  // boxes.
327  return ((r1 & r2) & (CONTAINS | WITHIN)) | ((r1 | r2) & DISJOINT);
328  }
329 
330  Relationship relate(Circle const &) const override;
331  Relationship relate(ConvexPolygon const &) const override;
332  Relationship relate(Ellipse const &) const override;
333 
334  std::vector<uint8_t> encode() const override;
335 
339  return decode(s.data(), s.size());
340  }
341  static std::unique_ptr<Box> decode(uint8_t const * buffer, size_t n);
343 
344 private:
345  static constexpr size_t ENCODED_SIZE = 33;
346 
347  void _enforceInvariants() {
348  // Make sure that _lat ⊆ [-π/2, π/2].
349  _lat.clipTo(allLatitudes());
350  // Make sure that both longitude and latitude intervals are
351  // empty, or neither is. This simplifies the implementation
352  // of the spatial relation tests.
353  if (_lat.isEmpty()) {
354  _lon = NormalizedAngleInterval();
355  } else if (_lon.isEmpty()) {
356  _lat = AngleInterval();
357  }
358  }
359 
361  AngleInterval _lat;
362 };
363 
365 
366 }} // namespace lsst::sphgeom
367 
368 #endif // LSST_SPHGEOM_BOX_H_
std::unique_ptr< Region > clone() const override
clone returns a deep copy of this region.
Definition: Box.h:303
static constexpr uint8_t TYPE_CODE
Definition: Box.h:56
Box & expandTo(LonLat const &x)
Definition: Box.h:246
bool isEmpty() const
isEmpty returns true if this interval does not contain any normalized angles.
static NormalizedAngleInterval allLongitudes()
allLongitudes returns a normalized angle interval containing all valid longitude angles.
Definition: Box.h:81
Box()
This constructor creates an empty box.
Definition: Box.h:92
Box expandedTo(Box const &x) const
Definition: Box.h:264
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
Definition: Box.h:307
static AngleInterval fromDegrees(double x, double y)
Definition: AngleInterval.h:43
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition: Box.h:311
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...
Angle getHeight() const
getHeight returns the height in latitude angle of this box.
Definition: Box.h:169
Box erodedBy(Angle w, Angle h) const
Definition: Box.h:295
static Box fromRadians(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:64
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition: Box.h:165
Angle getLat() const
Definition: LonLat.h:90
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:39
Box & erodeBy(Angle w, Angle h)
Definition: Box.h:293
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
Definition: Box.cc:447
table::Key< int > b
NormalizedAngleInterval & expandTo(NormalizedAngle x)
Interval & clipTo(Scalar x)
Definition: Interval.h:159
static NormalizedAngleInterval fromRadians(double a, double b)
Box(LonLat const &p)
This constructor creates a box containing a single point.
Definition: Box.h:95
static AngleInterval fromRadians(double x, double y)
Definition: AngleInterval.h:48
std::ostream & operator<<(std::ostream &, Angle const &)
Definition: Angle.cc:34
bool isWithin(Scalar x) const
Definition: Interval.h:140
static NormalizedAngleInterval fromDegrees(double a, double b)
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55
Scalar getCenter() const
getCenter returns the center of this interval.
Definition: Interval.h:89
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
This constructor creates a box spanning the given longitude and latitude intervals.
Definition: Box.h:123
static Box full()
Definition: Box.h:71
bool isDisjointFrom(LonLat const &x) const
Definition: Box.h:186
NormalizedAngle getLon() const
Definition: LonLat.h:88
bool isFull() const
isFull returns true if this interval contains all normalized angles.
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition: Box.h:54
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition: Box.cc:78
Scalar getSize() const
getSize returns the size (length, width) of this interval.
Definition: Interval.h:93
Box(LonLat const &p1, LonLat const &p2)
This constructor creates a box spanning the longitude interval [p1.getLon(), p2.getLon()] and latitud...
Definition: Box.h:105
Relationship relate(LonLat const &p) const
Definition: Box.h:297
This file declares a class for representing unit vectors in ℝ³.
static Box fromDegrees(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:59
Ellipse is an elliptical region on the sphere.
Definition: Ellipse.h:169
bool intersects(LonLat const &x) const
Definition: Box.h:194
bool contains(Box const &x) const
Definition: Box.h:178
Box dilatedBy(Angle r) const
Definition: Box.h:273
T data(T... args)
Relationship relate(Scalar x) const
Definition: Interval.h:249
A base class for image defects.
This file defines an interface for spherical regions.
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
static AngleInterval allLatitudes()
allLatitudes returns an angle interval containing all valid latitude angles.
Definition: Box.h:87
Box(LonLat const &p, Angle w, Angle h)
This constructor creates a box with center p, half-width (in longitude angle) w and half-height (in l...
Definition: Box.h:114
Region is a minimal interface for 2-dimensional regions on the unit sphere.
Definition: Region.h:79
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition: Box.h:145
Box clippedTo(LonLat const &x) const
clippedTo returns the intersection of this box and x.
Definition: Box.h:235
constexpr double PI
Definition: constants.h:36
static Box empty()
Definition: Box.h:69
Interval & expandTo(Scalar x)
Definition: Interval.h:192
Box & clipTo(LonLat const &x)
clipTo shrinks this box until it contains only x.
Definition: Box.h:217
virtual Relationship relate(Region const &) const =0
Relationship relate(NormalizedAngle x) const
NormalizedAngleInterval represents closed intervals of normalized angles, i.e.
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
Definition: Box.cc:127
bool isWithin(LonLat const &x) const
Definition: Box.h:206
bool isEmpty() const
isEmpty returns true if this interval does not contain any points.
Definition: Interval.h:83
bool contains(LonLat const &x) const
Definition: Box.h:174
double x
This file declares a class representing closed intervals of normalized angles, i.e.
Circle is a circular region on the unit sphere that contains its boundary.
Definition: Circle.h:46
ConvexPolygon is a closed convex polygon on the unit sphere.
Definition: ConvexPolygon.h:57
bool operator!=(Box const &b) const
Definition: Box.h:135
double w
Definition: CoaddPsf.cc:69
bool operator==(LonLat const &p) const
A box is equal to a point p if it contains only p.
Definition: Box.h:138
static NormalizedAngleInterval full()
bool operator!=(LonLat const &p) const
Definition: Box.h:142
T size(T... args)
LonLat getCenter() const
getCenter returns the center of this box.
Definition: Box.h:159
STL class.
This file defines a class for representing angle intervals.
bool isDisjointFrom(Box const &x) const
Definition: Box.h:188
Box & clipTo(Box const &x)
x.clipTo(y) sets x to the smallest box containing the intersection of x and y.
Definition: Box.h:227
STL class.
Angle represents an angle in radians.
Definition: Angle.h:43
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition: Box.h:148
NormalizedAngleInterval & clipTo(NormalizedAngle x)
clipTo shrinks this interval until all its points are in x.
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition: LonLat.h:48
bool intersects(Box const &x) const
Definition: Box.h:198
Box & expandTo(Box const &x)
Definition: Box.h:252
Box clippedTo(Box const &x) const
clippedTo returns the smallest box containing the intersection of this box and x. ...
Definition: Box.h:240
Box3d represents a box in ℝ³.
Definition: Box3d.h:42
bool operator==(Box const &b) const
Two boxes are equal if they contain the same points.
Definition: Box.h:131
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at...
Definition: Box.cc:43
bool contains(Scalar x) const
Definition: Interval.h:98
lsst::geom::Angle Angle
Definition: misc.h:33
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
Definition: UnitVector3d.h:55
Relationship relate(Region const &r) const override
Definition: Box.h:315
double getArea() const
getArea returns the area of this box in steradians.
Definition: Box.cc:115
Box erodedBy(Angle r) const
Definition: Box.h:294
NormalizedAngle getCenter() const
getCenter returns the center of this interval.
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition: Box.h:155
bool isWithin(Box const &x) const
Definition: Box.h:210
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition: Box.cc:187
Relationship relate(Box const &b) const override
Definition: Box.h:320
Box dilatedBy(Angle w, Angle h) const
Definition: Box.h:291
STL class.
This file contains a class representing spherical coordinates.
STL class.
Box expandedTo(LonLat const &x) const
Definition: Box.h:263
NormalizedAngle getSize() const
getSize returns the size (length, width) of this interval.
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition: Box.h:338
bool intersects(Scalar x) const
Definition: Interval.h:130
Box & erodeBy(Angle r)
Definition: Box.h:292