index

package
v0.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2024 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrFeatureNotFound

type ErrFeatureNotFound[K feature.Key] struct {
	Key K
}

func (ErrFeatureNotFound[K]) Error

func (err ErrFeatureNotFound[K]) Error() string

type Index

type Index[K feature.Key, F feature.Feature[K]] struct {
	// contains filtered or unexported fields
}

Index allows finding features by bounding box and custom queries. It is NOT thread-safe.

func New

func New[K feature.Key, F feature.Feature[K]](features []F) (*Index[K, F], error)

Creates a new index containing features.

func (*Index[K, F]) Delete

func (index *Index[K, F]) Delete(key K) error

Delete removes a feature by its key.

Example (Intersect)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
_ = index.Delete(CityID("wrocław"))
location := primitives.Point{14.499678611755371, 53.41209631751399}
// A 1000kmx1000km bounding rectangle around the location so we match both cities.
radius := 500000.0
bounds, _ := geo.NewBoundsAround(location, radius)
results, _ := index.Intersect(bounds)
fmt.Println(len(results), "result")
Output:

1 result
Example (IntersectMultipleFeaturesPerKey)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
wroclaw2, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin, &wroclaw2})
_ = index.Delete(CityID("wrocław"))
location := primitives.Point{14.499678611755371, 53.41209631751399}
// A 1000kmx1000km bounding rectangle around the location so we match both cities.
radius := 500000.0
bounds, _ := geo.NewBoundsAround(location, radius)
results, _ := index.Intersect(bounds)
fmt.Println(len(results), "result")
Output:

1 result
Example (Lookup)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
_ = index.Delete(CityID("wrocław"))
results, _ := index.Lookup(CityID("wrocław"))
fmt.Println(len(results), "matches")
Output:

0 matches

func (*Index[K, F]) FindContaining

func (index *Index[K, F]) FindContaining(point primitives.Point) ([]F, error)

FindContaining returns features containing the given point.

Example

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
location := primitives.Point{14.499678611755371, 53.41209631751399}
results, _ := index.FindContaining(location)
fmt.Println(len(results), "result:", results[0].Name)
Output:

1 result: Szczecin

func (*Index[K, F]) Insert

func (index *Index[K, F]) Insert(f F) error

Insert adds a feature to the index.

func (*Index[K, F]) Intersect

func (index *Index[K, F]) Intersect(bounds *primitives.Rect) ([]F, error)

Intersect returns features whose bounding boxes intersect the given bounding box.

Example

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
location := primitives.Point{14.499678611755371, 53.41209631751399}
// A 1000kmx1000km bounding rectangle around the location so we match both cities.
radius := 500000.0
bounds, _ := geo.NewBoundsAround(location, radius)
results, _ := index.Intersect(bounds)
fmt.Println(len(results), "results")
Output:

2 results

func (*Index[K, F]) Keys

func (index *Index[K, F]) Keys() *hashset.Set[K]

Keys returns a set containing all keys.

func (*Index[K, F]) Lookup

func (index *Index[K, F]) Lookup(key K) ([]F, error)

Lookup returns a feature based on its key. It returns a slice containing one result or an empty slice if there's no match.

Example

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
results, _ := index.Lookup(CityID("wrocław"))
fmt.Println(len(results), "match")
Output:

1 match

func (*Index[K, F]) Query

func (index *Index[K, F]) Query(bounds *primitives.Rect, query query.Query[K, F]) ([]F, error)

Query returns features with bounding boxes intersecting the specified bounding box and matching the provided query.

Example (Preconditions)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 638384, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 407811, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
location := primitives.Point{14.499678611755371, 53.41209631751399}
// A 1000kmx1000km bounding rectangle around the location so we match both cities.
radius := 500000.0
bounds, _ := geo.NewBoundsAround(location, radius)
results, _ := index.Query(bounds, query.Build[CityID, *City]().Where(PopulationGreaterThan{500000}).Query())
fmt.Println(len(results), "result")
Output:

1 result

func (*Index[K, F]) Size

func (index *Index[K, F]) Size() int

Size returns the number of features in the index.

func (*Index[K, F]) Update

func (index *Index[K, F]) Update(f F) error

Update updates a feature (either its bounding rectangle or properties).

Example (BoundariesChanged)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 500000, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 300000, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
szczecin2, _ := NewCity("szczecin", "Szczecin", 350000, pip.Polygon{Points: farAwayLandBoundaries})
_ = index.Update(&szczecin2) // Update key = "szczecin"
location := primitives.Point{14.499678611755371, 53.41209631751399}
// A 1000kmx1000km bounding rectangle around the location so we match both cities.
radius := 500000.0
bounds, _ := geo.NewBoundsAround(location, radius)
origResults, _ := index.Intersect(bounds)
newBounds, _ := geo.NewBoundsAround(primitives.Point{0, 0}, 50)
newResults, _ := index.Intersect(newBounds)
fmt.Println(len(origResults), "matching original location,", len(newResults), "matching new location")
Output:

1 matching original location, 1 matching new location
Example (IntersectNoBoundariesChanged)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

szczecin, _ := NewCity("szczecin", "Szczecin", 300000, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&szczecin})
szczecin2, _ := NewCity("szczecin", "Szczecin", 350000, pip.Polygon{Points: szczecinBoundaries})
_ = index.Update(&szczecin2) // Update key = "szczecin"
location := primitives.Point{14.499678611755371, 53.41209631751399}
bounds, _ := geo.NewBoundsAround(location, 500000.0)
results, _ := index.Intersect(bounds)
population := results[0].Population
fmt.Println("Population:", population)
Output:

Population: 350000
Example (LookupNoBoundariesChanged)

This example uses an example spatial feature implementation. See https://github.com/bilus/fencer/blob/master/index/index_test.go for more details.

wroclaw, _ := NewCity("wrocław", "Wrocław", 500000, pip.Polygon{Points: wroclawBoundaries})
szczecin, _ := NewCity("szczecin", "Szczecin", 300000, pip.Polygon{Points: szczecinBoundaries})
index, _ := index.New[CityID]([]*City{&wroclaw, &szczecin})
szczecin2, _ := NewCity("szczecin", "Szczecin", 350000, pip.Polygon{Points: szczecinBoundaries})
_ = index.Update(&szczecin2) // Update key = "szczecin"
results, _ := index.Lookup(CityID("szczecin"))
population := results[0].Population
fmt.Println("Population:", population)
Output:

Population: 350000

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL