github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/vector/hnsw/distancer/geo_spatial.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package distancer 13 14 import ( 15 "fmt" 16 "math" 17 ) 18 19 func geoDist(a, b []float32) (float32, bool, error) { 20 if len(a) != 2 || len(b) != 2 { 21 return 0, false, fmt.Errorf("distance vectors must have len 2") 22 } 23 24 latA := a[0] 25 latB := b[0] 26 lonA := a[1] 27 lonB := b[1] 28 const R = float64(6371e3) 29 30 latARadian := float64(latA * math.Pi / 180) 31 latBRadian := float64(latB * math.Pi / 180) 32 deltaLatRadian := float64(latB-latA) * math.Pi / 180 33 deltaLonRadian := float64(lonB-lonA) * math.Pi / 180 34 35 A := math.Sin(deltaLatRadian/2)*math.Sin(deltaLatRadian/2) + 36 math.Cos(latARadian)*math.Cos(latBRadian)*math.Sin(deltaLonRadian/2)*math.Sin(deltaLonRadian/2) 37 38 C := 2 * math.Atan2(math.Sqrt(A), math.Sqrt(1-A)) 39 40 return float32(R * C), true, nil 41 } 42 43 type GeoDistancer struct { 44 a []float32 45 } 46 47 func (g GeoDistancer) Distance(b []float32) (float32, bool, error) { 48 return geoDist(g.a, b) 49 } 50 51 type GeoProvider struct{} 52 53 func (gp GeoProvider) New(vec []float32) Distancer { 54 return GeoDistancer{a: vec} 55 } 56 57 func (gp GeoProvider) SingleDist(vec1, vec2 []float32) (float32, bool, error) { 58 return geoDist(vec1, vec2) 59 } 60 61 func (gp GeoProvider) Type() string { 62 return "geo" 63 } 64 65 func (gp GeoProvider) Step(x, y []float32) float32 { 66 panic("Not implemented") 67 } 68 69 func (gp GeoProvider) Wrap(x float32) float32 { 70 panic("Not implemented") 71 } 72 73 func NewGeoProvider() Provider { 74 return GeoProvider{} 75 }