carpool-service/geoutils/distance.go

54 lines
1.0 KiB
Go
Raw Normal View History

2023-03-29 22:45:18 +00:00
package geoutils
import (
"math"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geo"
"github.com/rs/zerolog/log"
)
func DistanceFromLineString(point orb.Point, lineString orb.LineString) (distance float64, closestIndex int) {
minDistance := math.Inf(1)
closest := -1
for i := 0; i < len(lineString)-1; i++ {
a := lineString[i]
b := lineString[i+1]
pointOnSegment := projectToSegment(point, a, b)
dist := geo.Distance(point, pointOnSegment)
if dist < minDistance {
minDistance = dist
closest = i
}
}
log.Debug().
Float64("min distance", minDistance).
Int("index", closest).
Any("point", point).
Msg("minimum distance to polyline")
return minDistance, closest
}
func projectToSegment(point, a, b orb.Point) orb.Point {
x := a[0]
y := a[1]
dx := b[0] - x
dy := b[1] - y
if dx != 0 || dy != 0 {
t := ((point[0]-x)*dx + (point[1]-y)*dy) / (dx*dx + dy*dy)
if t > 1 {
x = b[0]
y = b[1]
} else if t > 0 {
x += dx * t
y += dy * t
}
}
return orb.Point{x, y}
}