1 | // Copyright 2005 Google Inc. All Rights Reserved. |
2 | |
3 | #ifndef UTIL_GEOMETRY_S2CELLID_H_ |
4 | #define UTIL_GEOMETRY_S2CELLID_H_ |
5 | |
6 | #include <iostream> |
7 | using std::ostream; |
8 | using std::cout; |
9 | using std::endl; |
10 | |
11 | #include <string> |
12 | using std::string; |
13 | |
14 | #include <vector> |
15 | using std::vector; |
16 | |
17 | #include "base/basictypes.h" |
18 | #include "base/logging.h" |
19 | #include "base/port.h" // for HASH_NAMESPACE_DECLARATION_START |
20 | #include "s2.h" |
21 | #include "util/math/vector2.h" |
22 | |
23 | class S2LatLng; |
24 | |
25 | // An S2CellId is a 64-bit unsigned integer that uniquely identifies a |
26 | // cell in the S2 cell decomposition. It has the following format: |
27 | // |
28 | // id = [face][face_pos] |
29 | // |
30 | // face: a 3-bit number (range 0..5) encoding the cube face. |
31 | // |
32 | // face_pos: a 61-bit number encoding the position of the center of this |
33 | // cell along the Hilbert curve over this face (see the Wiki |
34 | // pages for details). |
35 | // |
36 | // Sequentially increasing cell ids follow a continuous space-filling curve |
37 | // over the entire sphere. They have the following properties: |
38 | // |
39 | // - The id of a cell at level k consists of a 3-bit face number followed |
40 | // by k bit pairs that recursively select one of the four children of |
41 | // each cell. The next bit is always 1, and all other bits are 0. |
42 | // Therefore, the level of a cell is determined by the position of its |
43 | // lowest-numbered bit that is turned on (for a cell at level k, this |
44 | // position is 2 * (kMaxLevel - k).) |
45 | // |
46 | // - The id of a parent cell is at the midpoint of the range of ids spanned |
47 | // by its children (or by its descendants at any level). |
48 | // |
49 | // Leaf cells are often used to represent points on the unit sphere, and |
50 | // this class provides methods for converting directly between these two |
51 | // representations. For cells that represent 2D regions rather than |
52 | // discrete point, it is better to use the S2Cell class. |
53 | // |
54 | // This class is intended to be copied by value as desired. It uses |
55 | // the default copy constructor and assignment operator. |
56 | class S2CellId { |
57 | public: |
58 | // Although only 60 bits are needed to represent the index of a leaf |
59 | // cell, we need an extra bit in order to represent the position of |
60 | // the center of the leaf cell along the Hilbert curve. |
61 | static int const kFaceBits = 3; |
62 | static int const kNumFaces = 6; |
63 | static int const kMaxLevel = S2::kMaxCellLevel; // Valid levels: 0..kMaxLevel |
64 | static int const kPosBits = 2 * kMaxLevel + 1; |
65 | static int const kMaxSize = 1 << kMaxLevel; |
66 | |
67 | inline explicit S2CellId(uint64 id) : id_(id) {} |
68 | |
69 | // The default constructor returns an invalid cell id. |
70 | inline S2CellId() : id_(0) {} |
71 | inline static S2CellId None() { return S2CellId(); } |
72 | |
73 | // Returns an invalid cell id guaranteed to be larger than any |
74 | // valid cell id. Useful for creating indexes. |
75 | inline static S2CellId Sentinel() { return S2CellId(~uint64(0)); } |
76 | |
77 | // Return a cell given its face (range 0..5), 61-bit Hilbert curve position |
78 | // within that face, and level (range 0..kMaxLevel). The given position |
79 | // will be modified to correspond to the Hilbert curve position at the |
80 | // center of the returned cell. This is a static function rather than a |
81 | // constructor in order to give names to the arguments. |
82 | static S2CellId FromFacePosLevel(int face, uint64 pos, int level); |
83 | |
84 | // Return the leaf cell containing the given point (a direction |
85 | // vector, not necessarily unit length). |
86 | static S2CellId FromPoint(S2Point const& p); |
87 | |
88 | // Return the leaf cell containing the given normalized S2LatLng. |
89 | static S2CellId FromLatLng(S2LatLng const& ll); |
90 | |
91 | // Return the direction vector corresponding to the center of the given |
92 | // cell. The vector returned by ToPointRaw is not necessarily unit length. |
93 | S2Point ToPoint() const { return ToPointRaw().Normalize(); } |
94 | S2Point ToPointRaw() const; |
95 | |
96 | // Return the center of the cell in (s,t) coordinates (see s2.h). |
97 | Vector2_d GetCenterST() const; |
98 | |
99 | // Return the center of the cell in (u,v) coordinates (see s2.h). Note that |
100 | // the center of the cell is defined as the point at which it is recursively |
101 | // subdivided into four children; in general, it is not at the midpoint of |
102 | // the (u,v) rectangle covered by the cell. |
103 | Vector2_d GetCenterUV() const; |
104 | |
105 | // Return the S2LatLng corresponding to the center of the given cell. |
106 | S2LatLng ToLatLng() const; |
107 | |
108 | // The 64-bit unique identifier for this cell. |
109 | inline uint64 id() const { return id_; } |
110 | |
111 | // Return true if id() represents a valid cell. |
112 | inline bool is_valid() const; |
113 | |
114 | // Which cube face this cell belongs to, in the range 0..5. |
115 | inline int face() const; |
116 | |
117 | // The position of the cell center along the Hilbert curve over this face, |
118 | // in the range 0..(2**kPosBits-1). |
119 | inline uint64 pos() const; |
120 | |
121 | // Return the subdivision level of the cell (range 0..kMaxLevel). |
122 | int level() const; |
123 | |
124 | // Return the edge length of this cell in (i,j)-space. |
125 | inline int GetSizeIJ() const; |
126 | |
127 | // Return the edge length of this cell in (s,t)-space. |
128 | inline double GetSizeST() const; |
129 | |
130 | // Like the above, but return the size of cells at the given level. |
131 | inline static int GetSizeIJ(int level); |
132 | inline static double GetSizeST(int level); |
133 | |
134 | // Return true if this is a leaf cell (more efficient than checking |
135 | // whether level() == kMaxLevel). |
136 | inline bool is_leaf() const; |
137 | |
138 | // Return true if this is a top-level face cell (more efficient than |
139 | // checking whether level() == 0). |
140 | inline bool is_face() const; |
141 | |
142 | // Return the child position (0..3) of this cell's ancestor at the given |
143 | // level, relative to its parent. The argument should be in the range |
144 | // 1..kMaxLevel. For example, child_position(1) returns the position of |
145 | // this cell's level-1 ancestor within its top-level face cell. |
146 | inline int child_position(int level) const; |
147 | |
148 | // Methods that return the range of cell ids that are contained |
149 | // within this cell (including itself). The range is *inclusive* |
150 | // (i.e. test using >= and <=) and the return values of both |
151 | // methods are valid leaf cell ids. |
152 | // |
153 | // These methods should not be used for iteration. If you want to |
154 | // iterate through all the leaf cells, call child_begin(kMaxLevel) and |
155 | // child_end(kMaxLevel) instead. |
156 | // |
157 | // It would in fact be error-prone to define a range_end() method, |
158 | // because (range_max().id() + 1) is not always a valid cell id, and the |
159 | // iterator would need to be tested using "<" rather that the usual "!=". |
160 | inline S2CellId range_min() const; |
161 | inline S2CellId range_max() const; |
162 | |
163 | // Return true if the given cell is contained within this one. |
164 | inline bool contains(S2CellId const& other) const; |
165 | |
166 | // Return true if the given cell intersects this one. |
167 | inline bool intersects(S2CellId const& other) const; |
168 | |
169 | // Return the cell at the previous level or at the given level (which must |
170 | // be less than or equal to the current level). |
171 | inline S2CellId parent() const; |
172 | inline S2CellId parent(int level) const; |
173 | |
174 | // Return the immediate child of this cell at the given traversal order |
175 | // position (in the range 0 to 3). This cell must not be a leaf cell. |
176 | inline S2CellId child(int position) const; |
177 | |
178 | // Iterator-style methods for traversing the immediate children of a cell or |
179 | // all of the children at a given level (greater than or equal to the current |
180 | // level). Note that the end value is exclusive, just like standard STL |
181 | // iterators, and may not even be a valid cell id. You should iterate using |
182 | // code like this: |
183 | // |
184 | // for(S2CellId c = id.child_begin(); c != id.child_end(); c = c.next()) |
185 | // ... |
186 | // |
187 | // The convention for advancing the iterator is "c = c.next()" rather |
188 | // than "++c" to avoid possible confusion with incrementing the |
189 | // underlying 64-bit cell id. |
190 | inline S2CellId child_begin() const; |
191 | inline S2CellId child_begin(int level) const; |
192 | inline S2CellId child_end() const; |
193 | inline S2CellId child_end(int level) const; |
194 | |
195 | // Return the next/previous cell at the same level along the Hilbert curve. |
196 | // Works correctly when advancing from one face to the next, but |
197 | // does *not* wrap around from the last face to the first or vice versa. |
198 | inline S2CellId next() const; |
199 | inline S2CellId prev() const; |
200 | |
201 | // This method advances or retreats the indicated number of steps along the |
202 | // Hilbert curve at the current level, and returns the new position. The |
203 | // position is never advanced past End() or before Begin(). |
204 | S2CellId advance(int64 steps) const; |
205 | |
206 | // Like next() and prev(), but these methods wrap around from the last face |
207 | // to the first and vice versa. They should *not* be used for iteration in |
208 | // conjunction with child_begin(), child_end(), Begin(), or End(). The |
209 | // input must be a valid cell id. |
210 | inline S2CellId next_wrap() const; |
211 | inline S2CellId prev_wrap() const; |
212 | |
213 | // This method advances or retreats the indicated number of steps along the |
214 | // Hilbert curve at the current level, and returns the new position. The |
215 | // position wraps between the first and last faces as necessary. The input |
216 | // must be a valid cell id. |
217 | S2CellId advance_wrap(int64 steps) const; |
218 | |
219 | // Iterator-style methods for traversing all the cells along the Hilbert |
220 | // curve at a given level (across all 6 faces of the cube). Note that the |
221 | // end value is exclusive (just like standard STL iterators), and is not a |
222 | // valid cell id. |
223 | inline static S2CellId Begin(int level); |
224 | inline static S2CellId End(int level); |
225 | |
226 | // Methods to encode and decode cell ids to compact text strings suitable |
227 | // for display or indexing. Cells at lower levels (i.e. larger cells) are |
228 | // encoded into fewer characters. The maximum token length is 16. |
229 | // |
230 | // ToToken() returns a string by value for convenience; the compiler |
231 | // does this without intermediate copying in most cases. |
232 | // |
233 | // These methods guarantee that FromToken(ToToken(x)) == x even when |
234 | // "x" is an invalid cell id. All tokens are alphanumeric strings. |
235 | // FromToken() returns S2CellId::None() for malformed inputs. |
236 | string ToToken() const; |
237 | static S2CellId FromToken(string const& token); |
238 | |
239 | // Creates a debug human readable string. Used for << and available for direct |
240 | // usage as well. |
241 | string ToString() const; |
242 | |
243 | // Return the four cells that are adjacent across the cell's four edges. |
244 | // Neighbors are returned in the order defined by S2Cell::GetEdge. All |
245 | // neighbors are guaranteed to be distinct. |
246 | void GetEdgeNeighbors(S2CellId neighbors[4]) const; |
247 | |
248 | // Return the neighbors of closest vertex to this cell at the given level, |
249 | // by appending them to "output". Normally there are four neighbors, but |
250 | // the closest vertex may only have three neighbors if it is one of the 8 |
251 | // cube vertices. |
252 | // |
253 | // Requires: level < this->level(), so that we can determine which vertex is |
254 | // closest (in particular, level == kMaxLevel is not allowed). |
255 | void AppendVertexNeighbors(int level, vector<S2CellId>* output) const; |
256 | |
257 | // Append all neighbors of this cell at the given level to "output". Two |
258 | // cells X and Y are neighbors if their boundaries intersect but their |
259 | // interiors do not. In particular, two cells that intersect at a single |
260 | // point are neighbors. |
261 | // |
262 | // Requires: nbr_level >= this->level(). Note that for cells adjacent to a |
263 | // face vertex, the same neighbor may be appended more than once. |
264 | void AppendAllNeighbors(int nbr_level, vector<S2CellId>* output) const; |
265 | |
266 | ///////////////////////////////////////////////////////////////////// |
267 | // Low-level methods. |
268 | |
269 | // Return a leaf cell given its cube face (range 0..5) and |
270 | // i- and j-coordinates (see s2.h). |
271 | static S2CellId FromFaceIJ(int face, int i, int j); |
272 | |
273 | // Return the (face, i, j) coordinates for the leaf cell corresponding to |
274 | // this cell id. Since cells are represented by the Hilbert curve position |
275 | // at the center of the cell, the returned (i,j) for non-leaf cells will be |
276 | // a leaf cell adjacent to the cell center. If "orientation" is non-NULL, |
277 | // also return the Hilbert curve orientation for the current cell. |
278 | int ToFaceIJOrientation(int* pi, int* pj, int* orientation) const; |
279 | |
280 | // Return the lowest-numbered bit that is on for this cell id, which is |
281 | // equal to (uint64(1) << (2 * (kMaxLevel - level))). So for example, |
282 | // a.lsb() <= b.lsb() if and only if a.level() >= b.level(), but the |
283 | // first test is more efficient. |
284 | uint64 lsb() const { return id_ & -id_; } |
285 | |
286 | // Return the lowest-numbered bit that is on for cells at the given level. |
287 | inline static uint64 lsb_for_level(int level) { |
288 | return uint64(1) << (2 * (kMaxLevel - level)); |
289 | } |
290 | |
291 | private: |
292 | // This is the offset required to wrap around from the beginning of the |
293 | // Hilbert curve to the end or vice versa; see next_wrap() and prev_wrap(). |
294 | static uint64 const kWrapOffset = uint64(kNumFaces) << kPosBits; |
295 | |
296 | // Return the i- or j-index of the leaf cell containing the given |
297 | // s- or t-value. Values are clamped appropriately. |
298 | inline static int STtoIJ(double s); |
299 | |
300 | // Return the (face, si, ti) coordinates of the center of the cell. Note |
301 | // that although (si,ti) coordinates span the range [0,2**31] in general, |
302 | // the cell center coordinates are always in the range [1,2**31-1] and |
303 | // therefore can be represented using a signed 32-bit integer. |
304 | inline int GetCenterSiTi(int* psi, int* pti) const; |
305 | |
306 | // Given (i, j) coordinates that may be out of bounds, normalize them by |
307 | // returning the corresponding neighbor cell on an adjacent face. |
308 | static S2CellId FromFaceIJWrap(int face, int i, int j); |
309 | |
310 | // Inline helper function that calls FromFaceIJ if "same_face" is true, |
311 | // or FromFaceIJWrap if "same_face" is false. |
312 | inline static S2CellId FromFaceIJSame(int face, int i, int j, bool same_face); |
313 | |
314 | uint64 id_; |
315 | } PACKED; // Necessary so that structures containing S2CellId's can be PACKED. |
316 | DECLARE_POD(S2CellId); |
317 | |
318 | inline bool operator==(S2CellId const& x, S2CellId const& y) { |
319 | return x.id() == y.id(); |
320 | } |
321 | |
322 | inline bool operator!=(S2CellId const& x, S2CellId const& y) { |
323 | return x.id() != y.id(); |
324 | } |
325 | |
326 | inline bool operator<(S2CellId const& x, S2CellId const& y) { |
327 | return x.id() < y.id(); |
328 | } |
329 | |
330 | inline bool operator>(S2CellId const& x, S2CellId const& y) { |
331 | return x.id() > y.id(); |
332 | } |
333 | |
334 | inline bool operator<=(S2CellId const& x, S2CellId const& y) { |
335 | return x.id() <= y.id(); |
336 | } |
337 | |
338 | inline bool operator>=(S2CellId const& x, S2CellId const& y) { |
339 | return x.id() >= y.id(); |
340 | } |
341 | |
342 | inline bool S2CellId::is_valid() const { |
343 | return (face() < kNumFaces && (lsb() & GG_ULONGLONG(0x1555555555555555))); |
344 | } |
345 | |
346 | inline int S2CellId::face() const { |
347 | return id_ >> kPosBits; |
348 | } |
349 | |
350 | inline uint64 S2CellId::pos() const { |
351 | return id_ & (~uint64(0) >> kFaceBits); |
352 | } |
353 | |
354 | inline int S2CellId::GetSizeIJ() const { |
355 | return GetSizeIJ(level()); |
356 | } |
357 | |
358 | inline double S2CellId::GetSizeST() const { |
359 | return GetSizeST(level()); |
360 | } |
361 | |
362 | inline int S2CellId::GetSizeIJ(int level) { |
363 | return 1 << (kMaxLevel - level); |
364 | } |
365 | |
366 | inline double S2CellId::GetSizeST(int level) { |
367 | // Floating-point multiplication is much faster than division. |
368 | return GetSizeIJ(level) * (1.0 / kMaxSize); |
369 | } |
370 | |
371 | inline bool S2CellId::is_leaf() const { |
372 | return int(id_) & 1; |
373 | } |
374 | |
375 | inline bool S2CellId::is_face() const { |
376 | return (id_ & (lsb_for_level(0) - 1)) == 0; |
377 | } |
378 | |
379 | inline int S2CellId::child_position(int level) const { |
380 | DCHECK(is_valid()); |
381 | return static_cast<int>(id_ >> (2 * (kMaxLevel - level) + 1)) & 3; |
382 | } |
383 | |
384 | inline S2CellId S2CellId::range_min() const { |
385 | return S2CellId(id_ - (lsb() - 1)); |
386 | } |
387 | |
388 | inline S2CellId S2CellId::range_max() const { |
389 | return S2CellId(id_ + (lsb() - 1)); |
390 | } |
391 | |
392 | inline bool S2CellId::contains(S2CellId const& other) const { |
393 | DCHECK(is_valid()); |
394 | DCHECK(other.is_valid()); |
395 | return other >= range_min() && other <= range_max(); |
396 | } |
397 | |
398 | inline bool S2CellId::intersects(S2CellId const& other) const { |
399 | DCHECK(is_valid()); |
400 | DCHECK(other.is_valid()); |
401 | return other.range_min() <= range_max() && other.range_max() >= range_min(); |
402 | } |
403 | |
404 | inline S2CellId S2CellId::parent(int level) const { |
405 | DCHECK(is_valid()); |
406 | DCHECK_GE(level, 0); |
407 | DCHECK_LE(level, this->level()); |
408 | uint64 new_lsb = lsb_for_level(level); |
409 | return S2CellId((id_ & -new_lsb) | new_lsb); |
410 | } |
411 | |
412 | inline S2CellId S2CellId::parent() const { |
413 | DCHECK(is_valid()); |
414 | DCHECK(!is_face()); |
415 | uint64 new_lsb = lsb() << 2; |
416 | return S2CellId((id_ & -new_lsb) | new_lsb); |
417 | } |
418 | |
419 | inline S2CellId S2CellId::child(int position) const { |
420 | DCHECK(is_valid()); |
421 | DCHECK(!is_leaf()); |
422 | // To change the level, we need to move the least-significant bit two |
423 | // positions downward. We do this by subtracting (4 * new_lsb) and adding |
424 | // new_lsb. Then to advance to the given child cell, we add |
425 | // (2 * position * new_lsb). |
426 | uint64 new_lsb = lsb() >> 2; |
427 | return S2CellId(id_ + (2 * position + 1 - 4) * new_lsb); |
428 | } |
429 | |
430 | inline S2CellId S2CellId::child_begin() const { |
431 | DCHECK(is_valid()); |
432 | DCHECK(!is_leaf()); |
433 | uint64 old_lsb = lsb(); |
434 | return S2CellId(id_ - old_lsb + (old_lsb >> 2)); |
435 | } |
436 | |
437 | inline S2CellId S2CellId::child_begin(int level) const { |
438 | DCHECK(is_valid()); |
439 | DCHECK_GE(level, this->level()); |
440 | DCHECK_LE(level, kMaxLevel); |
441 | return S2CellId(id_ - lsb() + lsb_for_level(level)); |
442 | } |
443 | |
444 | inline S2CellId S2CellId::child_end() const { |
445 | DCHECK(is_valid()); |
446 | DCHECK(!is_leaf()); |
447 | uint64 old_lsb = lsb(); |
448 | return S2CellId(id_ + old_lsb + (old_lsb >> 2)); |
449 | } |
450 | |
451 | inline S2CellId S2CellId::child_end(int level) const { |
452 | DCHECK(is_valid()); |
453 | DCHECK_GE(level, this->level()); |
454 | DCHECK_LE(level, kMaxLevel); |
455 | return S2CellId(id_ + lsb() + lsb_for_level(level)); |
456 | } |
457 | |
458 | inline S2CellId S2CellId::next() const { |
459 | return S2CellId(id_ + (lsb() << 1)); |
460 | } |
461 | |
462 | inline S2CellId S2CellId::prev() const { |
463 | return S2CellId(id_ - (lsb() << 1)); |
464 | } |
465 | |
466 | inline S2CellId S2CellId::next_wrap() const { |
467 | DCHECK(is_valid()); |
468 | S2CellId n = next(); |
469 | if (n.id_ < kWrapOffset) return n; |
470 | return S2CellId(n.id_ - kWrapOffset); |
471 | } |
472 | |
473 | inline S2CellId S2CellId::prev_wrap() const { |
474 | DCHECK(is_valid()); |
475 | S2CellId p = prev(); |
476 | if (p.id_ < kWrapOffset) return p; |
477 | return S2CellId(p.id_ + kWrapOffset); |
478 | } |
479 | |
480 | inline S2CellId S2CellId::Begin(int level) { |
481 | return FromFacePosLevel(0, 0, 0).child_begin(level); |
482 | } |
483 | |
484 | inline S2CellId S2CellId::End(int level) { |
485 | return FromFacePosLevel(5, 0, 0).child_end(level); |
486 | } |
487 | |
488 | ostream& operator<<(ostream& os, S2CellId const& id); |
489 | |
490 | #ifndef SWIG |
491 | #include<hash_set> |
492 | namespace __gnu_cxx { |
493 | |
494 | |
495 | template<> struct hash<S2CellId> { |
496 | size_t operator()(S2CellId const& id) const { |
497 | return static_cast<size_t>(id.id() >> 32) + static_cast<size_t>(id.id()); |
498 | } |
499 | }; |
500 | |
501 | |
502 | } // namespace __gnu_cxx |
503 | |
504 | #endif // SWIG |
505 | |
506 | #endif // UTIL_GEOMETRY_S2CELLID_H_ |
507 | |