gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

cellid.go (34379B)


      1 // Copyright 2014 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 package s2
     16 
     17 import (
     18 	"bytes"
     19 	"fmt"
     20 	"io"
     21 	"math"
     22 	"sort"
     23 	"strconv"
     24 	"strings"
     25 
     26 	"github.com/golang/geo/r1"
     27 	"github.com/golang/geo/r2"
     28 	"github.com/golang/geo/r3"
     29 	"github.com/golang/geo/s1"
     30 )
     31 
     32 // CellID uniquely identifies a cell in the S2 cell decomposition.
     33 // The most significant 3 bits encode the face number (0-5). The
     34 // remaining 61 bits encode the position of the center of this cell
     35 // along the Hilbert curve on that face. The zero value and the value
     36 // (1<<64)-1 are invalid cell IDs. The first compares less than any
     37 // valid cell ID, the second as greater than any valid cell ID.
     38 //
     39 // Sequentially increasing cell IDs follow a continuous space-filling curve
     40 // over the entire sphere. They have the following properties:
     41 //
     42 //  - The ID of a cell at level k consists of a 3-bit face number followed
     43 //    by k bit pairs that recursively select one of the four children of
     44 //    each cell. The next bit is always 1, and all other bits are 0.
     45 //    Therefore, the level of a cell is determined by the position of its
     46 //    lowest-numbered bit that is turned on (for a cell at level k, this
     47 //    position is 2 * (maxLevel - k)).
     48 //
     49 //  - The ID of a parent cell is at the midpoint of the range of IDs spanned
     50 //    by its children (or by its descendants at any level).
     51 //
     52 // Leaf cells are often used to represent points on the unit sphere, and
     53 // this type provides methods for converting directly between these two
     54 // representations. For cells that represent 2D regions rather than
     55 // discrete point, it is better to use Cells.
     56 type CellID uint64
     57 
     58 // SentinelCellID is an invalid cell ID guaranteed to be larger than any
     59 // valid cell ID. It is used primarily by ShapeIndex. The value is also used
     60 // by some S2 types when encoding data.
     61 // Note that the sentinel's RangeMin == RangeMax == itself.
     62 const SentinelCellID = CellID(^uint64(0))
     63 
     64 // sortCellIDs sorts the slice of CellIDs in place.
     65 func sortCellIDs(ci []CellID) {
     66 	sort.Sort(cellIDs(ci))
     67 }
     68 
     69 // cellIDs implements the Sort interface for slices of CellIDs.
     70 type cellIDs []CellID
     71 
     72 func (c cellIDs) Len() int           { return len(c) }
     73 func (c cellIDs) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
     74 func (c cellIDs) Less(i, j int) bool { return c[i] < c[j] }
     75 
     76 // TODO(dsymonds): Some of these constants should probably be exported.
     77 const (
     78 	faceBits = 3
     79 	numFaces = 6
     80 
     81 	// This is the number of levels needed to specify a leaf cell.
     82 	maxLevel = 30
     83 
     84 	// The extra position bit (61 rather than 60) lets us encode each cell as its
     85 	// Hilbert curve position at the cell center (which is halfway along the
     86 	// portion of the Hilbert curve that fills that cell).
     87 	posBits = 2*maxLevel + 1
     88 
     89 	// The maximum index of a valid leaf cell plus one. The range of valid leaf
     90 	// cell indices is [0..maxSize-1].
     91 	maxSize = 1 << maxLevel
     92 
     93 	wrapOffset = uint64(numFaces) << posBits
     94 )
     95 
     96 // CellIDFromFacePosLevel returns a cell given its face in the range
     97 // [0,5], the 61-bit Hilbert curve position pos within that face, and
     98 // the level in the range [0,maxLevel]. The position in the cell ID
     99 // will be truncated to correspond to the Hilbert curve position at
    100 // the center of the returned cell.
    101 func CellIDFromFacePosLevel(face int, pos uint64, level int) CellID {
    102 	return CellID(uint64(face)<<posBits + pos | 1).Parent(level)
    103 }
    104 
    105 // CellIDFromFace returns the cell corresponding to a given S2 cube face.
    106 func CellIDFromFace(face int) CellID {
    107 	return CellID((uint64(face) << posBits) + lsbForLevel(0))
    108 }
    109 
    110 // CellIDFromLatLng returns the leaf cell containing ll.
    111 func CellIDFromLatLng(ll LatLng) CellID {
    112 	return cellIDFromPoint(PointFromLatLng(ll))
    113 }
    114 
    115 // CellIDFromToken returns a cell given a hex-encoded string of its uint64 ID.
    116 func CellIDFromToken(s string) CellID {
    117 	if len(s) > 16 {
    118 		return CellID(0)
    119 	}
    120 	n, err := strconv.ParseUint(s, 16, 64)
    121 	if err != nil {
    122 		return CellID(0)
    123 	}
    124 	// Equivalent to right-padding string with zeros to 16 characters.
    125 	if len(s) < 16 {
    126 		n = n << (4 * uint(16-len(s)))
    127 	}
    128 	return CellID(n)
    129 }
    130 
    131 // ToToken returns a hex-encoded string of the uint64 cell id, with leading
    132 // zeros included but trailing zeros stripped.
    133 func (ci CellID) ToToken() string {
    134 	s := strings.TrimRight(fmt.Sprintf("%016x", uint64(ci)), "0")
    135 	if len(s) == 0 {
    136 		return "X"
    137 	}
    138 	return s
    139 }
    140 
    141 // IsValid reports whether ci represents a valid cell.
    142 func (ci CellID) IsValid() bool {
    143 	return ci.Face() < numFaces && (ci.lsb()&0x1555555555555555 != 0)
    144 }
    145 
    146 // Face returns the cube face for this cell ID, in the range [0,5].
    147 func (ci CellID) Face() int { return int(uint64(ci) >> posBits) }
    148 
    149 // Pos returns the position along the Hilbert curve of this cell ID, in the range [0,2^posBits-1].
    150 func (ci CellID) Pos() uint64 { return uint64(ci) & (^uint64(0) >> faceBits) }
    151 
    152 // Level returns the subdivision level of this cell ID, in the range [0, maxLevel].
    153 func (ci CellID) Level() int {
    154 	return maxLevel - findLSBSetNonZero64(uint64(ci))>>1
    155 }
    156 
    157 // IsLeaf returns whether this cell ID is at the deepest level;
    158 // that is, the level at which the cells are smallest.
    159 func (ci CellID) IsLeaf() bool { return uint64(ci)&1 != 0 }
    160 
    161 // ChildPosition returns the child position (0..3) of this cell's
    162 // ancestor at the given level, relative to its parent.  The argument
    163 // should be in the range 1..kMaxLevel.  For example,
    164 // ChildPosition(1) returns the position of this cell's level-1
    165 // ancestor within its top-level face cell.
    166 func (ci CellID) ChildPosition(level int) int {
    167 	return int(uint64(ci)>>uint64(2*(maxLevel-level)+1)) & 3
    168 }
    169 
    170 // lsbForLevel returns the lowest-numbered bit that is on for cells at the given level.
    171 func lsbForLevel(level int) uint64 { return 1 << uint64(2*(maxLevel-level)) }
    172 
    173 // Parent returns the cell at the given level, which must be no greater than the current level.
    174 func (ci CellID) Parent(level int) CellID {
    175 	lsb := lsbForLevel(level)
    176 	return CellID((uint64(ci) & -lsb) | lsb)
    177 }
    178 
    179 // immediateParent is cheaper than Parent, but assumes !ci.isFace().
    180 func (ci CellID) immediateParent() CellID {
    181 	nlsb := CellID(ci.lsb() << 2)
    182 	return (ci & -nlsb) | nlsb
    183 }
    184 
    185 // isFace returns whether this is a top-level (face) cell.
    186 func (ci CellID) isFace() bool { return uint64(ci)&(lsbForLevel(0)-1) == 0 }
    187 
    188 // lsb returns the least significant bit that is set.
    189 func (ci CellID) lsb() uint64 { return uint64(ci) & -uint64(ci) }
    190 
    191 // Children returns the four immediate children of this cell.
    192 // If ci is a leaf cell, it returns four identical cells that are not the children.
    193 func (ci CellID) Children() [4]CellID {
    194 	var ch [4]CellID
    195 	lsb := CellID(ci.lsb())
    196 	ch[0] = ci - lsb + lsb>>2
    197 	lsb >>= 1
    198 	ch[1] = ch[0] + lsb
    199 	ch[2] = ch[1] + lsb
    200 	ch[3] = ch[2] + lsb
    201 	return ch
    202 }
    203 
    204 func sizeIJ(level int) int {
    205 	return 1 << uint(maxLevel-level)
    206 }
    207 
    208 // EdgeNeighbors returns the four cells that are adjacent across the cell's four edges.
    209 // Edges 0, 1, 2, 3 are in the down, right, up, left directions in the face space.
    210 // All neighbors are guaranteed to be distinct.
    211 func (ci CellID) EdgeNeighbors() [4]CellID {
    212 	level := ci.Level()
    213 	size := sizeIJ(level)
    214 	f, i, j, _ := ci.faceIJOrientation()
    215 	return [4]CellID{
    216 		cellIDFromFaceIJWrap(f, i, j-size).Parent(level),
    217 		cellIDFromFaceIJWrap(f, i+size, j).Parent(level),
    218 		cellIDFromFaceIJWrap(f, i, j+size).Parent(level),
    219 		cellIDFromFaceIJWrap(f, i-size, j).Parent(level),
    220 	}
    221 }
    222 
    223 // VertexNeighbors returns the neighboring cellIDs with vertex closest to this cell at the given level.
    224 // (Normally there are four neighbors, but the closest vertex may only have three neighbors if it is one of
    225 // the 8 cube vertices.)
    226 func (ci CellID) VertexNeighbors(level int) []CellID {
    227 	halfSize := sizeIJ(level + 1)
    228 	size := halfSize << 1
    229 	f, i, j, _ := ci.faceIJOrientation()
    230 
    231 	var isame, jsame bool
    232 	var ioffset, joffset int
    233 	if i&halfSize != 0 {
    234 		ioffset = size
    235 		isame = (i + size) < maxSize
    236 	} else {
    237 		ioffset = -size
    238 		isame = (i - size) >= 0
    239 	}
    240 	if j&halfSize != 0 {
    241 		joffset = size
    242 		jsame = (j + size) < maxSize
    243 	} else {
    244 		joffset = -size
    245 		jsame = (j - size) >= 0
    246 	}
    247 
    248 	results := []CellID{
    249 		ci.Parent(level),
    250 		cellIDFromFaceIJSame(f, i+ioffset, j, isame).Parent(level),
    251 		cellIDFromFaceIJSame(f, i, j+joffset, jsame).Parent(level),
    252 	}
    253 
    254 	if isame || jsame {
    255 		results = append(results, cellIDFromFaceIJSame(f, i+ioffset, j+joffset, isame && jsame).Parent(level))
    256 	}
    257 
    258 	return results
    259 }
    260 
    261 // AllNeighbors returns all neighbors of this cell at the given level. Two
    262 // cells X and Y are neighbors if their boundaries intersect but their
    263 // interiors do not. In particular, two cells that intersect at a single
    264 // point are neighbors. Note that for cells adjacent to a face vertex, the
    265 // same neighbor may be returned more than once. There could be up to eight
    266 // neighbors including the diagonal ones that share the vertex.
    267 //
    268 // This requires level >= ci.Level().
    269 func (ci CellID) AllNeighbors(level int) []CellID {
    270 	var neighbors []CellID
    271 
    272 	face, i, j, _ := ci.faceIJOrientation()
    273 
    274 	// Find the coordinates of the lower left-hand leaf cell. We need to
    275 	// normalize (i,j) to a known position within the cell because level
    276 	// may be larger than this cell's level.
    277 	size := sizeIJ(ci.Level())
    278 	i &= -size
    279 	j &= -size
    280 
    281 	nbrSize := sizeIJ(level)
    282 
    283 	// We compute the top-bottom, left-right, and diagonal neighbors in one
    284 	// pass. The loop test is at the end of the loop to avoid 32-bit overflow.
    285 	for k := -nbrSize; ; k += nbrSize {
    286 		var sameFace bool
    287 		if k < 0 {
    288 			sameFace = (j+k >= 0)
    289 		} else if k >= size {
    290 			sameFace = (j+k < maxSize)
    291 		} else {
    292 			sameFace = true
    293 			// Top and bottom neighbors.
    294 			neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+k, j-nbrSize,
    295 				j-size >= 0).Parent(level))
    296 			neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+k, j+size,
    297 				j+size < maxSize).Parent(level))
    298 		}
    299 
    300 		// Left, right, and diagonal neighbors.
    301 		neighbors = append(neighbors, cellIDFromFaceIJSame(face, i-nbrSize, j+k,
    302 			sameFace && i-size >= 0).Parent(level))
    303 		neighbors = append(neighbors, cellIDFromFaceIJSame(face, i+size, j+k,
    304 			sameFace && i+size < maxSize).Parent(level))
    305 
    306 		if k >= size {
    307 			break
    308 		}
    309 	}
    310 
    311 	return neighbors
    312 }
    313 
    314 // RangeMin returns the minimum CellID that is contained within this cell.
    315 func (ci CellID) RangeMin() CellID { return CellID(uint64(ci) - (ci.lsb() - 1)) }
    316 
    317 // RangeMax returns the maximum CellID that is contained within this cell.
    318 func (ci CellID) RangeMax() CellID { return CellID(uint64(ci) + (ci.lsb() - 1)) }
    319 
    320 // Contains returns true iff the CellID contains oci.
    321 func (ci CellID) Contains(oci CellID) bool {
    322 	return uint64(ci.RangeMin()) <= uint64(oci) && uint64(oci) <= uint64(ci.RangeMax())
    323 }
    324 
    325 // Intersects returns true iff the CellID intersects oci.
    326 func (ci CellID) Intersects(oci CellID) bool {
    327 	return uint64(oci.RangeMin()) <= uint64(ci.RangeMax()) && uint64(oci.RangeMax()) >= uint64(ci.RangeMin())
    328 }
    329 
    330 // String returns the string representation of the cell ID in the form "1/3210".
    331 func (ci CellID) String() string {
    332 	if !ci.IsValid() {
    333 		return "Invalid: " + strconv.FormatInt(int64(ci), 16)
    334 	}
    335 	var b bytes.Buffer
    336 	b.WriteByte("012345"[ci.Face()]) // values > 5 will have been picked off by !IsValid above
    337 	b.WriteByte('/')
    338 	for level := 1; level <= ci.Level(); level++ {
    339 		b.WriteByte("0123"[ci.ChildPosition(level)])
    340 	}
    341 	return b.String()
    342 }
    343 
    344 // cellIDFromString returns a CellID from a string in the form "1/3210".
    345 func cellIDFromString(s string) CellID {
    346 	level := len(s) - 2
    347 	if level < 0 || level > maxLevel {
    348 		return CellID(0)
    349 	}
    350 	face := int(s[0] - '0')
    351 	if face < 0 || face > 5 || s[1] != '/' {
    352 		return CellID(0)
    353 	}
    354 	id := CellIDFromFace(face)
    355 	for i := 2; i < len(s); i++ {
    356 		childPos := s[i] - '0'
    357 		if childPos < 0 || childPos > 3 {
    358 			return CellID(0)
    359 		}
    360 		id = id.Children()[childPos]
    361 	}
    362 	return id
    363 }
    364 
    365 // Point returns the center of the s2 cell on the sphere as a Point.
    366 // The maximum directional error in Point (compared to the exact
    367 // mathematical result) is 1.5 * dblEpsilon radians, and the maximum length
    368 // error is 2 * dblEpsilon (the same as Normalize).
    369 func (ci CellID) Point() Point { return Point{ci.rawPoint().Normalize()} }
    370 
    371 // LatLng returns the center of the s2 cell on the sphere as a LatLng.
    372 func (ci CellID) LatLng() LatLng { return LatLngFromPoint(Point{ci.rawPoint()}) }
    373 
    374 // ChildBegin returns the first child in a traversal of the children of this cell, in Hilbert curve order.
    375 //
    376 //    for ci := c.ChildBegin(); ci != c.ChildEnd(); ci = ci.Next() {
    377 //        ...
    378 //    }
    379 func (ci CellID) ChildBegin() CellID {
    380 	ol := ci.lsb()
    381 	return CellID(uint64(ci) - ol + ol>>2)
    382 }
    383 
    384 // ChildBeginAtLevel returns the first cell in a traversal of children a given level deeper than this cell, in
    385 // Hilbert curve order. The given level must be no smaller than the cell's level.
    386 // See ChildBegin for example use.
    387 func (ci CellID) ChildBeginAtLevel(level int) CellID {
    388 	return CellID(uint64(ci) - ci.lsb() + lsbForLevel(level))
    389 }
    390 
    391 // ChildEnd returns the first cell after a traversal of the children of this cell in Hilbert curve order.
    392 // The returned cell may be invalid.
    393 func (ci CellID) ChildEnd() CellID {
    394 	ol := ci.lsb()
    395 	return CellID(uint64(ci) + ol + ol>>2)
    396 }
    397 
    398 // ChildEndAtLevel returns the first cell after the last child in a traversal of children a given level deeper
    399 // than this cell, in Hilbert curve order.
    400 // The given level must be no smaller than the cell's level.
    401 // The returned cell may be invalid.
    402 func (ci CellID) ChildEndAtLevel(level int) CellID {
    403 	return CellID(uint64(ci) + ci.lsb() + lsbForLevel(level))
    404 }
    405 
    406 // Next returns the next cell along the Hilbert curve.
    407 // This is expected to be used with ChildBegin and ChildEnd,
    408 // or ChildBeginAtLevel and ChildEndAtLevel.
    409 func (ci CellID) Next() CellID {
    410 	return CellID(uint64(ci) + ci.lsb()<<1)
    411 }
    412 
    413 // Prev returns the previous cell along the Hilbert curve.
    414 func (ci CellID) Prev() CellID {
    415 	return CellID(uint64(ci) - ci.lsb()<<1)
    416 }
    417 
    418 // NextWrap returns the next cell along the Hilbert curve, wrapping from last to
    419 // first as necessary. This should not be used with ChildBegin and ChildEnd.
    420 func (ci CellID) NextWrap() CellID {
    421 	n := ci.Next()
    422 	if uint64(n) < wrapOffset {
    423 		return n
    424 	}
    425 	return CellID(uint64(n) - wrapOffset)
    426 }
    427 
    428 // PrevWrap returns the previous cell along the Hilbert curve, wrapping around from
    429 // first to last as necessary. This should not be used with ChildBegin and ChildEnd.
    430 func (ci CellID) PrevWrap() CellID {
    431 	p := ci.Prev()
    432 	if uint64(p) < wrapOffset {
    433 		return p
    434 	}
    435 	return CellID(uint64(p) + wrapOffset)
    436 }
    437 
    438 // AdvanceWrap advances or retreats the indicated number of steps along the
    439 // Hilbert curve at the current level and returns the new position. The
    440 // position wraps between the first and last faces as necessary.
    441 func (ci CellID) AdvanceWrap(steps int64) CellID {
    442 	if steps == 0 {
    443 		return ci
    444 	}
    445 
    446 	// We clamp the number of steps if necessary to ensure that we do not
    447 	// advance past the End() or before the Begin() of this level.
    448 	shift := uint(2*(maxLevel-ci.Level()) + 1)
    449 	if steps < 0 {
    450 		if min := -int64(uint64(ci) >> shift); steps < min {
    451 			wrap := int64(wrapOffset >> shift)
    452 			steps %= wrap
    453 			if steps < min {
    454 				steps += wrap
    455 			}
    456 		}
    457 	} else {
    458 		// Unlike Advance(), we don't want to return End(level).
    459 		if max := int64((wrapOffset - uint64(ci)) >> shift); steps > max {
    460 			wrap := int64(wrapOffset >> shift)
    461 			steps %= wrap
    462 			if steps > max {
    463 				steps -= wrap
    464 			}
    465 		}
    466 	}
    467 
    468 	// If steps is negative, then shifting it left has undefined behavior.
    469 	// Cast to uint64 for a 2's complement answer.
    470 	return CellID(uint64(ci) + (uint64(steps) << shift))
    471 }
    472 
    473 // Encode encodes the CellID.
    474 func (ci CellID) Encode(w io.Writer) error {
    475 	e := &encoder{w: w}
    476 	ci.encode(e)
    477 	return e.err
    478 }
    479 
    480 func (ci CellID) encode(e *encoder) {
    481 	e.writeUint64(uint64(ci))
    482 }
    483 
    484 // Decode decodes the CellID.
    485 func (ci *CellID) Decode(r io.Reader) error {
    486 	d := &decoder{r: asByteReader(r)}
    487 	ci.decode(d)
    488 	return d.err
    489 }
    490 
    491 func (ci *CellID) decode(d *decoder) {
    492 	*ci = CellID(d.readUint64())
    493 }
    494 
    495 // TODO: the methods below are not exported yet.  Settle on the entire API design
    496 // before doing this.  Do we want to mirror the C++ one as closely as possible?
    497 
    498 // distanceFromBegin returns the number of steps along the Hilbert curve that
    499 // this cell is from the first node in the S2 hierarchy at our level. (i.e.,
    500 // FromFace(0).ChildBeginAtLevel(ci.Level())). This is analogous to Pos(), but
    501 // for this cell's level.
    502 // The return value is always non-negative.
    503 func (ci CellID) distanceFromBegin() int64 {
    504 	return int64(ci >> uint64(2*(maxLevel-ci.Level())+1))
    505 }
    506 
    507 // rawPoint returns an unnormalized r3 vector from the origin through the center
    508 // of the s2 cell on the sphere.
    509 func (ci CellID) rawPoint() r3.Vector {
    510 	face, si, ti := ci.faceSiTi()
    511 	return faceUVToXYZ(face, stToUV((0.5/maxSize)*float64(si)), stToUV((0.5/maxSize)*float64(ti)))
    512 }
    513 
    514 // faceSiTi returns the Face/Si/Ti coordinates of the center of the cell.
    515 func (ci CellID) faceSiTi() (face int, si, ti uint32) {
    516 	face, i, j, _ := ci.faceIJOrientation()
    517 	delta := 0
    518 	if ci.IsLeaf() {
    519 		delta = 1
    520 	} else {
    521 		if (i^(int(ci)>>2))&1 != 0 {
    522 			delta = 2
    523 		}
    524 	}
    525 	return face, uint32(2*i + delta), uint32(2*j + delta)
    526 }
    527 
    528 // faceIJOrientation uses the global lookupIJ table to unfiddle the bits of ci.
    529 func (ci CellID) faceIJOrientation() (f, i, j, orientation int) {
    530 	f = ci.Face()
    531 	orientation = f & swapMask
    532 	nbits := maxLevel - 7*lookupBits // first iteration
    533 
    534 	// Each iteration maps 8 bits of the Hilbert curve position into
    535 	// 4 bits of "i" and "j". The lookup table transforms a key of the
    536 	// form "ppppppppoo" to a value of the form "iiiijjjjoo", where the
    537 	// letters [ijpo] represents bits of "i", "j", the Hilbert curve
    538 	// position, and the Hilbert curve orientation respectively.
    539 	//
    540 	// On the first iteration we need to be careful to clear out the bits
    541 	// representing the cube face.
    542 	for k := 7; k >= 0; k-- {
    543 		orientation += (int(uint64(ci)>>uint64(k*2*lookupBits+1)) & ((1 << uint(2*nbits)) - 1)) << 2
    544 		orientation = lookupIJ[orientation]
    545 		i += (orientation >> (lookupBits + 2)) << uint(k*lookupBits)
    546 		j += ((orientation >> 2) & ((1 << lookupBits) - 1)) << uint(k*lookupBits)
    547 		orientation &= (swapMask | invertMask)
    548 		nbits = lookupBits // following iterations
    549 	}
    550 
    551 	// The position of a non-leaf cell at level "n" consists of a prefix of
    552 	// 2*n bits that identifies the cell, followed by a suffix of
    553 	// 2*(maxLevel-n)+1 bits of the form 10*. If n==maxLevel, the suffix is
    554 	// just "1" and has no effect. Otherwise, it consists of "10", followed
    555 	// by (maxLevel-n-1) repetitions of "00", followed by "0". The "10" has
    556 	// no effect, while each occurrence of "00" has the effect of reversing
    557 	// the swapMask bit.
    558 	if ci.lsb()&0x1111111111111110 != 0 {
    559 		orientation ^= swapMask
    560 	}
    561 
    562 	return
    563 }
    564 
    565 // cellIDFromFaceIJ returns a leaf cell given its cube face (range 0..5) and IJ coordinates.
    566 func cellIDFromFaceIJ(f, i, j int) CellID {
    567 	// Note that this value gets shifted one bit to the left at the end
    568 	// of the function.
    569 	n := uint64(f) << (posBits - 1)
    570 	// Alternating faces have opposite Hilbert curve orientations; this
    571 	// is necessary in order for all faces to have a right-handed
    572 	// coordinate system.
    573 	bits := f & swapMask
    574 	// Each iteration maps 4 bits of "i" and "j" into 8 bits of the Hilbert
    575 	// curve position.  The lookup table transforms a 10-bit key of the form
    576 	// "iiiijjjjoo" to a 10-bit value of the form "ppppppppoo", where the
    577 	// letters [ijpo] denote bits of "i", "j", Hilbert curve position, and
    578 	// Hilbert curve orientation respectively.
    579 	for k := 7; k >= 0; k-- {
    580 		mask := (1 << lookupBits) - 1
    581 		bits += ((i >> uint(k*lookupBits)) & mask) << (lookupBits + 2)
    582 		bits += ((j >> uint(k*lookupBits)) & mask) << 2
    583 		bits = lookupPos[bits]
    584 		n |= uint64(bits>>2) << (uint(k) * 2 * lookupBits)
    585 		bits &= (swapMask | invertMask)
    586 	}
    587 	return CellID(n*2 + 1)
    588 }
    589 
    590 func cellIDFromFaceIJWrap(f, i, j int) CellID {
    591 	// Convert i and j to the coordinates of a leaf cell just beyond the
    592 	// boundary of this face.  This prevents 32-bit overflow in the case
    593 	// of finding the neighbors of a face cell.
    594 	i = clampInt(i, -1, maxSize)
    595 	j = clampInt(j, -1, maxSize)
    596 
    597 	// We want to wrap these coordinates onto the appropriate adjacent face.
    598 	// The easiest way to do this is to convert the (i,j) coordinates to (x,y,z)
    599 	// (which yields a point outside the normal face boundary), and then call
    600 	// xyzToFaceUV to project back onto the correct face.
    601 	//
    602 	// The code below converts (i,j) to (si,ti), and then (si,ti) to (u,v) using
    603 	// the linear projection (u=2*s-1 and v=2*t-1).  (The code further below
    604 	// converts back using the inverse projection, s=0.5*(u+1) and t=0.5*(v+1).
    605 	// Any projection would work here, so we use the simplest.)  We also clamp
    606 	// the (u,v) coordinates so that the point is barely outside the
    607 	// [-1,1]x[-1,1] face rectangle, since otherwise the reprojection step
    608 	// (which divides by the new z coordinate) might change the other
    609 	// coordinates enough so that we end up in the wrong leaf cell.
    610 	const scale = 1.0 / maxSize
    611 	limit := math.Nextafter(1, 2)
    612 	u := math.Max(-limit, math.Min(limit, scale*float64((i<<1)+1-maxSize)))
    613 	v := math.Max(-limit, math.Min(limit, scale*float64((j<<1)+1-maxSize)))
    614 
    615 	// Find the leaf cell coordinates on the adjacent face, and convert
    616 	// them to a cell id at the appropriate level.
    617 	f, u, v = xyzToFaceUV(faceUVToXYZ(f, u, v))
    618 	return cellIDFromFaceIJ(f, stToIJ(0.5*(u+1)), stToIJ(0.5*(v+1)))
    619 }
    620 
    621 func cellIDFromFaceIJSame(f, i, j int, sameFace bool) CellID {
    622 	if sameFace {
    623 		return cellIDFromFaceIJ(f, i, j)
    624 	}
    625 	return cellIDFromFaceIJWrap(f, i, j)
    626 }
    627 
    628 // ijToSTMin converts the i- or j-index of a leaf cell to the minimum corresponding
    629 // s- or t-value contained by that cell. The argument must be in the range
    630 // [0..2**30], i.e. up to one position beyond the normal range of valid leaf
    631 // cell indices.
    632 func ijToSTMin(i int) float64 {
    633 	return float64(i) / float64(maxSize)
    634 }
    635 
    636 // stToIJ converts value in ST coordinates to a value in IJ coordinates.
    637 func stToIJ(s float64) int {
    638 	return clampInt(int(math.Floor(maxSize*s)), 0, maxSize-1)
    639 }
    640 
    641 // cellIDFromPoint returns a leaf cell containing point p. Usually there is
    642 // exactly one such cell, but for points along the edge of a cell, any
    643 // adjacent cell may be (deterministically) chosen. This is because
    644 // s2.CellIDs are considered to be closed sets. The returned cell will
    645 // always contain the given point, i.e.
    646 //
    647 //   CellFromPoint(p).ContainsPoint(p)
    648 //
    649 // is always true.
    650 func cellIDFromPoint(p Point) CellID {
    651 	f, u, v := xyzToFaceUV(r3.Vector{p.X, p.Y, p.Z})
    652 	i := stToIJ(uvToST(u))
    653 	j := stToIJ(uvToST(v))
    654 	return cellIDFromFaceIJ(f, i, j)
    655 }
    656 
    657 // ijLevelToBoundUV returns the bounds in (u,v)-space for the cell at the given
    658 // level containing the leaf cell with the given (i,j)-coordinates.
    659 func ijLevelToBoundUV(i, j, level int) r2.Rect {
    660 	cellSize := sizeIJ(level)
    661 	xLo := i & -cellSize
    662 	yLo := j & -cellSize
    663 
    664 	return r2.Rect{
    665 		X: r1.Interval{
    666 			Lo: stToUV(ijToSTMin(xLo)),
    667 			Hi: stToUV(ijToSTMin(xLo + cellSize)),
    668 		},
    669 		Y: r1.Interval{
    670 			Lo: stToUV(ijToSTMin(yLo)),
    671 			Hi: stToUV(ijToSTMin(yLo + cellSize)),
    672 		},
    673 	}
    674 }
    675 
    676 // Constants related to the bit mangling in the Cell ID.
    677 const (
    678 	lookupBits = 4
    679 	swapMask   = 0x01
    680 	invertMask = 0x02
    681 )
    682 
    683 // The following lookup tables are used to convert efficiently between an
    684 // (i,j) cell index and the corresponding position along the Hilbert curve.
    685 //
    686 // lookupPos maps 4 bits of "i", 4 bits of "j", and 2 bits representing the
    687 // orientation of the current cell into 8 bits representing the order in which
    688 // that subcell is visited by the Hilbert curve, plus 2 bits indicating the
    689 // new orientation of the Hilbert curve within that subcell. (Cell
    690 // orientations are represented as combination of swapMask and invertMask.)
    691 //
    692 // lookupIJ is an inverted table used for mapping in the opposite
    693 // direction.
    694 //
    695 // We also experimented with looking up 16 bits at a time (14 bits of position
    696 // plus 2 of orientation) but found that smaller lookup tables gave better
    697 // performance. (2KB fits easily in the primary cache.)
    698 var (
    699 	ijToPos = [4][4]int{
    700 		{0, 1, 3, 2}, // canonical order
    701 		{0, 3, 1, 2}, // axes swapped
    702 		{2, 3, 1, 0}, // bits inverted
    703 		{2, 1, 3, 0}, // swapped & inverted
    704 	}
    705 	posToIJ = [4][4]int{
    706 		{0, 1, 3, 2}, // canonical order:    (0,0), (0,1), (1,1), (1,0)
    707 		{0, 2, 3, 1}, // axes swapped:       (0,0), (1,0), (1,1), (0,1)
    708 		{3, 2, 0, 1}, // bits inverted:      (1,1), (1,0), (0,0), (0,1)
    709 		{3, 1, 0, 2}, // swapped & inverted: (1,1), (0,1), (0,0), (1,0)
    710 	}
    711 	posToOrientation = [4]int{swapMask, 0, 0, invertMask | swapMask}
    712 	lookupIJ         [1 << (2*lookupBits + 2)]int
    713 	lookupPos        [1 << (2*lookupBits + 2)]int
    714 )
    715 
    716 func init() {
    717 	initLookupCell(0, 0, 0, 0, 0, 0)
    718 	initLookupCell(0, 0, 0, swapMask, 0, swapMask)
    719 	initLookupCell(0, 0, 0, invertMask, 0, invertMask)
    720 	initLookupCell(0, 0, 0, swapMask|invertMask, 0, swapMask|invertMask)
    721 }
    722 
    723 // initLookupCell initializes the lookupIJ table at init time.
    724 func initLookupCell(level, i, j, origOrientation, pos, orientation int) {
    725 	if level == lookupBits {
    726 		ij := (i << lookupBits) + j
    727 		lookupPos[(ij<<2)+origOrientation] = (pos << 2) + orientation
    728 		lookupIJ[(pos<<2)+origOrientation] = (ij << 2) + orientation
    729 		return
    730 	}
    731 
    732 	level++
    733 	i <<= 1
    734 	j <<= 1
    735 	pos <<= 2
    736 	r := posToIJ[orientation]
    737 	initLookupCell(level, i+(r[0]>>1), j+(r[0]&1), origOrientation, pos, orientation^posToOrientation[0])
    738 	initLookupCell(level, i+(r[1]>>1), j+(r[1]&1), origOrientation, pos+1, orientation^posToOrientation[1])
    739 	initLookupCell(level, i+(r[2]>>1), j+(r[2]&1), origOrientation, pos+2, orientation^posToOrientation[2])
    740 	initLookupCell(level, i+(r[3]>>1), j+(r[3]&1), origOrientation, pos+3, orientation^posToOrientation[3])
    741 }
    742 
    743 // CommonAncestorLevel returns the level of the common ancestor of the two S2 CellIDs.
    744 func (ci CellID) CommonAncestorLevel(other CellID) (level int, ok bool) {
    745 	bits := uint64(ci ^ other)
    746 	if bits < ci.lsb() {
    747 		bits = ci.lsb()
    748 	}
    749 	if bits < other.lsb() {
    750 		bits = other.lsb()
    751 	}
    752 
    753 	msbPos := findMSBSetNonZero64(bits)
    754 	if msbPos > 60 {
    755 		return 0, false
    756 	}
    757 	return (60 - msbPos) >> 1, true
    758 }
    759 
    760 // Advance advances or retreats the indicated number of steps along the
    761 // Hilbert curve at the current level, and returns the new position. The
    762 // position is never advanced past End() or before Begin().
    763 func (ci CellID) Advance(steps int64) CellID {
    764 	if steps == 0 {
    765 		return ci
    766 	}
    767 
    768 	// We clamp the number of steps if necessary to ensure that we do not
    769 	// advance past the End() or before the Begin() of this level. Note that
    770 	// minSteps and maxSteps always fit in a signed 64-bit integer.
    771 	stepShift := uint(2*(maxLevel-ci.Level()) + 1)
    772 	if steps < 0 {
    773 		minSteps := -int64(uint64(ci) >> stepShift)
    774 		if steps < minSteps {
    775 			steps = minSteps
    776 		}
    777 	} else {
    778 		maxSteps := int64((wrapOffset + ci.lsb() - uint64(ci)) >> stepShift)
    779 		if steps > maxSteps {
    780 			steps = maxSteps
    781 		}
    782 	}
    783 	return ci + CellID(steps)<<stepShift
    784 }
    785 
    786 // centerST return the center of the CellID in (s,t)-space.
    787 func (ci CellID) centerST() r2.Point {
    788 	_, si, ti := ci.faceSiTi()
    789 	return r2.Point{siTiToST(si), siTiToST(ti)}
    790 }
    791 
    792 // sizeST returns the edge length of this CellID in (s,t)-space at the given level.
    793 func (ci CellID) sizeST(level int) float64 {
    794 	return ijToSTMin(sizeIJ(level))
    795 }
    796 
    797 // boundST returns the bound of this CellID in (s,t)-space.
    798 func (ci CellID) boundST() r2.Rect {
    799 	s := ci.sizeST(ci.Level())
    800 	return r2.RectFromCenterSize(ci.centerST(), r2.Point{s, s})
    801 }
    802 
    803 // centerUV returns the center of this CellID in (u,v)-space. Note that
    804 // the center of the cell is defined as the point at which it is recursively
    805 // subdivided into four children; in general, it is not at the midpoint of
    806 // the (u,v) rectangle covered by the cell.
    807 func (ci CellID) centerUV() r2.Point {
    808 	_, si, ti := ci.faceSiTi()
    809 	return r2.Point{stToUV(siTiToST(si)), stToUV(siTiToST(ti))}
    810 }
    811 
    812 // boundUV returns the bound of this CellID in (u,v)-space.
    813 func (ci CellID) boundUV() r2.Rect {
    814 	_, i, j, _ := ci.faceIJOrientation()
    815 	return ijLevelToBoundUV(i, j, ci.Level())
    816 }
    817 
    818 // expandEndpoint returns a new u-coordinate u' such that the distance from the
    819 // line u=u' to the given edge (u,v0)-(u,v1) is exactly the given distance
    820 // (which is specified as the sine of the angle corresponding to the distance).
    821 func expandEndpoint(u, maxV, sinDist float64) float64 {
    822 	// This is based on solving a spherical right triangle, similar to the
    823 	// calculation in Cap.RectBound.
    824 	// Given an edge of the form (u,v0)-(u,v1), let maxV = max(abs(v0), abs(v1)).
    825 	sinUShift := sinDist * math.Sqrt((1+u*u+maxV*maxV)/(1+u*u))
    826 	cosUShift := math.Sqrt(1 - sinUShift*sinUShift)
    827 	// The following is an expansion of tan(atan(u) + asin(sinUShift)).
    828 	return (cosUShift*u + sinUShift) / (cosUShift - sinUShift*u)
    829 }
    830 
    831 // expandedByDistanceUV returns a rectangle expanded in (u,v)-space so that it
    832 // contains all points within the given distance of the boundary, and return the
    833 // smallest such rectangle. If the distance is negative, then instead shrink this
    834 // rectangle so that it excludes all points within the given absolute distance
    835 // of the boundary.
    836 //
    837 // Distances are measured *on the sphere*, not in (u,v)-space. For example,
    838 // you can use this method to expand the (u,v)-bound of an CellID so that
    839 // it contains all points within 5km of the original cell. You can then
    840 // test whether a point lies within the expanded bounds like this:
    841 //
    842 //   if u, v, ok := faceXYZtoUV(face, point); ok && bound.ContainsPoint(r2.Point{u,v}) { ... }
    843 //
    844 // Limitations:
    845 //
    846 //  - Because the rectangle is drawn on one of the six cube-face planes
    847 //    (i.e., {x,y,z} = +/-1), it can cover at most one hemisphere. This
    848 //    limits the maximum amount that a rectangle can be expanded. For
    849 //    example, CellID bounds can be expanded safely by at most 45 degrees
    850 //    (about 5000 km on the Earth's surface).
    851 //
    852 //  - The implementation is not exact for negative distances. The resulting
    853 //    rectangle will exclude all points within the given distance of the
    854 //    boundary but may be slightly smaller than necessary.
    855 func expandedByDistanceUV(uv r2.Rect, distance s1.Angle) r2.Rect {
    856 	// Expand each of the four sides of the rectangle just enough to include all
    857 	// points within the given distance of that side. (The rectangle may be
    858 	// expanded by a different amount in (u,v)-space on each side.)
    859 	maxU := math.Max(math.Abs(uv.X.Lo), math.Abs(uv.X.Hi))
    860 	maxV := math.Max(math.Abs(uv.Y.Lo), math.Abs(uv.Y.Hi))
    861 	sinDist := math.Sin(float64(distance))
    862 	return r2.Rect{
    863 		X: r1.Interval{expandEndpoint(uv.X.Lo, maxV, -sinDist),
    864 			expandEndpoint(uv.X.Hi, maxV, sinDist)},
    865 		Y: r1.Interval{expandEndpoint(uv.Y.Lo, maxU, -sinDist),
    866 			expandEndpoint(uv.Y.Hi, maxU, sinDist)}}
    867 }
    868 
    869 // MaxTile returns the largest cell with the same RangeMin such that
    870 // RangeMax < limit.RangeMin. It returns limit if no such cell exists.
    871 // This method can be used to generate a small set of CellIDs that covers
    872 // a given range (a tiling). This example shows how to generate a tiling
    873 // for a semi-open range of leaf cells [start, limit):
    874 //
    875 //   for id := start.MaxTile(limit); id != limit; id = id.Next().MaxTile(limit)) { ... }
    876 //
    877 // Note that in general the cells in the tiling will be of different sizes;
    878 // they gradually get larger (near the middle of the range) and then
    879 // gradually get smaller as limit is approached.
    880 func (ci CellID) MaxTile(limit CellID) CellID {
    881 	start := ci.RangeMin()
    882 	if start >= limit.RangeMin() {
    883 		return limit
    884 	}
    885 
    886 	if ci.RangeMax() >= limit {
    887 		// The cell is too large, shrink it. Note that when generating coverings
    888 		// of CellID ranges, this loop usually executes only once. Also because
    889 		// ci.RangeMin() < limit.RangeMin(), we will always exit the loop by the
    890 		// time we reach a leaf cell.
    891 		for {
    892 			ci = ci.Children()[0]
    893 			if ci.RangeMax() < limit {
    894 				break
    895 			}
    896 		}
    897 		return ci
    898 	}
    899 
    900 	// The cell may be too small. Grow it if necessary. Note that generally
    901 	// this loop only iterates once.
    902 	for !ci.isFace() {
    903 		parent := ci.immediateParent()
    904 		if parent.RangeMin() != start || parent.RangeMax() >= limit {
    905 			break
    906 		}
    907 		ci = parent
    908 	}
    909 	return ci
    910 }
    911 
    912 // centerFaceSiTi returns the (face, si, ti) coordinates of the center of the cell.
    913 // Note that although (si,ti) coordinates span the range [0,2**31] in general,
    914 // the cell center coordinates are always in the range [1,2**31-1] and
    915 // therefore can be represented using a signed 32-bit integer.
    916 func (ci CellID) centerFaceSiTi() (face, si, ti int) {
    917 	// First we compute the discrete (i,j) coordinates of a leaf cell contained
    918 	// within the given cell. Given that cells are represented by the Hilbert
    919 	// curve position corresponding at their center, it turns out that the cell
    920 	// returned by faceIJOrientation is always one of two leaf cells closest
    921 	// to the center of the cell (unless the given cell is a leaf cell itself,
    922 	// in which case there is only one possibility).
    923 	//
    924 	// Given a cell of size s >= 2 (i.e. not a leaf cell), and letting (imin,
    925 	// jmin) be the coordinates of its lower left-hand corner, the leaf cell
    926 	// returned by faceIJOrientation is either (imin + s/2, jmin + s/2)
    927 	// (imin + s/2 - 1, jmin + s/2 - 1). The first case is the one we want.
    928 	// We can distinguish these two cases by looking at the low bit of i or
    929 	// j. In the second case the low bit is one, unless s == 2 (i.e. the
    930 	// level just above leaf cells) in which case the low bit is zero.
    931 	//
    932 	// In the code below, the expression ((i ^ (int(id) >> 2)) & 1) is true
    933 	// if we are in the second case described above.
    934 	face, i, j, _ := ci.faceIJOrientation()
    935 	delta := 0
    936 	if ci.IsLeaf() {
    937 		delta = 1
    938 	} else if (int64(i)^(int64(ci)>>2))&1 == 1 {
    939 		delta = 2
    940 	}
    941 
    942 	// Note that (2 * {i,j} + delta) will never overflow a 32-bit integer.
    943 	return face, 2*i + delta, 2*j + delta
    944 }