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  }