Documentation
¶
Index ¶
- type ErrFeatureNotFound
- type Index
- func (index *Index[K, F]) Delete(key K) error
- func (index *Index[K, F]) FindContaining(point primitives.Point) ([]F, error)
- func (index *Index[K, F]) Insert(f F) error
- func (index *Index[K, F]) Intersect(bounds *primitives.Rect) ([]F, error)
- func (index *Index[K, F]) Keys() *hashset.Set[K]
- func (index *Index[K, F]) Lookup(key K) ([]F, error)
- func (index *Index[K, F]) Query(bounds *primitives.Rect, query query.Query[K, F]) ([]F, error)
- func (index *Index[K, F]) Size() int
- func (index *Index[K, F]) Update(f F) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ErrFeatureNotFound ¶
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 (*Index[K, F]) Delete ¶
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]) 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]) Lookup ¶
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 ¶
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]) Update ¶
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