Coverage Report

Created: 2026-11-10 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/s2geometry/src/s2/s2region.h
Line
Count
Source
1
// Copyright 2005 Google Inc. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
16
// Author: ericv@google.com (Eric Veach)
17
18
#ifndef S2_S2REGION_H_
19
#define S2_S2REGION_H_
20
21
#include <vector>
22
23
#include "s2/_fp_contract_off.h"  // IWYU pragma: keep
24
#include "s2/s1angle.h"
25
#include "s2/s2point.h"
26
27
class S2Cap;
28
class S2Cell;
29
class S2CellId;
30
class S2LatLngRect;
31
32
// An S2Region represents a two-dimensional region over the unit sphere.
33
// It is an abstract interface with various concrete subtypes.
34
//
35
// The main purpose of this interface is to allow complex regions to be
36
// approximated as simpler regions.  So rather than having a wide variety
37
// of virtual methods that are implemented by all subtypes, the interface
38
// is restricted to methods that are useful for computing approximations.
39
class S2Region {
40
 public:
41
0
  virtual ~S2Region() = default;
42
43
  // Returns a copy of the region.  Owned data is deep-copied, while
44
  // references to external data are not.  Therefore if the region depends
45
  // on the lifetime of external objects, the copy shares that dependency.
46
  //
47
  // Note that the return type is S2Region*, but the actual object returned
48
  // is of the same type as the object being cloned.
49
  virtual S2Region* Clone() const = 0;
50
51
  // Returns a bounding spherical cap that contains the region.  The bound may
52
  // not be tight.
53
  virtual S2Cap GetCapBound() const = 0;
54
55
  // Returns a bounding latitude-longitude rectangle that contains the region.
56
  // The bound may not be tight.
57
  virtual S2LatLngRect GetRectBound() const = 0;
58
59
  // Returns a small collection of S2CellIds whose union covers the region.
60
  // The cells are not sorted, may have redundancies (such as cells that
61
  // contain other cells), and may cover much more area than necessary.
62
  //
63
  // This method is not intended for direct use by client code.  Clients
64
  // should typically use S2RegionCoverer::GetCovering, which has options to
65
  // control the size and accuracy of the covering.  Alternatively, if you
66
  // want a fast covering and don't care about accuracy, consider calling
67
  // S2RegionCoverer::GetFastCovering (which returns a cleaned-up version of
68
  // the covering computed by this method).
69
  //
70
  // GetCellUnionBound() implementations should attempt to return a small
71
  // covering (ideally 4 cells or fewer) that covers the region and can be
72
  // computed quickly.  The result is used by S2RegionCoverer as a starting
73
  // point for further refinement.
74
  //
75
  // `GetCapBound().GetCellUnionBound(cell_ids)` and
76
  // `GetRectBound().GetCellUnionBound(cell_ids)` are always valid
77
  // implementations, but something better should be done if possible.
78
  virtual void GetCellUnionBound(std::vector<S2CellId>* cell_ids) const = 0;
79
80
  // Returns true if the region completely contains the given cell, otherwise
81
  // either the region does not contain the cell or the containment relationship
82
  // could not be determined.
83
  virtual bool Contains(const S2Cell& cell) const = 0;
84
85
  // If this method returns false, the region does not intersect the given
86
  // cell.  Otherwise, either the region intersects the cell, or the
87
  // intersection relationship could not be determined.
88
  //
89
  // Note that there is currently exactly one implementation of this method
90
  // (S2LatLngRect::MayIntersect) that takes advantage of the semantics above
91
  // to be more efficient.  For all other S2Region subtypes, this method
92
  // returns true if the region intersect the cell and false otherwise.
93
  virtual bool MayIntersect(const S2Cell& cell) const = 0;
94
95
  // Returns true if and only if the given point is contained by the region.
96
  // The point 'p' is generally required to be unit length, although some
97
  // subtypes may relax this restriction.
98
  virtual bool Contains(const S2Point& p) const = 0;
99
100
  //////////////////////////////////////////////////////////////////////////
101
  // Many S2Region subtypes also define the following non-virtual methods.
102
  //////////////////////////////////////////////////////////////////////////
103
104
  // Appends a serialized representation of the region to "encoder".
105
  //
106
  // The representation chosen is left up to the sub-classes but it should
107
  // satisfy the following constraints:
108
  // - It should encode a version number.
109
  // - It should be deserializable using the corresponding Decode method.
110
  // - Performance, not space, should be the chief consideration. Encode() and
111
  //   Decode() should be implemented such that the combination is equivalent
112
  //   to calling Clone().
113
  //
114
  // REQUIRES: "encoder" uses the default constructor, so that its buffer
115
  //           can be enlarged as necessary by calling Ensure(int).
116
  //
117
  // void Encode(Encoder* encoder) const;
118
119
  // Decodes an S2Region encoded with Encode().  Note that this method
120
  // requires that an S2Region object of the appropriate concrete type has
121
  // already been constructed.  It is not possible to decode regions of
122
  // unknown type.
123
  //
124
  // Whenever the Decode method is changed to deal with new serialized
125
  // representations, it should be done so in a manner that allows for
126
  // older versions to be decoded i.e. the version number in the serialized
127
  // representation should be used to decide how to decode the data.
128
  //
129
  // Returns true on success.
130
  //
131
  // bool Decode(Decoder* decoder);
132
133
 protected:
134
0
  S2Region() = default;
135
  // Allow derived classes to define copy/move.  They may assume S2Region has
136
  // no members.  Default the move assign/constructor as well so derived
137
  // classes can default their constructors/assignment operator.
138
0
  S2Region(const S2Region&) noexcept = default;
139
0
  S2Region(S2Region&&) noexcept = default;
140
0
  S2Region& operator=(const S2Region&) = default;
141
0
  S2Region& operator=(S2Region&&) = default;
142
};
143
144
#endif  // S2_S2REGION_H_