make distance stuff greate again
This commit is contained in:
54
geoutils/distance.go
Normal file
54
geoutils/distance.go
Normal file
@@ -0,0 +1,54 @@
|
||||
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).
|
||||
Any("linestring", lineString).
|
||||
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}
|
||||
}
|
||||
Reference in New Issue
Block a user