summaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/geo/s2/cell_index.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/geo/s2/cell_index.go')
-rw-r--r--vendor/github.com/golang/geo/s2/cell_index.go498
1 files changed, 0 insertions, 498 deletions
diff --git a/vendor/github.com/golang/geo/s2/cell_index.go b/vendor/github.com/golang/geo/s2/cell_index.go
deleted file mode 100644
index ef16d0895..000000000
--- a/vendor/github.com/golang/geo/s2/cell_index.go
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package s2
-
-import (
- "sort"
-)
-
-const (
- // A special label indicating that the ContentsIterator done is true.
- cellIndexDoneContents = -1
-)
-
-// cellIndexNode represents a node in the CellIndex. Cells are organized in a
-// tree such that the ancestors of a given node contain that node.
-type cellIndexNode struct {
- cellID CellID
- label int32
- parent int32
-}
-
-// newCellIndexNode returns a node with the appropriate default values.
-func newCellIndexNode() cellIndexNode {
- return cellIndexNode{
- cellID: 0,
- label: cellIndexDoneContents,
- parent: -1,
- }
-}
-
-// A rangeNode represents a range of leaf CellIDs. The range starts at
-// startID (a leaf cell) and ends at the startID field of the next
-// rangeNode. contents points to the node of the CellIndex cellTree
-// representing the cells that overlap this range.
-type rangeNode struct {
- startID CellID // First leaf cell contained by this range.
- contents int32 // Contents of this node (an index within the cell tree).
-}
-
-// CellIndexIterator is an iterator that visits the entire set of indexed
-// (CellID, label) pairs in an unspecified order.
-type CellIndexIterator struct {
- // TODO(roberts): Implement
-}
-
-// NewCellIndexIterator creates an iterator for the given CellIndex.
-func NewCellIndexIterator(index *CellIndex) *CellIndexIterator {
- return &CellIndexIterator{}
-}
-
-// CellIndexRangeIterator is an iterator that seeks and iterates over a set of
-// non-overlapping leaf cell ranges that cover the entire sphere. The indexed
-// (CellID, label) pairs that intersect the current leaf cell range can be
-// visited using CellIndexContentsIterator (see below).
-type CellIndexRangeIterator struct {
- rangeNodes []rangeNode
- pos int
- nonEmpty bool
-}
-
-// NewCellIndexRangeIterator creates an iterator for the given CellIndex.
-// The iterator is initially *unpositioned*; you must call a positioning method
-// such as Begin() or Seek() before accessing its contents.
-func NewCellIndexRangeIterator(index *CellIndex) *CellIndexRangeIterator {
- return &CellIndexRangeIterator{
- rangeNodes: index.rangeNodes,
- }
-}
-
-// NewCellIndexNonEmptyRangeIterator creates an iterator for the given CellIndex.
-// The iterator is initially *unpositioned*; you must call a positioning method such as
-// Begin() or Seek() before accessing its contents.
-func NewCellIndexNonEmptyRangeIterator(index *CellIndex) *CellIndexRangeIterator {
- return &CellIndexRangeIterator{
- rangeNodes: index.rangeNodes,
- nonEmpty: true,
- }
-}
-
-// StartID reports the CellID of the start of the current range of leaf CellIDs.
-//
-// If done is true, this returns the last possible CellID. This property means
-// that most loops do not need to test done explicitly.
-func (c *CellIndexRangeIterator) StartID() CellID {
- return c.rangeNodes[c.pos].startID
-}
-
-// LimitID reports the non-inclusive end of the current range of leaf CellIDs.
-//
-// This assumes the iterator is not done.
-func (c *CellIndexRangeIterator) LimitID() CellID {
- return c.rangeNodes[c.pos+1].startID
-}
-
-// IsEmpty reports if no (CellID, label) pairs intersect this range.
-// Also returns true if done() is true.
-func (c *CellIndexRangeIterator) IsEmpty() bool {
- return c.rangeNodes[c.pos].contents == cellIndexDoneContents
-}
-
-// Begin positions the iterator at the first range of leaf cells (if any).
-func (c *CellIndexRangeIterator) Begin() {
- c.pos = 0
- for c.nonEmpty && c.IsEmpty() && !c.Done() {
- c.pos++
- }
-}
-
-// Prev positions the iterator at the previous entry and reports whether it was not
-// already positioned at the beginning.
-func (c *CellIndexRangeIterator) Prev() bool {
- if c.nonEmpty {
- return c.nonEmptyPrev()
- }
- return c.prev()
-}
-
-// prev is used to position the iterator at the previous entry without checking
-// if nonEmpty is true to prevent unwanted recursion.
-func (c *CellIndexRangeIterator) prev() bool {
- if c.pos == 0 {
- return false
- }
-
- c.pos--
- return true
-}
-
-// Prev positions the iterator at the previous entry, and reports whether it was
-// already positioned at the beginning.
-func (c *CellIndexRangeIterator) nonEmptyPrev() bool {
- for c.prev() {
- if !c.IsEmpty() {
- return true
- }
- }
-
- // Return the iterator to its original position.
- if c.IsEmpty() && !c.Done() {
- c.Next()
- }
- return false
-}
-
-// Next advances the iterator to the next range of leaf cells.
-//
-// This assumes the iterator is not done.
-func (c *CellIndexRangeIterator) Next() {
- c.pos++
- for c.nonEmpty && c.IsEmpty() && !c.Done() {
- c.pos++
- }
-}
-
-// Advance reports if advancing would leave it positioned on a valid range. If
-// the value would not be valid, the positioning is not changed.
-func (c *CellIndexRangeIterator) Advance(n int) bool {
- // Note that the last element of rangeNodes is a sentinel value.
- if n >= len(c.rangeNodes)-1-c.pos {
- return false
- }
- c.pos += n
- return true
-}
-
-// Finish positions the iterator so that done is true.
-func (c *CellIndexRangeIterator) Finish() {
- // Note that the last element of rangeNodes is a sentinel value.
- c.pos = len(c.rangeNodes) - 1
-}
-
-// Done reports if the iterator is positioned beyond the last valid range.
-func (c *CellIndexRangeIterator) Done() bool {
- return c.pos >= len(c.rangeNodes)-1
-}
-
-// Seek positions the iterator at the first range with startID >= target.
-// Such an entry always exists as long as "target" is a valid leaf cell.
-//
-// Note that it is valid to access startID even when done is true.
-func (c *CellIndexRangeIterator) Seek(target CellID) {
- c.pos = sort.Search(len(c.rangeNodes), func(i int) bool {
- return c.rangeNodes[i].startID > target
- }) - 1
-
- // Ensure we don't go beyond the beginning.
- if c.pos < 0 {
- c.pos = 0
- }
-
- // Nonempty needs to find the next non-empty entry.
- for c.nonEmpty && c.IsEmpty() && !c.Done() {
- // c.Next()
- c.pos++
- }
-}
-
-// CellIndexContentsIterator is an iterator that visits the (CellID, label) pairs
-// that cover a set of leaf cell ranges (see CellIndexRangeIterator). Note that
-// when multiple leaf cell ranges are visited, this iterator only guarantees that
-// each result will be reported at least once, i.e. duplicate values may be
-// suppressed. If you want duplicate values to be reported again, be sure to call
-// Clear first.
-//
-// In particular, the implementation guarantees that when multiple leaf
-// cell ranges are visited in monotonically increasing order, then each
-// (CellID, label) pair is reported exactly once.
-type CellIndexContentsIterator struct {
- // The maximum index within the cellTree slice visited during the
- // previous call to StartUnion. This is used to eliminate duplicate
- // values when StartUnion is called multiple times.
- nodeCutoff int32
-
- // The maximum index within the cellTree visited during the
- // current call to StartUnion. This is used to update nodeCutoff.
- nextNodeCutoff int32
-
- // The value of startID from the previous call to StartUnion.
- // This is used to check whether these values are monotonically
- // increasing.
- prevStartID CellID
-
- // The cell tree from CellIndex
- cellTree []cellIndexNode
-
- // A copy of the current node in the cell tree.
- node cellIndexNode
-}
-
-// NewCellIndexContentsIterator returns a new contents iterator.
-//
-// Note that the iterator needs to be positioned using StartUnion before
-// it can be safely used.
-func NewCellIndexContentsIterator(index *CellIndex) *CellIndexContentsIterator {
- it := &CellIndexContentsIterator{
- cellTree: index.cellTree,
- prevStartID: 0,
- nodeCutoff: -1,
- nextNodeCutoff: -1,
- node: cellIndexNode{label: cellIndexDoneContents},
- }
- return it
-}
-
-// Clear clears all state with respect to which range(s) have been visited.
-func (c *CellIndexContentsIterator) Clear() {
- c.prevStartID = 0
- c.nodeCutoff = -1
- c.nextNodeCutoff = -1
- c.node.label = cellIndexDoneContents
-}
-
-// CellID returns the current CellID.
-func (c *CellIndexContentsIterator) CellID() CellID {
- return c.node.cellID
-}
-
-// Label returns the current Label.
-func (c *CellIndexContentsIterator) Label() int32 {
- return c.node.label
-}
-
-// Next advances the iterator to the next (CellID, label) pair covered by the
-// current leaf cell range.
-//
-// This requires the iterator to not be done.
-func (c *CellIndexContentsIterator) Next() {
- if c.node.parent <= c.nodeCutoff {
- // We have already processed this node and its ancestors.
- c.nodeCutoff = c.nextNodeCutoff
- c.node.label = cellIndexDoneContents
- } else {
- c.node = c.cellTree[c.node.parent]
- }
-}
-
-// Done reports if all (CellID, label) pairs have been visited.
-func (c *CellIndexContentsIterator) Done() bool {
- return c.node.label == cellIndexDoneContents
-}
-
-// StartUnion positions the ContentsIterator at the first (cell_id, label) pair
-// that covers the given leaf cell range. Note that when multiple leaf cell
-// ranges are visited using the same ContentsIterator, duplicate values
-// may be suppressed. If you don't want this behavior, call Reset() first.
-func (c *CellIndexContentsIterator) StartUnion(r *CellIndexRangeIterator) {
- if r.StartID() < c.prevStartID {
- c.nodeCutoff = -1 // Can't automatically eliminate duplicates.
- }
- c.prevStartID = r.StartID()
-
- contents := r.rangeNodes[r.pos].contents
- if contents <= c.nodeCutoff {
- c.node.label = cellIndexDoneContents
- } else {
- c.node = c.cellTree[contents]
- }
-
- // When visiting ancestors, we can stop as soon as the node index is smaller
- // than any previously visited node index. Because indexes are assigned
- // using a preorder traversal, such nodes are guaranteed to have already
- // been reported.
- c.nextNodeCutoff = contents
-}
-
-// CellIndex stores a collection of (CellID, label) pairs.
-//
-// The CellIDs may be overlapping or contain duplicate values. For example, a
-// CellIndex could store a collection of CellUnions, where each CellUnion
-// gets its own non-negative int32 label.
-//
-// Similar to ShapeIndex and PointIndex which map each stored element to an
-// identifier, CellIndex stores a label that is typically used to map the
-// results of queries back to client's specific data.
-//
-// The zero value for a CellIndex is sufficient when constructing a CellIndex.
-//
-// To build a CellIndex where each Cell has a distinct label, call Add for each
-// (CellID, label) pair, and then Build the index. For example:
-//
-// // contents is a mapping of an identifier in my system (restaurantID,
-// // vehicleID, etc) to a CellID
-// var contents = map[int32]CellID{...}
-//
-// for key, val := range contents {
-// index.Add(val, key)
-// }
-//
-// index.Build()
-//
-// There is also a helper method that adds all elements of CellUnion with the
-// same label:
-//
-// index.AddCellUnion(cellUnion, label)
-//
-// Note that the index is not dynamic; the contents of the index cannot be
-// changed once it has been built. Adding more after calling Build results in
-// undefined behavior of the index.
-//
-// There are several options for retrieving data from the index. The simplest
-// is to use a built-in method such as IntersectingLabels (which returns
-// the labels of all cells that intersect a given target CellUnion):
-//
-// labels := index.IntersectingLabels(targetUnion);
-//
-// Alternatively, you can use a ClosestCellQuery which computes the cell(s)
-// that are closest to a given target geometry.
-//
-// For example, here is how to find all cells that are closer than
-// distanceLimit to a given target point:
-//
-// query := NewClosestCellQuery(cellIndex, opts)
-// target := NewMinDistanceToPointTarget(targetPoint);
-// for result := range query.FindCells(target) {
-// // result.Distance() is the distance to the target.
-// // result.CellID() is the indexed CellID.
-// // result.Label() is the label associated with the CellID.
-// DoSomething(targetPoint, result);
-// }
-//
-// Internally, the index consists of a set of non-overlapping leaf cell ranges
-// that subdivide the sphere and such that each range intersects a particular
-// set of (cellID, label) pairs.
-//
-// Most clients should use either the methods such as VisitIntersectingCells
-// and IntersectingLabels, or a helper such as ClosestCellQuery.
-type CellIndex struct {
- // A tree of (cellID, label) pairs such that if X is an ancestor of Y, then
- // X.cellID contains Y.cellID. The contents of a given range of leaf
- // cells can be represented by pointing to a node of this tree.
- cellTree []cellIndexNode
-
- // The last element of rangeNodes is a sentinel value, which is necessary
- // in order to represent the range covered by the previous element.
- rangeNodes []rangeNode
-}
-
-// Add adds the given CellID and Label to the index.
-func (c *CellIndex) Add(id CellID, label int32) {
- if label < 0 {
- panic("labels must be non-negative")
- }
- c.cellTree = append(c.cellTree, cellIndexNode{cellID: id, label: label, parent: -1})
-}
-
-// AddCellUnion adds all of the elements of the given CellUnion to the index with the same label.
-func (c *CellIndex) AddCellUnion(cu CellUnion, label int32) {
- if label < 0 {
- panic("labels must be non-negative")
- }
- for _, cell := range cu {
- c.Add(cell, label)
- }
-}
-
-// Build builds the index for use. This method should only be called once.
-func (c *CellIndex) Build() {
- // To build the cell tree and leaf cell ranges, we maintain a stack of
- // (CellID, label) pairs that contain the current leaf cell. This struct
- // represents an instruction to push or pop a (cellID, label) pair.
- //
- // If label >= 0, the (cellID, label) pair is pushed on the stack.
- // If CellID == SentinelCellID, a pair is popped from the stack.
- // Otherwise the stack is unchanged but a rangeNode is still emitted.
-
- // delta represents an entry in a stack of (CellID, label) pairs used in the
- // construction of the CellIndex structure.
- type delta struct {
- startID CellID
- cellID CellID
- label int32
- }
-
- deltas := make([]delta, 0, 2*len(c.cellTree)+2)
-
- // Create two deltas for each (cellID, label) pair: one to add the pair to
- // the stack (at the start of its leaf cell range), and one to remove it from
- // the stack (at the end of its leaf cell range).
- for _, node := range c.cellTree {
- deltas = append(deltas, delta{
- startID: node.cellID.RangeMin(),
- cellID: node.cellID,
- label: node.label,
- })
- deltas = append(deltas, delta{
- startID: node.cellID.RangeMax().Next(),
- cellID: SentinelCellID,
- label: -1,
- })
- }
-
- // We also create two special deltas to ensure that a RangeNode is emitted at
- // the beginning and end of the CellID range.
- deltas = append(deltas, delta{
- startID: CellIDFromFace(0).ChildBeginAtLevel(maxLevel),
- cellID: CellID(0),
- label: -1,
- })
- deltas = append(deltas, delta{
- startID: CellIDFromFace(5).ChildEndAtLevel(maxLevel),
- cellID: CellID(0),
- label: -1,
- })
-
- sort.Slice(deltas, func(i, j int) bool {
- // deltas are sorted first by startID, then in reverse order by cellID,
- // and then by label. This is necessary to ensure that (1) larger cells
- // are pushed on the stack before smaller cells, and (2) cells are popped
- // off the stack before any new cells are added.
-
- if si, sj := deltas[i].startID, deltas[j].startID; si != sj {
- return si < sj
- }
- if si, sj := deltas[i].cellID, deltas[j].cellID; si != sj {
- return si > sj
- }
- return deltas[i].label < deltas[j].label
- })
-
- // Now walk through the deltas to build the leaf cell ranges and cell tree
- // (which is essentially a permanent form of the "stack" described above).
- c.cellTree = nil
- c.rangeNodes = nil
- contents := int32(-1)
- for i := 0; i < len(deltas); {
- startID := deltas[i].startID
- // Process all the deltas associated with the current startID.
- for ; i < len(deltas) && deltas[i].startID == startID; i++ {
- if deltas[i].label >= 0 {
- c.cellTree = append(c.cellTree, cellIndexNode{
- cellID: deltas[i].cellID,
- label: deltas[i].label,
- parent: contents})
- contents = int32(len(c.cellTree) - 1)
- } else if deltas[i].cellID == SentinelCellID {
- contents = c.cellTree[contents].parent
- }
- }
- c.rangeNodes = append(c.rangeNodes, rangeNode{startID, contents})
- }
-}
-
-// TODO(roberts): Differences from C++
-// IntersectingLabels
-// VisitIntersectingCells
-// CellIndexIterator