tile38/pkg/index/index.go

96 lines
2.1 KiB
Go
Raw Normal View History

2016-03-05 02:08:16 +03:00
package index
2016-10-03 21:37:16 +03:00
import (
2018-08-03 05:57:11 +03:00
"github.com/tidwall/boxtree/d2"
2016-10-03 21:37:16 +03:00
)
2016-03-05 02:08:16 +03:00
// Index is a geospatial index
type Index struct {
2018-08-03 05:57:11 +03:00
r d2.BoxTree
}
// New create a new index
func New() *Index {
2018-08-03 05:57:11 +03:00
return &Index{}
}
2016-03-05 02:08:16 +03:00
// Item represents an index item.
type Item interface {
Point() (x, y float64)
Rect() (minX, minY, maxX, maxY float64)
2016-03-05 02:08:16 +03:00
}
// FlexItem can represent a point or a rectangle
type FlexItem struct {
MinX, MinY, MaxX, MaxY float64
2016-03-05 02:08:16 +03:00
}
// Rect returns the rectangle
func (item *FlexItem) Rect() (minX, minY, maxX, maxY float64) {
return item.MinX, item.MinY, item.MaxX, item.MaxY
2016-03-05 02:08:16 +03:00
}
// Point returns the point
func (item *FlexItem) Point() (x, y float64) {
return item.MinX, item.MinY
2016-03-05 02:08:16 +03:00
}
// Insert inserts an item into the index
func (ix *Index) Insert(item Item) {
minX, minY, maxX, maxY := item.Rect()
2018-08-03 05:57:11 +03:00
ix.r.Insert([]float64{minX, minY}, []float64{maxX, maxY}, item)
2016-03-05 02:08:16 +03:00
}
// Remove removed an item from the index
func (ix *Index) Remove(item Item) {
minX, minY, maxX, maxY := item.Rect()
2018-08-03 05:57:11 +03:00
ix.r.Delete([]float64{minX, minY}, []float64{maxX, maxY}, item)
2016-03-05 02:08:16 +03:00
}
// Count counts all items in the index.
func (ix *Index) Count() int {
return ix.r.Count()
2016-03-05 02:08:16 +03:00
}
// Bounds returns the minimum bounding rectangle of all items in the index.
2017-08-11 03:32:40 +03:00
func (ix *Index) Bounds() (MinX, MinY, MaxX, MaxY float64) {
min, max := ix.r.Bounds()
return min[0], min[1], max[0], max[1]
}
2016-03-05 02:08:16 +03:00
// RemoveAll removes all items from the index.
func (ix *Index) RemoveAll() {
2018-08-03 05:57:11 +03:00
ix.r = d2.BoxTree{}
2017-08-11 03:32:40 +03:00
}
2018-08-03 05:57:11 +03:00
// KNN returns the nearsest neighbors
func (ix *Index) KNN(x, y float64, iterator func(item interface{}) bool) bool {
2018-08-03 05:57:11 +03:00
res := true
ix.r.Nearby([]float64{x, y}, []float64{x, y},
func(_, _ []float64, item interface{}) bool {
if !iterator(item) {
res = false
return false
}
return true
})
2018-08-03 05:57:11 +03:00
return res
}
2016-03-05 02:08:16 +03:00
// Search returns all items that intersect the bounding box.
func (ix *Index) Search(minX, minY, maxX, maxY float64,
2017-08-11 03:32:40 +03:00
iterator func(item interface{}) bool,
) bool {
2018-08-03 05:57:11 +03:00
res := true
ix.r.Search([]float64{minX, minY}, []float64{maxX, maxY},
func(_, _ []float64, item interface{}) bool {
if !iterator(item) {
res = false
return false
}
return true
})
2018-08-03 05:57:11 +03:00
return res
2016-03-05 02:08:16 +03:00
}