penguin/golifehk

@golifehk bot in Telegram

query/GeoLocation.go

raw ยท 1388 bytes

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
}