Skip to content
Snippets Groups Projects
Select Git revision
  • master default
1 result

autocomplete_distance.go

Blame
  • autocomplete_distance.go 1.60 KiB
    package main
    
    import (
    	"errors"
    	"math"
    	"strconv"
    	"strings"
    )
    
    type Position struct {
    	Latitude  float64 `json:"stop_lat"`
    	Longitude float64 `json:"stop_lon"`
    }
    
    func PositionFromString(data string) (Position, error) {
    	var err error
    	var position Position
    
    	split := strings.Split(data, ",")
    	if len(split) != 2 {
    		return position, errors.New("incorrect format")
    	}
    
    	if position.Latitude, err = strconv.ParseFloat(split[0], 64); err != nil {
    		return position, err
    	}
    	if position.Longitude, err = strconv.ParseFloat(split[1], 64); err != nil {
    		return position, err
    	}
    
    	return position, nil
    }
    
    // haversin(θ) function
    func hsin(theta float64) float64 {
    	return math.Pow(math.Sin(theta/2), 2)
    }
    
    // Distance function returns the distance (in meters) between two points of
    //     a given longitude and latitude relatively accurately (using a spherical
    //     approximation of the Earth) through the Haversin Distance Formula for
    //     great arc distance on a sphere with accuracy for small distances
    //
    // point coordinates are supplied in degrees and converted into rad. in the func
    //
    // distance returned is METERS!!!!!!
    // http://en.wikipedia.org/wiki/Haversine_formula
    func Distance(a Position, b Position) float64 {
    	// convert to radians
    	// must cast radius as float to multiply later
    	var la1, lo1, la2, lo2, r float64
    	la1 = a.Latitude * math.Pi / 180
    	lo1 = a.Longitude * math.Pi / 180
    	la2 = b.Latitude * math.Pi / 180
    	lo2 = b.Longitude * math.Pi / 180
    
    	r = 6378100 // Earth radius in METERS
    
    	// calculate
    	h := hsin(la2-la1) + math.Cos(la1)*math.Cos(la2)*hsin(lo2-lo1)
    
    	return 2 * r * math.Asin(math.Sqrt(h))
    }