package query import ( "github.com/tidwall/geodesic" "sort" ) type GeoLocation struct { Latitude float64 Longitude float64 } func (b GeoLocation) HasGeoLocation() bool { return true } func (b GeoLocation) Lat() float64 { return b.Latitude } func (b GeoLocation) Lon() float64 { return b.Longitude } func (b GeoLocation) Dist(lat float64, lon float64) float64 { var dist float64 geodesic.WGS84.Inverse( lat, lon, b.Latitude, b.Longitude, &dist, nil, nil, ) return dist } type NoGeoLocation struct{} func (b NoGeoLocation) HasGeoLocation() bool { return false } func (b NoGeoLocation) Lat() float64 { return 0 } func (b NoGeoLocation) Lon() float64 { return 0 } func (b NoGeoLocation) Dist(lat, lon float64) float64 { return 0 } func (b NoGeoLocation) Register(map[string]struct{}) bool { return false } type GeoLocations []ISearchable func (m GeoLocations) SortByNearest(p GeoLocation) { sort.Slice(m, func(i, j int) bool { return m[i].Dist(p.Lat(), p.Lon()) < m[j].Dist(p.Lat(), p.Lon()) }) } func (b GeoLocation) Register(map[string]struct{}) bool { return false } func (m GeoLocations) Clean() *GeoLocations { registers := map[string]struct{}{} items := &GeoLocations{} for _, item := range m { if item.HasGeoLocation() && item.Register(registers) { *items = append(*items, item) } } return items }