2016-03-05 02:08:16 +03:00
|
|
|
package index
|
|
|
|
|
2016-10-03 21:37:16 +03:00
|
|
|
import (
|
2018-05-08 16:56:28 +03:00
|
|
|
rtree "github.com/tidwall/tile38/pkg/index/rtree"
|
2016-10-03 21:37:16 +03:00
|
|
|
)
|
2016-03-05 02:08:16 +03:00
|
|
|
|
2018-05-08 16:56:28 +03:00
|
|
|
// Index is a geospatial index
|
|
|
|
type Index struct {
|
|
|
|
r *rtree.RTree
|
|
|
|
}
|
|
|
|
|
|
|
|
// New create a new index
|
|
|
|
func New() *Index {
|
|
|
|
return &Index{
|
|
|
|
r: rtree.New(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-05 02:08:16 +03:00
|
|
|
// Item represents an index item.
|
|
|
|
type Item interface {
|
2018-05-08 16:56:28 +03:00
|
|
|
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 {
|
2018-05-08 16:56:28 +03:00
|
|
|
MinX, MinY, MaxX, MaxY float64
|
2016-03-05 02:08:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Rect returns the rectangle
|
2018-05-08 16:56:28 +03:00
|
|
|
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
|
2018-05-08 16:56:28 +03:00
|
|
|
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) {
|
2018-05-08 16:56:28 +03:00
|
|
|
minX, minY, maxX, maxY := item.Rect()
|
|
|
|
ix.r.Insert([2]float64{minX, minY}, [2]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) {
|
2018-05-08 16:56:28 +03:00
|
|
|
minX, minY, maxX, maxY := item.Rect()
|
|
|
|
ix.r.Remove([2]float64{minX, minY}, [2]float64{maxX, maxY}, item)
|
2016-03-05 02:08:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Count counts all items in the index.
|
|
|
|
func (ix *Index) Count() int {
|
2018-05-08 16:56:28 +03:00
|
|
|
return ix.r.Count()
|
2016-03-05 02:08:16 +03:00
|
|
|
}
|
|
|
|
|
2016-08-19 18:33:58 +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) {
|
2018-05-08 16:56:28 +03:00
|
|
|
min, max := ix.r.Bounds()
|
|
|
|
return min[0], min[1], max[0], max[1]
|
|
|
|
|
2016-08-19 18:33:58 +03:00
|
|
|
}
|
|
|
|
|
2016-03-05 02:08:16 +03:00
|
|
|
// RemoveAll removes all items from the index.
|
|
|
|
func (ix *Index) RemoveAll() {
|
2018-05-08 16:56:28 +03:00
|
|
|
ix.r = rtree.New()
|
2017-08-11 03:32:40 +03:00
|
|
|
}
|
|
|
|
|
2018-05-08 16:56:28 +03:00
|
|
|
func (ix *Index) KNN(x, y float64, iterator func(item interface{}) bool) bool {
|
|
|
|
return ix.r.KNN([2]float64{x, y}, [2]float64{x, y}, true,
|
|
|
|
func(item interface{}, dist float64) bool {
|
|
|
|
return iterator(item)
|
|
|
|
})
|
2017-01-31 02:41:12 +03:00
|
|
|
}
|
|
|
|
|
2016-03-05 02:08:16 +03:00
|
|
|
// Search returns all items that intersect the bounding box.
|
2018-05-08 16:56:28 +03:00
|
|
|
func (ix *Index) Search(minX, minY, maxX, maxY float64,
|
2017-08-11 03:32:40 +03:00
|
|
|
iterator func(item interface{}) bool,
|
|
|
|
) bool {
|
2018-05-08 16:56:28 +03:00
|
|
|
return ix.r.Search([2]float64{minX, minY}, [2]float64{maxX, maxY},
|
|
|
|
func(item interface{}) bool {
|
|
|
|
return iterator(item)
|
|
|
|
})
|
2016-03-05 02:08:16 +03:00
|
|
|
}
|