- Notifications
You must be signed in to change notification settings - Fork1
lovoo/rtreego
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A library for efficiently storing and querying spatial datain the Go programming language.
The R-tree is a popular data structure for efficiently storing andquerying spatial objects; one common use is implementing geospatialindexes in database management systems. Both bounding-box queriesand k-nearest-neighbor queries are supported.
R-trees are balanced, so maximum tree height is guaranteed to belogarithmic in the number of entries; however, good worst-caseperformance is not guaranteed. Instead, a number of rebalancingheuristics are applied that perform well in practice. For moredetails please refer to the references.
This implementation handles the general N-dimensional case; for a moreefficient implementation for the 3-dimensional case, seePatrickHiggins' fork.
Get the source code fromGitHub or,with Go 1 installed, rungo get github.com/dhconnelly/rtreego
.
Make sure youimport github.com/dhconnelly/rtreego
in your Go source files.
To create a new tree, specify the number of spatial dimensions and the minimumand maximum branching factor:
rt := rtreego.NewTree(2, 25, 50)
You can also bulk-load the tree when creating it by passing the objects asa parameter.
rt := rtreego.NewTree(2, 25, 50, objects...)
Any type that implements theSpatial
interface can be stored in the tree:
type Spatial interface { Bounds() *Rect}
Rect
s are data structures for representing spatial objects, whilePoint
srepresent spatial locations. CreatingPoint
s is easy--they're just slicesoffloat64
s:
p1 := rtreego.Point{0.4, 0.5}p2 := rtreego.Point{6.2, -3.4}
To create aRect
, specify a location and the lengths of the sides:
r1, _ := rtreego.NewRect(p1, []float64{1, 2})r2, _ := rtreego.NewRect(p2, []float64{1.7, 2.7})
To demonstrate, let's create and store some test data.
type Thing struct { where *Rect name string}func (t *Thing) Bounds() *Rect { return t.where}rt.Insert(&Thing{r1, "foo"})rt.Insert(&Thing{r2, "bar"})size := rt.Size() // returns 2
We can insert and delete objects from the tree in any order.
rt.Delete(thing2)// do some stuff...rt.Insert(anotherThing)
Note thatDelete
function does the equality comparison by comparing thememory addresses of the objects. If you do not have a pointer to the originalobject anymore, you can define a custom comparator.
type Comparator func(obj1, obj2 Spatial) (equal bool)
You can use a custom comparator withDeleteWithComparator
function.
cmp := func(obj1, obj2 Spatial) bool { sp1 := obj1.(*IDRect) sp2 := obj2.(*IDRect) return sp1.ID == sp2.ID}rt.DeleteWithComparator(obj, cmp)
If you want to store points instead of rectangles, you can easily convert apoint into a rectangle using theToRect
method:
var tol = 0.01type Somewhere struct { location rtreego.Point name string wormhole chan int}func (s *Somewhere) Bounds() *Rect { // define the bounds of s to be a rectangle centered at s.location // with side lengths 2 * tol: return s.location.ToRect(tol)}rt.Insert(&Somewhere{rtreego.Point{0, 0}, "Someplace", nil})
If you want to update the location of an object, you must delete it, update it,and re-insert. Just modifying the object so that the*Rect
returned byLocation()
changes, without deleting and re-inserting the object, willcorrupt the tree.
Bounding-box and k-nearest-neighbors queries are supported.
Bounding-box queries require a search*Rect
. It returns all objects thattouch the search rectangle.
bb, _ := rtreego.NewRect(rtreego.Point{1.7, -3.4}, []float64{3.2, 1.9})// Get a slice of the objects in rt that intersect bb:results := rt.SearchIntersect(bb)
You can filter out values during searches by implementing Filter functions.
type Filter func(results []Spatial, object Spatial) (refuse, abort bool)
A filter for limiting results by result count is included in the package forbackwards compatibility.
// maximum of three results will be returnedtree.SearchIntersect(bb, LimitFilter(3))
Nearest-neighbor queries find the objects in a tree closest to a specifiedquery point.
q := rtreego.Point{6.5, -2.47}k := 5// Get a slice of the k objects in rt closest to q:results = rt.NearestNeighbors(k, q)
SeeGoDoc for full APIdocumentation.
A. Guttman. R-trees: A Dynamic Index Structure for Spatial Searching.Proceedings of ACM SIGMOD, pages 47-57, 1984.http://www.cs.jhu.edu/~misha/ReadingSeminar/Papers/Guttman84.pdf
N. Beckmann, H .P. Kriegel, R. Schneider and B. Seeger. The R*-tree: AnEfficient and Robust Access Method for Points and Rectangles. Proceedingsof ACM SIGMOD, pages 323-331, May 1990.http://infolab.usc.edu/csci587/Fall2011/papers/p322-beckmann.pdf
N. Roussopoulos, S. Kelley and F. Vincent. Nearest Neighbor Queries. ACMSIGMOD, pages 71-79, 1995.http://www.postgis.org/support/nearestneighbor.pdf
Written byDaniel Connelly (dhconnelly@gmail.com).
rtreego is released under a BSD-style license, described in theLICENSE
file.
About
an R-Tree library for Go
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Languages
- Go100.0%