geo

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2024 License: MIT Imports: 3 Imported by: 0

README

Go - KDBush/geo

A geographic extension for Golang port of KDBush, the fastest static spatial index for points.

It implements fast nearest neighbors queries for locations on Earth, taking Earth curvature and date line wrapping into account. Inspired by sphere-knn, but uses a different algorithm.

This extension works for and require https://github.com/raditzlawliet/kdbush and only use standard library

This implementation is based on:

Dump file cities5000 for Benchmark are from geonames.org data.

Usage

By default, when you go get kdbush, it will include this extension

import(
    "github.com/raditzlawliet/kdbush"
    "github.com/raditzlawliet/kdbush/geo"
)

//...
points = []kdbush.Point{
    // Surabaya
    &geo.MarkerPoint{Lat: -7.265850333832262, Lng: 112.74996851603348},
    &geo.MarkerPoint{Lat: -7.261669467066506, Lng: 112.74641761874226},
    &geo.MarkerPoint{Lat: -7.262083358514896, Lng: 112.74242319159997},
    &geo.MarkerPoint{Lat: -7.266374558931883, Lng: 112.74432953003436},
    &geo.MarkerPoint{Lat: -7.271393029465542, Lng: 112.74264315372703},
    // Surabaya but not near from previous one
    &geo.MarkerPoint{Lat: -7.279393373923168, Lng: 112.7413233810989},
    // Jakarta
    &geo.MarkerPoint{Lat: -6.199482563158932, Lng: 106.84831233134457},
    &geo.MarkerPoint{Lat: -6.173354331560208, Lng: 106.82685482999992},
    ...
}

// Build Index
bush := kdbush.NewBush().
    BuildIndexWith(points, kdbush.STANDARD_NODE_SIZE)

// Try to search 5 cloests around 10km in Jakarta
results := geo.Around(bush, 106.84831233134457,  -6.199482563158932, 5, 10, nil)
fmt.Println(results)
// [6, 7]

API

Around(kdbush, longitude, latitude, maxResults, maxDistanceInKm, filterFn)

Returns an array of the closest ids (indices) of points from a given location in order of increasing distance.

  • kdbush: kdbush pointer *KDBush
  • longitude: query point longitude float64
  • latitude: query point latitude float64
  • maxResults: maximum number of points to return (-1 for all result) int.
  • maxDistance: maximum distance in kilometers to search within (-1 for all distance) float64.
  • filterFn: (optional) a function to filter the results (ids) with func(int) bool.
Distance(longitude1, latitude1, longitude2, latitude2)

Returns great circle distance between two locations in kilometers.

  • longitude1: query point longitude location A float64
  • latitude1: query point latitude location A float64
  • longitude2: query point longitude location B float64
  • latitude2: query point latitude location B float64

Benchmark

All benchmark are run on Go 1.20.3, Windows 11 & 12th Gen Intel(R) Core(TM) i7-12700H (Laptop version).

Do not trust benchmark

go test -bench=BenchmarkGeo -benchmem -benchtime=10s

Benchmark Around (-benchtime=10s); NodeSize=64

  • Around 1k closest with various data
  • Around 5k closest with various data
  • All data (not recommended)
  • Around 1 cloests with various data (Recommended)
BenchmarkGeo/AroundClosest1kWithData_1000-20               75482            161787 ns/op          139080 B/op       1054 allocs/op
BenchmarkGeo/AroundClosest1kWithData_10000-20              57481            211893 ns/op          186408 B/op       1547 allocs/op
BenchmarkGeo/AroundClosest1kWithData_100000-20             62398            190905 ns/op          168296 B/op       1428 allocs/op
BenchmarkGeo/AroundClosest1kWithData_1000000-20            65750            184053 ns/op          178664 B/op       1536 allocs/op
BenchmarkGeo/AroundClosest5kWithData_1000-20               74416            163814 ns/op          139080 B/op       1054 allocs/op
BenchmarkGeo/AroundClosest5kWithData_10000-20               6087           1907396 ns/op         1426632 B/op      10544 allocs/op
BenchmarkGeo/AroundClosest5kWithData_100000-20              1142          10424478 ns/op         7698122 B/op      57933 allocs/op
BenchmarkGeo/AroundClosest5kWithData_1000000-20             1287          15748340 ns/op         7179145 B/op      53549 allocs/op
BenchmarkGeo/AroundWithData_1000-20                        73365            164499 ns/op          139080 B/op       1054 allocs/op
BenchmarkGeo/AroundWithData_10000-20                        6308           1902256 ns/op         1426632 B/op      10544 allocs/op
BenchmarkGeo/AroundWithData_100000-20                        590          20246603 ns/op        14280010 B/op     104140 allocs/op
BenchmarkGeo/AroundWithData_1000000-20                        57         212027111 ns/op        141484404 B/op   1032826 allocs/op
BenchmarkGeo/AroundClosest1RanndomWithData_1000-20       2275586              5234 ns/op            9176 B/op         84 allocs/op
BenchmarkGeo/AroundClosest1RanndomWithData_10000-20      2708715              6653 ns/op            7000 B/op         71 allocs/op
BenchmarkGeo/AroundClosest1RanndomWithData_100000-20     1977226              5778 ns/op            9848 B/op         91 allocs/op
BenchmarkGeo/AroundClosest1RanndomWithData_1000000-20            1833982              6515 ns/op           11864 B/op        112 allocs/op
BenchmarkGeo/Distance-20                                        289074040               41.70 ns/op            0 B/op          0 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Around

func Around(bush *kdbush.KDBush, lng, lat float64, maxResults int, maxDistanceInKm float64, predicate func(int) bool) []int

func Distance

func Distance(lng1, lat1, lng2, lat2 float64) float64

Distance return great circle distance between two locations in kilometers

Types

type MarkerPoint

type MarkerPoint struct {
	Lat, Lng float64
}

MarkerPoint a basic point struct implement [KDBush.Point]

func (*MarkerPoint) GetX

func (p *MarkerPoint) GetX() (X float64)

func (*MarkerPoint) GetY

func (p *MarkerPoint) GetY() (Y float64)

Jump to

Keyboard shortcuts

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